niedziela, 26 października 2014

Manipulowanie załącznikami i obrazami w CakePHP - czyli trochę o miniaturkach

Od jakiegoś już czasu rozwijam swój własny Behavior do manipulowania plikami i obrazami w CakePHP, jednak wcześniej nie został nigdzie tak szczegółowo opisany...
Oficjalne i zarazem zawsze aktualne repozytorium (GIT) znajduje się pod adresem repo.kdev.pl/filebehavior (hostowane przez bitbucket.org) i jest prowadzone w języku angielskim. Na tą chwilę behavior przygotowany jest pod wersję 2.x, aby używać go w wersji 1.x należałoby go lekko zmodyfikować. Natomiast, co do nadchodzącego Cake'a 3.0, to pojawi się niebawem odpowiednia wersja...

Dlaczego Behavior, a nie Komponent lub Helper albo jeszcze jakiś Vendor? Ponieważ, z przyjętego założenia, wzorca MVC oraz zasad Cake'a, komponent służy jako wspomagacz Kontrolera, helper Widoku, a behavior Modelu, natomiast vendor powinien obsługiwać osobny skrypt niekoniecznie zgodny z MVC. Jeśli, więc obrazy i załączniki stanowią treść strony, to powinny być obsługiwane jak inne treści, czyli za pomocą modelu, stąd pomocnik modelu czyli behavior. Tyle pokrótce...

Przejdźmy zatem do konkretów...
Po pobraniu behavior'a, a tym samym jedynego pliku FileBehavior.php i zapisaniu go w katalogu app/Model/Behavior możemy już korzystać z jego funkcjonalności.
Aby podłączyć behavior do naszego modelu musimy skorzystać z publicznej własności modelu $actsAs:
public $actsAs = array(
    'File' => array(
        'attachment'
    )
);

Pamiętać należy, iż w tablicy podajemy nazwę behaviora, bez członu 'behavior', a w tablicy podać nazwy pól jakie chcemy zapisać. Oczywiście nazwa pola odpowiada nazwie pola w formularzu:
$this->Form->input('attachment', array(
 'type' => 'file'
));

Dodamy teraz kilka parametrów:
public $actsAs = array(
    'File' => array(
        'attachment'
            'path' => 'files/attachments',
            'types' => array(
                'application/msword',
                'application/vnd.ms-word'
            ),
            'extensions' => array(
                'doc',
                'docx'
            )
        )
    )
);
W powyższym kodzie wskazaliśmy ścieżkę, gdzie pliki będą zapisywane, ścieżka tyczy się adresu w katalogu app/webroot/files/attachments/. Dodatkowo zostały wskazane jakie typy (mime-type) oraz rozszerzenia plików mają być akceptowane. Warto zauważyć, że behavior celowo nie posiada, żadnej bazy typów i rozszerzeń plików, musimy je zawsze zdeklarować.
W sumie to byłoby na tyle jeśli chodzi o "zwykłe" pliki.

Natomiast jeśli chodzi o zapis i manipulowanie obrazami, to zasada jest podobna, z tym że dodatkowo w naszej tablicy wstawiamy klucz thumbs, jak poniżej:
public $actsAs = array(
    'File' => array(
        'image' => array(
            'path' => 'files/images',
            'thumbs' => array(
                'miniature' => array(
                    'square' => array(100)
                ),
                'wide' => array(
                    'width' => array(350)
                ),
                'fitting' => array(
                    'fit' => array(300, 400, true)
                )
            )
        )
    )
);

Jak wcześniej wspomniałem, behavior nie posiada bazy typów i rozszerzeń plików, jednak w przypadku obrazów taka lista jest założona z powodu wymogów i ograniczeń biblioteki GD.

W tablicy thumbs klucze posłużą nam jako sufiksy do nazw plików. Z tablicy wynika, że przesłany plik z pola image zostanie wygenerowany w trzech postaciach z sufiksami, kolejno: _miniature, _wide i _fitting oraz _original jako plik w oryginalnej postaci.
Każdy z tych sufiksów posiada swoją definicję. Do definicji w jakiej postaci ma zostać wygenerowana tzw. miniaturka służy 6 nazw (metod): width, height, shorter, longer, square oraz fit:
  • Metoda width, posiada jeden parametr (integer) przekazywany w tablicy i służy do dopasowania przesyłanego obrazu i skalowania go do wskazanej szerokości.
  • Metoda height, działa podobnie, jednak skaluje do wskazanej wysokości.
  • Metody shorter oraz longer posiadają jeden parametr (integer) przekazywany w tablicy i służą do dopasowania obrazu, odpowiednio do jego krótszego lub dłuższego boku do wskazanej długości.
  • Metoda square posiada jeden parametr (integer) lub dwa parametry (integer oraz boolean) w przekazywanej tablicy. Pierwszy parametr w obu przypadkach to docelowa długość boku wygenerowanego kwadratu. W przypadku podania tylko pierwszego parametru, obraz zostanie zeskalowany oraz przycięty. W przypadku podania obu parametrów, a drugiego jako true, to obraz zostanie zeskalowany tak, aby cały się zmieścił w kwadracie oraz zostaną dodane tzw. marginesy.
  • Metoda fit działa podobnie do metody square, jednak posiada dwa (integer oraz integer) lub trzy (integer, integer, boolean) parametry. W przypadku podania tylko dwóch parametrów obraz zostanie zeskalowany i przycięty do wskazanych wymiarów (szerokość, wysokość). Natomiast w przypadku podania trzeciego parametru jako true, obraz zostanie tak zeskalowany aby zmieścił się w podanych wymiarach oraz zostaną dodane tzw. marginesy.
Podsumowując, z przykładu powyżej wynika, że zostanie wygenerowany: obraz w kwadracie o boku 100 pikseli z prawdopodobnie uciętym obrazem, obraz o szerokości 350 pikseli i wysokości proporcjonalnej oraz obraz dopasowany do szerokości 300 pikseli oraz wysokości 400 pikseli bez ucinania.

Dodatkową opcją jest znak wodny, który jest często wykorzystywany do oznaczenia zdjęć np. logotypem. Aby dodać znak wodny potrzebujemy klucza w naszej tablicy o nazwie watermark:
public $actsAs = array(
    'File' => array(
        'image' => array(
            'path' => 'files/images',
            'watermark' => 'img/logo-watermark.png',
            'thumbs' => array(
                'fitting' => array(
                    'fit' => array(300, 400),
                    'watermark' => 7
                )
             )
        )
    )
);

Klucz watermark dodany pod kluczem path, służy do wskazania grafiki jaka ma zostać dodana jako znak wodny z folderu app/webroot/img/. Natomiast klucz watermark w definicji miniaturki oznacza położenie znaku wodnego. Odpowiednio: 1 (lewy górny róg), 2 (góra, centrum), 3 (prawy górny róg), 4 (lewy, centrum), 5 (środek), 6 (prawy, centrum), 7 (lewy dolny róg), 8 (dół, centrum), 9 (prawy dolny róg).

To byłoby chyba wszystko:)

Zapraszam do testowania, używania oraz zgłaszania uwag i sugestii na repo.kdev.pl/filebehavior/issues.

Brak komentarzy:

Prześlij komentarz