Cyfroteka.pl

klikaj i czytaj online

Cyfro
Czytomierz
00060 006987 14280594 na godz. na dobę w sumie
CakePHP 1.3. Programowanie aplikacji. Receptury - książka
CakePHP 1.3. Programowanie aplikacji. Receptury - książka
Autor: Liczba stron: 328
Wydawca: Helion Język publikacji: polski
ISBN: 978-83-246-3542-9 Data wydania:
Lektor:
Kategoria: ebooki >> komputery i informatyka >> webmasterstwo >> php - programowanie
Porównaj ceny (książka, ebook (-25%), audiobook).

Poznaj optymalne przepisy na CakePHP!

CakePHP jest jednym z tych frameworków dla języka PHP, które dzięki swym licznym zaletom już zdobyły dużą popularność wśród programistów. Pozwala na błyskawiczne tworzenie skalowalnych aplikacji internetowych, korzystających ze wzorca MVC oraz zaawansowanych narzędzi (na przykład mapowania obiektowo-relacyjnego baz danych). W tej książce znajdziesz sześćdziesiąt gotowych przepisów na rozwiązanie różnego rodzaju problemów pojawiających się podczas pracy z CakePHP. Część przedstawionych receptur poświęcono bezpieczeństwu, a część współpracy z bazami danych czy wykorzystaniu technologii AJAX. Ponadto podczas lektury nauczysz się korzystać z geolokalizacji, usług REST oraz funkcji pomocnych przy testowaniu. Poznasz przepis na stworzenie aplikacji obsługującej wiele języków oraz dowiesz się więcej o współpracy z powłoką systemu. Ta pełna gotowych rozwiązań książka powinna znaleźć się na półce każdego programisty PHP używającego CakePHP!

Ta książka pozwoli Ci...

Sięgnij po skuteczne rozwiązania najczęstszych problemów z CakePHP!

Znajdź podobne książki Ostatnio czytane w tej kategorii

Darmowy fragment publikacji:

Tytuł oryginału: CakePHP 1.3 Application Development Cookbook Tłumaczenie: Przemysław Pietraszek (rozdz.1), Krzysztof Rychlicki-Kicior (wstęp, rozdz. 2 – 11) ISBN: 978-83-246-3542-9 Copyright © Packt Publishing 2011. First published in the English language under the title „CakePHP 1.3 Application Development Cookbook” © Helion 2012 All rights reserved All rights reserved. No part of this book may be reproduced or transmitted in any form or by any means, electronic or mechanical, including photocopying, recording or by any information storage retrieval system, without permission from the Publisher. Wszelkie prawa zastrzeżone. Nieautoryzowane rozpowszechnianie całości lub fragmentu niniejszej publikacji w jakiejkolwiek postaci jest zabronione. Wykonywanie kopii metodą kserograficzną, fotograficzną, a także kopiowanie książki na nośniku filmowym, magnetycznym lub innym powoduje naruszenie praw autorskich niniejszej publikacji. Wszystkie znaki występujące w tekście są zastrzeżonymi znakami firmowymi bądź towarowymi ich właścicieli. Autor oraz Wydawnictwo HELION dołożyli wszelkich starań, by zawarte w tej książce informacje były kompletne i rzetelne. Nie biorą jednak żadnej odpowiedzialności ani za ich wykorzystanie, ani za związane z tym ewentualne naruszenie praw patentowych lub autorskich. Autor oraz Wydawnictwo HELION nie ponoszą również żadnej odpowiedzialności za ewentualne szkody wynikłe z wykorzystania informacji zawartych w książce. Pliki z przykładami omawianymi w książce można znaleźć pod adresem: ftp://ftp.helion.pl/przyklady/ caph3r.zip Wydawnictwo HELION ul. Kościuszki 1c, 44-100 GLIWICE tel. 32 231 22 19, 32 230 98 63 e-mail: helion@helion.pl WWW: http://helion.pl (księgarnia internetowa, katalog książek) Drogi Czytelniku! Jeżeli chcesz ocenić tę książkę, zajrzyj pod adres http://helion.pl/user/opinie/caph3r Możesz tam wpisać swoje uwagi, spostrzeżenia, recenzję. Printed in Poland. • Kup książkę • Poleć książkę • Oceń książkę • Księgarnia internetowa • Lubię to! » Nasza społeczność Spis treĂci O autorze O recenzentach Przedmowa O czym jest ta ksiÈĝka? Oprogramowanie wykorzystywane w ksiÈĝce Dla kogo jest ta ksiÈĝka? Konwencje typograficzne Materiaïy dodatkowe i pomoc Rozdziaï 1. Uwierzytelnianie Wprowadzenie Konfiguracja prostego systemu uwierzytelniania Uĝywanie i konfiguracja komponentu Auth Logowanie za pomocÈ nazwy uĝytkownika lub adresu e-mail Zapisywanie informacji o uĝytkowniku po zalogowaniu Pobieranie informacji o zalogowanym uĝytkowniku Uĝywanie prefiksów do kontroli dostÚpu bazujÈcej na rolach Autoryzacja wykorzystujÈca warstwÚ kontroli dostÚpu (ACL) Integracja z OpenID Rozdziaï 2. WiÈzania modeli Wprowadzenie Dodanie zachowania Containable do wszystkich modeli Ograniczanie wiÈzañ zwracanych przez wyszukiwania Modyfikowanie parametrów wiÈzañ dla wyszukiwañ Modyfikowanie warunków wiÈzañ dla wyszukiwañ Zmiana typu zïÈczenia dla powiÈzañ jeden-do-jednego Tworzenie wielu powiÈzañ z tym samym modelem Dodawanie wiÈzañ w locie 9 11 13 13 16 17 17 17 19 19 20 24 28 31 33 36 38 45 49 49 50 51 59 63 65 66 69 Spis treĞci Rozdziaï 3. Wszystko o pobieraniu danych Wprowadzenie Wykonywanie zapytañ GROUP i COUNT Wykorzystywanie pól wirtualnych Tworzenie zapytañ z wykorzystaniem zïÈczeñ doraěnych Wyszukiwanie elementów speïniajÈcych okreĂlone kryteria Implementacja wïasnego typu wyszukiwania Stronicowanie wyszukiwañ wïasnych typów Implementacja stronicowania na bazie technologii AJAX Rozdziaï 4. Walidacja i zachowania Wprowadzenie Dodawanie wielu reguï walidacji Tworzenie wïasnych reguï walidacji Wykorzystywanie wywoïañ zwrotnych w zachowaniach Wykorzystywanie zachowañ do dodawania nowych pól Wykorzystywanie zachowania Sluggable Geokodowanie adresów przy uĝyciu zachowania Geocodable Rozdziaï 5. ½ródïa danych Wprowadzenie Udoskonalanie dziennika zapytañ ěródïa danych SQL Parsowanie plików CSV za pomocÈ ěródeï danych Konsumowanie kanaïów RSS za pomocÈ ěródeï danych Tworzenie ěródïa danych przy uĝyciu serwisu Twitter Dodawanie obsïugi transakcji i blokad w ěródle danych MySQL Rozdziaï 6. Magia trasowania Wprowadzenie Wykorzystywanie parametrów named i GET Wykorzystywanie tras z prefiksami Praca z elementami tras Dodawanie tras typu catch-all dla stron profilowych Dodawanie walidacji dla klas typu catch-all Tworzenie wïasnych klas trasowania Rozdziaï 7. Tworzenie i wykorzystywanie usïug sieciowych Wprowadzenie Tworzenie kanaïu RSS Konsumowanie usïugi JSON Tworzenie usïug REST przy uĝyciu formatu JSON Dodawanie uwierzytelniania do usïug REST Implementacja autoryzacji dostÚpu do API przy uĝyciu tokenu 6 73 73 74 80 84 87 89 93 96 99 99 100 104 109 116 118 122 127 127 127 134 138 142 152 161 161 162 168 172 175 179 182 187 187 188 194 199 208 213 Spis treĞci Rozdziaï 8. Praca z powïokami Wprowadzenie Tworzenie i uruchamianie powïoki Parsowanie parametrów wiersza poleceñ Tworzenie zadañ powïoki wielokrotnego uĝytku Wysyïanie wiadomoĂci e-mail z poziomu powïoki Tworzenie automatycznych zadañ za pomocÈ wtyczki Robot Rozdziaï 9. Internacjonalizacja aplikacji Wprowadzenie Internacjonalizacja tekstów w kontrolerach i widokach Internacjonalizacja komunikatów walidacji w modelach Tïumaczenie tekstów zawierajÈcych dynamicznie generowanÈ treĂÊ Ekstrakcja i tïumaczenie tekstów Tïumaczenie rekordów baz danych za pomocÈ zachowania Translate Ustawianie i zapamiÚtywanie jÚzyka Rozdziaï 10. Testowanie Wprowadzenie Konfiguracja frameworka do testów Tworzenie testowych danych i metod modeli Testowanie akcji kontrolera i ich widoków Wykorzystywanie zaĂlepek do testowania kontrolerów Uruchamianie testów w konsoli Rozdziaï 11. NarzÚdzia i klasy pomocnicze Wprowadzenie Wykorzystywanie klasy Set Operacje na tekĂcie przy uĝyciu klasy String Wysyïanie wiadomoĂci e-mail Wykrywanie typów plików za pomocÈ MagicDb Rzucanie i obsïuga wyjÈtków Skorowidz 219 219 220 224 229 239 243 249 249 250 256 259 262 266 270 273 273 274 278 286 290 294 297 297 298 305 308 314 319 325 7 9 Internacjonalizacja aplikacji W tym rozdziale omówimy nastÚpujÈce zagadnienia: Q internacjonalizacjÚ tekstów w kontrolerach i widokach; Q internacjonalizacjÚ komunikatów walidacji w modelach; Q tïumaczenie tekstów zawierajÈcych dynamicznie generowanÈ treĂÊ; Q ekstrakcjÚ i tïumaczenie tekstów; Q tïumaczenie rekordów baz danych za pomocÈ zachowania Translate; Q ustawianie i zapamiÚtywanie jÚzyka. Wprowadzenie W tym rozdziale zajmiemy siÚ przykïadami, które pozwolÈ na internacjonalizacjÚ — umiÚ- dzynarodowienie — wszystkich elementów aplikacji CakePHP, zarówno statycznych (zawartych np. w widokach), jak i dynamicznych (np. rekordy baz danych). W pierwszych dwóch przykïadach pokaĝemy, jak udostÚpniÊ elementy widoków, a takĝe ko- munikaty walidacji modelu do tïumaczeñ. W trzecim przykïadzie bÚdziemy tïumaczyÊ bardziej zïoĝone wyraĝenia. Czwarty przykïad to pokaz moĝliwoĂci wbudowanych narzÚdzi CakePHP, które potrafiÈ wyïuskaÊ statycznÈ treĂÊ aplikacji wymagajÈcÈ tïumaczenia. PiÈty przykïad przedstawia mechanizm tïumaczenia rekordów baz danych. Na zakoñczenie dowiesz siÚ, jak umoĝliwiÊ uĝytkownikowi zmianÚ aktywnego jÚzyka aplikacji. CakePHP 1.3. Programowanie aplikacji. Receptury Internacjonalizacja tekstów w kontrolerach i widokach W tym przykïadzie dowiesz siÚ, jak zinternacjonalizowaÊ tekst, który znajduje siÚ w widokach naszej aplikacji, a takĝe jak przygotowaÊ takie teksty do tïumaczenia. Zanim zaczniesz Aby wykonaÊ poniĝszy przykïad, musisz skorzystaÊ z przykïadowych danych. Utwórz tabelÚ articles, korzystajÈc z poniĝszego zapytania SQL: CREATE TABLE articles ( id INT UNSIGNED AUTO_INCREMENT NOT NULL, title VARCHAR(255) NOT NULL, body TEXT NOT NULL, created DATETIME NOT NULL, modified DATETIME NOT NULL, PRIMARY KEY( id ) ); Teraz dodaj kilka rekordów, korzystajÈc z poniĝszych zapytañ SQL: INSERT INTO articles ( title , body , created , modified ) VALUES ( First article , The body of the first article. , NOW(), NOW()), ( Second article , The body of the second article. , NOW(), NOW()), ( Third article , The body of the third article. , NOW(), NOW()); Utwórz plik app/controllers/articles_controller.php i umieĂÊ w nim kontroler o nastÚpujÈcej treĂci: ?php class ArticlesController extends AppController { public function index() { $this- paginate[ limit ] = 2; $articles = $this- paginate(); $this- set(compact( articles )); } public function add() { if (!empty($this- data)) { $this- Article- create(); if ($this- Article- save($this- data)) { $this- Session- setFlash( Article saved! ); $this- redirect(array( action = index )); } else { $this- Session- setFlash( Please correct errors! ); } } 250 Rozdziaá 9. • Internacjonalizacja aplikacji } public function view($id) { $article = $this- Article- find( first , array( conditions = array( Article.id = $id) )); if (empty($article)) { $this- cakeError( error404 ); } $this- set(compact( article )); } } ? W dalszej kolejnoĂci utwórz plik app/models/article.php o nastÚpujÈcej treĂci: ?php class Article extends AppModel { public $validate = array( title = notEmpty , body = notEmpty ); } ? Utwórz podkatalog app/views/articles, po czym dodaj do niego plik index.ctp o nastÚpujÈcej treĂci: h1 Articles /h1 p ?php echo $this- Paginator- counter(); ? nbsp;- nbsp; ?php echo $this- Paginator- prev(); ? nbsp; ?php echo $this- Paginator- numbers(); ? nbsp; ?php echo $this- Paginator- next(); ? /p p ?php echo count($articles) . articles: ; ? /p ul ?php foreach($articles as $article) { ? li ?php echo $this- Html- link( $article[ Article ][ title ], array( action = view , $article[ Article ][ id ]) ); ? /li ?php } ? /ul p ?php echo $this- Html- link( Create article , array( action = add )); ? /p 251 CakePHP 1.3. Programowanie aplikacji. Receptury Do katalogu app/views/articles dodaj plik add.ctp o nastÚpujÈcej treĂci: ?php echo $this- Form- create(); echo $this- Form- inputs(array( legend = Create article , title = array( label = Title ), body = array( label = Body ) )); echo $this- Form- end( Save ); ? Na zakoñczenie dodaj plik app/views/articles/view.ctp o nastÚpujÈcej treĂci: h1 ?php echo $article[ Article ][ title ]; ? /h1 ?php echo $article[ Article ][ body ]; ? Jak to zrobiÊ 1. Zmodyfikuj treĂÊ pliku app/controllers/articles_controller.php, uwzglÚdniajÈc zmiany zaznaczone pogrubionÈ czcionkÈ w metodzie add(): public function add() { if (!empty($this- data)) { $this- Article- create(); if ($this- Article- save($this- data)) { $this- Session- setFlash(__( Article saved , true)); $this- redirect(array( action = index )); } else { $this- Session- setFlash(__( Please correct the errors , true)); } } } 2. Otwórz plik app/views/articles/add.ctp i wprowadě zaznaczone pogrubionÈ czcionkÈ zmiany: ?php echo $this- Form- create(); echo $this- Form- inputs(array( legend = __( New Article , true), title = array( label = __( Title: , true)), body = array( label = __( Body: , true)) )); echo $this- Form- end(__( Save , true)); ? 252 Rozdziaá 9. • Internacjonalizacja aplikacji 3. Otwórz plik app/views/articles/index.ctp i wprowadě nastÚpujÈce zmiany: h1 ?php __( Articles ); ? /h1 p ?php echo $this- Paginator- counter(__( Showing records start - end in page page out of pages , true)); ? nbsp;- nbsp; ?php echo $this- Paginator- prev(__( Previous , true)); ? nbsp; ?php echo $this- Paginator- numbers(); ? nbsp; ?php echo $this- Paginator- next(__( Next , true)); ? /p p ?php $count = count($articles); echo $count . . __n( article , articles , $count, true) . : ; ? /p ul ?php foreach($articles as $article) { ? li ?php echo $this- Html- link( $article[ Article ][ title ], array( action = view , $article[ Article ][ id ]) ); ? /li ?php } ? /ul p ?php echo $this- Html- link(__( Create article , true), array( action = add )); ? /p Przejdě na stronÚ http://localhost/articles. PowinieneĂ otrzymaÊ stronicowanÈ listÚ artykuïów podobnÈ do przedstawionej na poniĝszym rysunku. 253 CakePHP 1.3. Programowanie aplikacji. Receptury Jak to dziaïa Dwie najwaĝniejsze metody udostÚpniane przez CakePHP do tïumaczenia to __() i __n(). Nazwy metod mogÈ wydaÊ siÚ nieco dziwne; ich pochodzenie wywodzi siÚ od implementacji narzÚdzia gettext w jÚzyku Perl — narzÚdzie to stanowi element Projektu Tïumaczenia GNU (GNU Translation Project). Metoda __() jest uĝywana do tïumaczenia tekstów statycznych i przyjmuje dwa parametry opisane w poniĝszej tabeli. Parametr singular return Opis Tekst, który ma byÊ przetïumaczony. JeĂli ten parametr ma wartoĂÊ true, przetïumaczony tekst zostanie zwrócony, a nie przesïany do klienta. DomyĂlnie false. Metoda __n() równieĝ pozwala na tïumaczenie tekstów statycznych, jednak uwzglÚdnia ona takĝe sytuacje, w których konkretna wartoĂÊ moĝe zaleĝeÊ od liczby — pojedynczej lub mno- giej. W zwiÈzku z tym przyjmuje ona cztery parametry wymienione w poniĝszej tabeli. Parametr singular plural count return Opis Tekst, który zostanie przetïumaczony na aktywny jÚzyk, jeĂli parametr count otrzyma wartoĂÊ singular. Tekst, który zostanie przetïumaczony na aktywny jÚzyk, jeĂli parametr count otrzyma wartoĂÊ plural. Zmienna lub wartoĂÊ liczbowa, która zostanie wykorzystana do okreĂlenia liczby dla danego tekstu (singular lub plural). JeĂli ten parametr ma wartoĂÊ true, przetïumaczony tekst zostanie zwrócony, a nie przesïany do klienta. DomyĂlnie false. Rozpoczynamy od zmiany komunikatów generowanych przez klasÚ ArticlesController, wy- korzystujÈc funkcjÚ __(). Zastrzegamy, ĝe teksty majÈ byÊ zwracane, a nie przesyïane do klienta. NastÚpnie modyfikujemy plik add.ctp, dziÚki czemu wszystkie etykiety formularza (wraz z jego legendÈ) zostanÈ przetïumaczone. W podobny sposób opakowujemy tytuï w widoku index.ctp za pomocÈ funkcji tïumaczenia. NastÚpnie korzystamy z pierwszego parametru metod counter(), next() i prev() (stanowiÈ- cych skïadowe klasy PaginatorHelper), aby przekazaÊ przetïumaczone wersje wszystkich tek- stowych elementów mechanizmu stronicowania. Na zakoñczenie korzystamy z funkcji __n(), by wybraÊ odpowiedni przetïumaczony tekst przy uĝyciu wartoĂci zmiennej count. 254 Rozdziaá 9. • Internacjonalizacja aplikacji JeĂli korzystasz z funkcji __n(), musisz pamiÚtaÊ, ĝe trzecim argumentem w wywoïaniach tej funkcji powinna byÊ zawsze zmienna, a nie wyraĝenie (np. zawierajÈce indeksy tablic). Wyraĝenia mogÈ do- prowadziÊ do zwrócenia nieoczekiwanych wyników podczas wywoïywania powïoki ekstraktora (por. przykïad „Ekstrakcja i tïumaczenie tekstów”). Domeny i kategorie Funkcje tïumaczeñ wykorzystywane w tym przykïadzie opakowujÈ funkcjÚ translate() nale- ĝÈcÈ do klasy I18n frameworka CakePHP. Metoda ta pozwala nie tylko na przeprowadzanie prostych tïumaczeñ; dziÚki niej programista moĝe okreĂliÊ domenÚ, z której sÈ pozyskiwane tïumaczone teksty, a takĝe kategoriÚ, do której naleĝy tekst do tïumaczenia. Domeny pozwalajÈ na wydzielanie grup tïumaczonych tekstów do osobnych plików. DomyĂl- nie, gdy domena nie jest okreĂlona jawnie, CakePHP korzysta z domeny default (domyĂlnej). JeĂli chcesz okreĂliÊ domenÚ, w której CakePHP powinien szukaÊ tïumaczonego tekstu, sko- rzystaj z funkcji __d() lub __dn(). Wyszukanie tïumaczonego tekstu w domenie moja_wtyczka wyglÈdaïoby nastÚpujÈco: $translated = __d( moja_wtyczka , Hello World , true); Kategorie umoĝliwiajÈ jeszcze wiÚkszÈ kontrolÚ nad zarzÈdzaniem tïumaczonymi tekstami. PozwalajÈ one na grupowanie plików tïumaczeñ w odrÚbnych katalogach; moĝna takĝe po- wiÈzaÊ tïumaczony tekst z dodatkowymi metadanymi. DomyĂlnie CakePHP zakïada, ĝe tïu- maczone teksty naleĝÈ do kategorii LC_MESSAGES. JeĂli chcesz zmieniÊ kategoriÚ, skorzystaj z funk- cji tïumaczenia __dc() i __dcn(), ustawiajÈc przedostatni argument — return — na wybranÈ kategoriÚ. Moĝe ona przyjmowaÊ jednÈ z okreĂlonych poniĝej wartoĂci: Q LC_ALL: 0; Q LC_COLLATE: 1; Q LC_CTYPE: 2; Q LC_MONETARY: 3; Q LC_NUMERIC: 4; Q LC_TIME: 5; Q LC_MESSAGES: 6. Próba znalezienia naleĝÈcego do kategorii LC_MESSAGES tekstu Hello World w domenie default wyglÈda nastÚpujÈco: $translated = __dc( default , Hello World , 6, true); KorzystajÈc z kategorii, zawsze podawaj wartoĂci liczbowe, a nie nazwy staïych. Te ostatnie sÈ bowiem zaleĝne od wykorzystywanej platformy. 255 CakePHP 1.3. Programowanie aplikacji. Receptury Zobacz równieĝ Q „Internacjonalizacja komunikatów walidacji w modelach”; Q „Ekstrakcja i tïumaczenie tekstów”. Internacjonalizacja komunikatów walidacji w modelach W tym przykïadzie wykorzystamy róĝne sposoby na zrealizowanie tego samego zadania: tïu- maczenia komunikatów walidacji w modelach. Zanim zaczniesz Aby wykonaÊ ten przykïad, musimy skorzystaÊ z podstawowego szkieletu aplikacji. W tym celu musisz wykonaÊ poprzedni przykïad. Jak to zrobiÊ Zmieñ treĂÊ pliku app/models/article.php, wprowadzajÈc zmiany zaznaczone pogrubionÈ czcionkÈ we wïaĂciwoĂci validate: public $validate = array( title = array( required = notEmpty ), body = array( required = notEmpty ) ); IstniejÈ dwa sposoby tïumaczenia komunikatów walidacji. Pierwszy z nich wymaga przesïo- niÚcia konstruktora modelu. Wystarczy dodaÊ jego poniĝszÈ implementacjÚ do klasy Article w pliku app/models/article.php: public function __construct($id = false, $table = null, $ds = null) { foreach($this- validate as $field = $rules) { if (!is_array($rules)) { $rules = (array) $rules; } foreach($rules as $key = $rule) { 256 Rozdziaá 9. • Internacjonalizacja aplikacji if (!is_array($rule)) { $rules[$key] = compact( rule ); } } $this- validate[$field] = $rules; } $this- validate = Set::merge($this- validate, array( title = array( required = array( message ´= __( A title must be specified , true)) ), body = array( required = array( message ´= __( You must define the body , true)) ) )); parent::__construct($id, $table, $ds); } InnÈ metodÈ tïumaczenia komunikatów walidacji jest przeniesienie komunikatów do widoku. W ten sposób zamiast przesïaniaÊ konstruktor i deklarowaÊ w nim komunikaty, wystarczy wprowadziÊ zmiany w pliku app/views/articles/add.ctp: ?php echo $this- Form- create(); echo $this- Form- inputs(array( title = array( label = __( Title: , true), error = array( required = __( A title must be specified , true) ) ), body = array( label = __( Body: , true), error = array( required = __( You must define the body , true) ) ) )); echo $this- Form- end(__( Save , true)); ? Obie metody doprowadzÈ do uzyskania takiego samego efektu. Przejdě na stronÚ http:// localhost/articles/add i wyĂlij formularz bez wprowadzania jakichkolwiek wartoĂci. PowinieneĂ uzyskaÊ efekt jak na poniĝszym rysunku. 257 CakePHP 1.3. Programowanie aplikacji. Receptury Jak to dziaïa Przed utworzeniem komunikatów o bïÚdach dla kaĝdej z reguï walidacji musimy owe reguïy nazwaÊ. W tym celu modyfikujemy model Article, dziÚki czemu kaĝda z reguï jest indekso- wana przy uĝyciu nazwy. W naszym przypadku wybieramy nazwÚ required dla reguïy Cake- PHP o nazwie notEmpty. Pierwsze rozwiÈzanie problemu tïumaczenia komunikatów walidacji moĝna okreĂliÊ mianem scentralizowanego — wszystkie komunikaty sÈ umieszczone w tym samym miejscu, w kon- struktorze modelu. Przesïaniamy konstruktor, dziÚki czemu moĝemy w jego wnÚtrzu zadekla- rowaÊ komunikaty o bïÚdach, które powinny byÊ przetïumaczone. MusieliĂmy skorzystaÊ z konstruktora, poniewaĝ wïaĂciwoĂci klas mogÈ zawieraÊ tylko statyczne przypisania. Poniĝszy blok kodu spowoduje bïÈd skïadni PHP: public $validate = array( title = array( required = array( rule = notEmpty , message = __( Nothing defined! , true) // B’kD SK’ADNI 258 Rozdziaá 9. • Internacjonalizacja aplikacji ) ) ); W implementacji konstruktora rozpoczynamy od sprawdzenia, czy wïaĂciwoĂÊ validate sta- nowi tablicÚ reguï (indeksowanych przy uĝyciu nazw pól). Musimy takĝe sprawdziÊ, czy kaĝ- da reguïa sama w sobie równieĝ stanowi tablicÚ (indeksowanÈ za pomocÈ nazw), której warto- Ăciami sÈ ponownie tablice, zawierajÈce przynajmniej ustawienie rule. Po zweryfikowaniu formatu wïaĂciwoĂci validate moĝemy poïÈczyÊ komunikaty walidacji dla kaĝdej z reguï, korzystajÈc z funkcji __() w celu przetïumaczenia komunikatów. Na zakoñ- czenie wywoïujemy konstruktor klasy bazowej, aby poprawnie zakoñczyÊ proces tworzenia caïego modelu. Drugie podejĂcie do problemu tïumaczenia przedstawione w tym przykïadzie przesuwa odpo- wiedzialnoĂÊ za obsïugÚ tïumaczeñ na widok, korzystajÈc z ustawienia error dostÚpnego w meto- dzie input() klasy FormHelper. To ustawienie otrzymuje tablicÚ indeksowanÈ za pomocÈ nazw reguï walidacji, której wartoĂciami sÈ komunikaty o bïÚdach wykorzystywane w razie niespeï- nienia poszczególnych reguï walidacji. Zobacz równieĝ Q „Ekstrakcja i tïumaczenie tekstów”. Tïumaczenie tekstów zawierajÈcych dynamicznie generowanÈ treĂÊ W tym przykïadzie dowiesz siÚ, jak tïumaczyÊ teksty, które zawierajÈ elementy dynamiczne — np. wartoĂci zmiennych. Zanim zaczniesz Aby wykonaÊ ten przykïad, musimy skorzystaÊ z podstawowego szkieletu aplikacji. W tym celu musisz wykonaÊ przykïad „Internacjonalizacja tekstów w kontrolerach i widokach”. Jak to zrobiÊ 1. Otwórz plik app/controllers/articles_controller.php i wprowadě zaznaczone pogrubionÈ czcionkÈ zmiany w metodzie add(): 259 CakePHP 1.3. Programowanie aplikacji. Receptury public function add() { if (!empty($this- data)) { $this- Article- create(); if ($this- Article- save($this- data)) { $this- Session- setFlash( sprintf(__( Article s saved , true), $this- Article- ´field( title )) ); $this- redirect(array( action = index )); } else { $this- Session- setFlash( ProszÚ poprawiÊ bïÚdy! ); } } } 2. Otwórz plik app/views/articles/index.ctp i wprowadě w nim zaznaczone pogrubionÈ czcionkÈ zmiany: h1 ?php __( Articles ); ? /h1 p ?php echo $this- Paginator- counter(__( Showing records start - end in page page out of pages , true)); ? nbsp;- nbsp; ?php echo $this- Paginator- prev(__( Previous , true)); ? nbsp; ?php echo $this- Paginator- numbers(); ? nbsp; ?php echo $this- Paginator- next(__( Next , true)); ? /p p ?php $count = count($articles); printf(__n( d article , d articles , $count, true), $count); ? /p ul ?php foreach($articles as $article) { ? li ?php echo $this- Html- link( $article[ Article ][ title ], array( action = view , $article[ Article ][ id ]) ); ? /li ?php } ? /ul p ?php echo $this- Html- link(__( Create article , true), array( action = add )); ? /p 260 Rozdziaá 9. • Internacjonalizacja aplikacji Jak to zrobiÊ Gdy podczas tworzenia aplikacji napotyka siÚ problem tïumaczenia treĂci zawierajÈcych ele- menty dynamiczne — np. wartoĂÊ zmiennej lub wartoĂÊ pola z bazy danych — moĝe siÚ po- jawiÊ pokusa doïÈczenia zmiennej do ïañcucha statycznego, a nastÚpnie przekazania takiego wyraĝenia do funkcji tïumaczenia: $translated = __( Hello . $name, true); // ½LE To wyraĝenie nie jest poprawne, poniewaĝ ekstraktor CakePHP (omówiony w przykïadzie „Ekstrakcja i tïumaczenie tekstów”) dziaïa poprawnie tylko dla tekstów statycznych. W innych jÚ- zykach moĝe na przykïad wystÈpiÊ koniecznoĂÊ zmiany kolejnoĂci sïów w zdaniu. W zwiÈzku z tym musimy skorzystaÊ z innej techniki przetwarzania ïañcuchów. RozwiÈzanie jest proste i stosunkowo popularne — funkcje PHP printf() i sprintf(). Obie funkcje przyjmujÈ te same argumenty. Pierwszy z nich jest obowiÈzkowy i okreĂla ïañ- cuch znaków do sformatowania. Wszystkie kolejne argumenty przekazane do funkcji zostanÈ wykorzystane do wygenerowania wynikowego ïañcucha znaków. Jedyna róĝnica pomiÚdzy funkcjami printf() a sprintf() polega na tym, ĝe pierwsza z nich wyĂwietli efekt swojej pra- cy, druga zaĂ — zwróci go. Przejděmy teraz do kodu naszej aplikacji. Rozpoczynamy od zmiany komunikatu zwracanego przez klasÚ ArticlesController po utworzeniu artykuïu. Korzystamy z funkcji sprintf(), ponie- waĝ efekt jej dziaïania chcemy przekazaÊ do metody setFlash() komponentu Session. W na- szej sytuacji wyraĝenie s pozwala na wstawienie do ïañcucha znaków tytuïu nowo utworzo- nego artykuïu. W podobny sposób podstawiamy wartoĂÊ zmiennej count pod ciÈg d. Tym razem korzystamy z funkcji printf(), aby wyĂwietliÊ od razu efekt dziaïania funkcji. Zmiana kolejnoĂci argumentów Gdy korzystamy z wyraĝeñ s lub d w funkcjach printf() i sprintf(), nie mamy kontroli nad sposobem pozycjonowania wartoĂci; nie moĝemy teĝ uĝyÊ dwa razy jednej wartoĂci, poniewaĝ kaĝde z wyraĝeñ jest dopasowywane do konkretnego, pojedynczego argumentu. Zaïóĝmy, ĝe dysponujemy nastÚpujÈcym wyraĝeniem: printf( Your name is s and your country is s , $name, $country); Pierwsze wyraĝenie s zostanie zastÈpione wartoĂciÈ zmiennej name, drugie — wartoĂciÈ zmiennej country. Problem pojawiïby siÚ w sytuacji, w której chcielibyĂmy zmieniÊ kolejnoĂÊ argumentów w ïañcuchu znaków, zachowujÈc jednoczeĂnie kolejnoĂÊ argumentów w obrÚbie wywoïania funkcji printf(). Na szczÚĂcie do argumentów funkcji printf() moĝemy siÚ odwoïywaÊ, korzystajÈc z ich nu- merów porzÈdkowych (okreĂlajÈcych ich pozycjÚ wĂród wszystkich argumentów przekaza- nych w danym wywoïaniu). W poniĝszym przykïadzie name jest argumentem 1, a country — argumentem 2: 261 CakePHP 1.3. Programowanie aplikacji. Receptury printf( You are from 2$s and your name is 1$s , $name, $country); Takie podejĂcie pozwala na ponowne uĝycie argumentu bez koniecznoĂci podawania go wie- lokrotnie w wywoïaniu funkcji printf(): printf( You are from 2$s and your name is 1$s . Welcome 1$s! , $name, ´$country); Zobacz równieĝ Q „Ekstrakcja i tïumaczenie tekstów”. Ekstrakcja i tïumaczenie tekstów W tym przykïadzie nauczymy siÚ pozyskiwaÊ wszystkie ïañcuchy znaków, które podlegajÈ tïumaczeniu w naszych aplikacjach CakePHP, a nastÚpnie przeprowadzimy proces tïumacze- nia, korzystajÈc z darmowego oprogramowania. Zanim zaczniesz Aby wykonaÊ ten przykïad, musimy skorzystaÊ z podstawowego szkieletu aplikacji. W tym celu musisz wykonaÊ przykïad „Internacjonalizacja tekstów w kontrolerach i widokach”. Musisz takĝe zainstalowaÊ aplikacjÚ Poedit w swoim systemie. Przejdě na stronÚ http://www. poedit.net/download.php, a nastÚpnie pobierz plik dla swojego systemu operacyjnego. Jak to zrobiÊ Przejdě do podkatalogu app/ Twojej aplikacji w wierszu poleceñ, a nastÚpnie wykonaj poniĝsze polecenie: Q jeĂli pracujesz w systemach GNU Linux/Mac/Unix: ../cake/console/cake i18n extract Q jeĂli jesteĂ uĝytkownikiem systemu Microsoft Windows: ..cakeconsolecake.bat i18n extract PowinieneĂ skorzystaÊ z ustawieñ domyĂlnych, jak przedstawiono na kolejnym rysunku. Po udzieleniu odpowiedzi na ostatnie pytanie powïoka przeszuka wszystkie pliki Twojej apli- kacji i na ich podstawie wygeneruje szablon tïumaczenia. Zostanie on umieszczony w pliku app/locale/default.pot. 262 Rozdziaá 9. • Internacjonalizacja aplikacji Otwórz plik Poedit, a nastÚpnie wybierz opcjÚ Nowy katalog z pliku POT z menu Plik. Pro- gram wyĂwietli okno wyboru pliku. Przejdě do podkatalogu app/locale Twojej aplikacji, za- znacz plik default.pot i kliknij przycisk Otwórz. Zostanie wyĂwietlone okno ustawieñ przed- stawione na poniĝszym rysunku. 263 CakePHP 1.3. Programowanie aplikacji. Receptury W oknie Ustawienia wprowadě nazwÚ projektu i informacje z nim zwiÈzane. W polu Formy liczby mnogiej powinieneĂ wprowadziÊ wyraĝenie, przy uĝyciu którego Poedit bÚdzie w stanie rozpoznaÊ tïumaczenia dla liczb mnogich. W wielu jÚzykach (np. angielskim, hiszpañskim, niemieckim i portugalskim) wystarczy wprowadziÊ poniĝsze wyraĝenie: nplurals=2; plural=(n != 1); WiÚcej informacji na temat liczb mnogich i wartoĂci, które powinno siÚ wobec nich stosowaÊ (w zaleĝ- noĂci od tïumaczonego jÚzyka) znajdziesz na stronie http://drupal.org/node/17564. Po wprowadzeniu wszystkich istotnych informacji kliknij przycisk OK. W tym momencie pro- gram zapyta, gdzie chcesz zapisaÊ przetïumaczony plik. Utwórz katalog o nazwie pol i umieĂÊ go w katalogu app/locale/. WewnÈtrz katalogu pol utwórz podkatalog LC_MESSAGES. NastÚpnie przy uĝyciu okna dialogowego programu Poedit wybierz folder app/locale/pol/LC_MESSAGES, po czym kliknij przycisk Zapisz, nie zmieniajÈc przy tym nazwy pliku — powinna mieÊ war- toĂÊ default.po. Program Poedit zaprezentuje wszystkie oryginalne ïañcuchy znaków. Do kaĝdego z nich moĝna dodaÊ tïumaczenie. Wystarczy wybraÊ jeden z oryginalnych tekstów, a nastÚpnie wprowadziÊ treĂÊ tïumaczenia w polu umieszczonym w dolnej czÚĂci okna. Po wprowadzeniu tïumaczeñ okno programu Poedit powinno wyglÈdaÊ tak, jak na kolejnej rysunku. Wybierz opcjÚ Zapisz z menu Plik, aby zapisaÊ przetïumaczony plik. W katalogu app/locale/ pol/LC_MESSAGES powinny byÊ dostÚpne dwa pliki: default.po i default.mo. Jak to dziaïa Na samym poczÈtku ekstraktor CakePHP musi otrzymaÊ Ăcieĝki do katalogów, które majÈ byÊ przez niego przetworzone. NastÚpnie mechanizm rekursywnie przeglÈda wszystkie katalogi, próbujÈc znaleěÊ wszystkie wywoïania funkcji tïumaczenia (__(), __n(), __d(), __dn(), __dcn() i __c()) w plikach PHP i plikach widoków. Dla kaĝdego znalezionego wywoïania ekstraktor wyïuska z niego tekst do przetïumaczenia (pierwszy argument wywoïañ funkcji __n() i __c(); drugi argument wywoïañ funkcji __d() i __dc(); pierwszy i drugi argument wywoïañ funkcji __n(); drugi i trzeci argument wywoïañ funkcji __dn() i __dcn()). W argumentach, które sÈ wyïuskiwane przez ekstraktor, naleĝy stosowaÊ jedynie statyczne ïañcuchy znaków PHP. Nie moĝna w ĝadnym przypadku uĝywaÊ wyraĝeñ PHP. JeĂli w tïumaczonych tekstach chcesz stosowaÊ zmienne lub inne wyraĝenia dynamiczne, zapoznaj siÚ z przykïadem „Tïumaczenie tek- stów zawierajÈcych dynamicznie generowanÈ treĂÊ”. 264 Rozdziaá 9. • Internacjonalizacja aplikacji Po pobraniu wszystkich tekstów do tïumaczenia przez ekstraktor zostanÈ utworzone odpo- wiednie szablony plików tïumaczeñ. JeĂli w swojej aplikacji korzystasz z funkcji tïumaczeñ, które majÈ zwiÈzek z domenami (__d(), __dn(), __dc() i __dcn()), moĝesz uwzglÚdniÊ wszystkie ïañcuchy w jednym pliku szablonu albo umieĂciÊ kaĝdÈ domenÚ w odrÚbnym pliku szablonu. Pliki szablonów majÈ rozszerzenie pot; ich nazwy sÈ zaĂ nazwami domen (np. default.pot jest domyĂlnym (default) plikiem szablonu). JeĂli otworzysz plik default.pot w zwykïym edytorze tekstowym, zauwaĝysz, ĝe rozpoczyna siÚ on od nagïówka zawierajÈcego wiele róĝnych ustawieñ, po którym nastÚpuje wïaĂciwa czÚĂÊ tïumaczenia. Kaĝdy ïañcuch do tïumaczenia jest reprezentowany za pomocÈ dwóch linijek — pierwsza z nich zawiera element oznaczony ciÈgiem msgid (ïañcuch do tïumaczenia), w drugiej zaĂ znajduje siÚ ciÈg msgstr — to wïaĂnie tam naleĝy wstawiaÊ przetïumaczone ïañcuchy znaków. Program Poedit umoĝliwia wygodnÈ edycjÚ plików w formacie pot, a takĝe zapisuje pliki do odpowiedniego katalogu (app/locale/pol/LC_MESSAGES). W katalogu tym znajdujÈ siÚ dwa pliki — default.po i default.pot. JeĂli otworzysz plik .po za pomocÈ zwykïego edytora, powinieneĂ natychmiast dostrzec podobieñstwo tego pliku do pliku szablonu. WyjÈtek stanowiÈ ustawie- 265 CakePHP 1.3. Programowanie aplikacji. Receptury nia nagïówka — zawierajÈ one wartoĂci okreĂlone przez nas w programie Poedit — i przede wszystkim treĂÊ tïumaczeñ wprowadzonych przez nas w aplikacji Poedit. Plik default.mo stanowi binarnÈ wersjÚ pliku default.po, takĝe wygenerowanego przez Poedit. Plik default.mo jest wykorzystywany przez CakePHP w celu szybszego przetwarzania pliku tïumaczeñ. Tïumaczenie rekordów baz danych za pomocÈ zachowania Translate W tym przykïadzie nauczymy siÚ tïumaczyÊ rekordy z bazy danych za pomocÈ zachowania Translate. Zanim zaczniesz Aby wykonaÊ ten przykïad, musimy skorzystaÊ z podstawowego szkieletu aplikacji. W tym celu musisz wykonaÊ przykïad „Internacjonalizacja tekstów w kontrolerach i widokach”. Jak to zrobiÊ Uruchom wiersz poleceñ, a nastÚpnie przejdě do podkatalogu app/ aplikacji i wykonaj poniĝsze polecenie. Q jeĂli pracujesz w systemach GNU Linux/Mac/Unix: ../cake/console/cake i18n initdb Q jeĂli jesteĂ uĝytkownikiem systemu Microsoft Windows: ..cakeconsolecake.bat i18n initdb Zaakceptuj domyĂlne opcje. Po wybraniu wszystkich opcji powïoka utworzy tabelÚ i18n, co przedstawiono na kolejnym rysunku. Zmodyfikuj treĂÊ pliku app/models/article.php zgodnie z poniĝszym listingiem: ?php class Article extends AppModel { public $validate = array( title = notEmpty , body = notEmpty ); public $actsAs = array( Translate = array( title , body ) ); } ? 266 Rozdziaá 9. • Internacjonalizacja aplikacji Teraz musimy przenieĂÊ wartoĂci pól title i body z tabeli articles do tabeli i18n, a nastÚpnie — usunÈÊ oryginalne kolumny z tabeli articles. Wykonaj poniĝsze zapytania SQL: INSERT INTO i18n ( locale , model , foreign_key , field , content ) SELECT eng , Article , articles . id , title , articles . title FROM articles ; INSERT INTO i18n ( locale , model , foreign_key , field , content ) SELECT eng , Article , articles . id , body , articles . body FROM articles ; ALTER TABLE articles DROP COLUMN title , DROP COLUMN body ; Dodaj polskie tïumaczenia naszych artykuïów, wykonujÈc poniĝsze zapytania SQL: INSERT INTO i18n ( locale , model , foreign_key , field , content ) VALUES ( pol , Article , 1, title , Pierwszy artykuï ), ( pol , Article , 1, body , TreĂÊ pierwszego artykuïu ), ( pol , Article , 2, title , Drugi artykuï ), ( pol , Article , 2, body , TreĂÊ drugiego artykuïu ), ( pol , Article , 3, title , Trzeci artykuï ), ( pol , Article , 3, body , TreĂÊ trzeciego artykuïu ); Na zakoñczenie wstaw poniĝszÈ instrukcjÚ na koñcu pliku app/config/bootstrap.php, tuĝ przed znacznikiem zamykajÈcym PHP: Configure::write( Config.language , eng ); 267 CakePHP 1.3. Programowanie aplikacji. Receptury Przejdě na stronÚ http://localhost/articles. PowinieneĂ zobaczyÊ ten sam wykaz artykuïów, który przedstawiono w pierwszym przykïadzie w tym rozdziale. Jak to dziaïa Rozpoczynamy od utworzenia tabeli wymaganej przez zachowanie Translate, korzystajÈc z powïoki i18n. Nosi ona takÈ samÈ nazwÚ i zawiera (poza kluczem gïównym) pola opisane w poniĝszej tabeli. Pole locale model foreign_key field content Opis JÚzyk tïumaczenia danego rekordu. Model, do którego naleĝy tïumaczony rekord. ID (klucz gïówny) w modelu, który identyfikuje tïumaczony rekord. Nazwa pola, które podlega tïumaczeniu. Przetïumaczona wartoĂÊ dla danego pola. NastÚpnie moĝemy dodaÊ zachowanie Translate do modelu Article i ustawiÊ je tak, aby byïy tïumaczone pola title i body. Taki zapis sprawi, ĝe pola te nie bÚdÈ wchodziïy w skïad tabeli articles — od tego momentu bÚdÈ one przechowywane w tabeli i18n. KorzystajÈc z wartoĂci model i foreign_key w tabeli i18n, zachowanie Translate pobierze odpowiednie wartoĂci dla danych pól przy kaĝdym pobraniu rekordu modelu Article (dla aktywnego jÚzyka). Kopiujemy wartoĂci pól title i body do tabeli i18n, dziÚki czemu moĝemy usunÈÊ pola z ta- beli articles. Wywoïanie funkcji call() wykorzystywane w klasie ArticlesController nie wymaga ĝadnych zmian. Co wiÚcej, proces tworzenia artykuïów bÚdzie przebiegaï bez ĝad- nych modyfikacji, poniewaĝ zachowanie Translate skorzysta z aktywnego jÚzyka podczas za- pisywania rekordów modelu Article. Na zakoñczenie musimy wybraÊ jÚzyk domyĂlny. W tym celu korzystamy z ustawienia Config.language. PominiÚcie tego kroku spowoduje ustawienie jÚzyka na podstawie wartoĂci nagïówka HTTP_ACCEPT_LANGUAGE wysyïanego przez przeglÈdarki. Wykorzystywanie odrÚbnych tabel tïumaczenia Wszystkie modele, które korzystajÈ z zachowania Translate, bÚdÈ zapisywaÊ tïumaczenia swoich pól domyĂlnie do tabeli i18n. Takie zachowanie moĝe byÊ nieco problematyczne, jeĂli dysponujemy duĝÈ liczbÈ rekordów lub duĝÈ liczbÈ tïumaczonych modeli. Na szczÚĂcie za- chowanie Translate pozwala na skonfigurowanie innego modelu tïumaczenia. W ramach przykïadu zapiszemy wszystkie tïumaczenia zwiÈzane z artykuïami do tabeli article_translations. Utwórz tabelÚ, a nastÚpnie skopiuj rekordy z tabeli i18n, korzystajÈc z poniĝszych zapytañ SQL: 268 Rozdziaá 9. • Internacjonalizacja aplikacji CREATE TABLE article_translations ( id INT UNSIGNED AUTO_INCREMENT NOT NULL, model VARCHAR(255) NOT NULL, foreign_key INT UNSIGNED NOT NULL, locale VARCHAR(6) NOT NULL, field VARCHAR(255) NOT NULL, content TEXT default NULL, KEY model__foreign_key ( model , foreign_key ), KEY model__foreign_key__locale ( model , foreign_key , locale ), PRIMARY KEY( id ) ); INSERT INTO article_translations SELECT id , model , foreign_key , locale , field , content FROM i18n ; Utwórz plik app/models/article_translation.php i wstaw do niego poniĝszy kod: ?php class ArticleTranslation extends AppModel { public $displayField = field ; } ? WïaĂciwoĂÊ displayField w modelu tïumaczeñ poinformuje zachowanie Translate o tym, które pole tabeli przechowuje nazwÚ tïumaczonego pola. Na zakoñczenie wprowadě zaznaczone pogrubionÈ czcionkÈ zmiany w pliku app/models/ article.php: ?php class Article extends AppModel { public $validate = array( title = notEmpty , body = notEmpty ); public $actsAs = array( Translate = array( title , body ) ); public $translateModel = ArticleTranslation ; } ? Zobacz równieĝ Q „Ustawianie i zapamiÚtywanie jÚzyka”. 269 CakePHP 1.3. Programowanie aplikacji. Receptury Ustawianie i zapamiÚtywanie jÚzyka W tym przykïadzie dowiesz siÚ, jak udostÚpniÊ uĝytkownikom moĝliwoĂÊ zmiany jÚzyka apli- kacji, a takĝe jak zapamiÚtaÊ ich wybór za pomocÈ ciasteczek (ang. cookies). Zanim zaczniesz Aby wykonaÊ ten przykïad, niezbÚdna bÚdzie w peïni umiÚdzynarodowiona aplikacja. W tym celu musisz wykonaÊ caïy przykïad „Tïumaczenie rekordów baz danych za pomocÈ zachowania Translate”. Musimy takĝe skorzystaÊ z ukïadu aplikacji, który moĝemy modyfikowaÊ. Skopiuj plik default.ctp z katalogu cake/libs/view/layouts do katalogu app/views/layouts. Jak to zrobiÊ 1. Dodaj poniĝsze instrukcje na koñcu pliku app/config/bootstrap.php, tuĝ przed znacznikiem zamykajÈcym PHP: Configure::write( Config.languages , array( eng = __( English , true), pol = __( Polski , true) )); 2. Zmieñ ukïad pliku app/views/layouts/default.ctp, dodajÈc w wybranym przez siebie miejscu listÚ jÚzyków (np. przed wywoïaniem metody flash() w komponencie Session): div style= float: right ?php $links = array(); $currentLanguage = Configure::read( Config.language ); foreach(Configure::read( Config.languages ) as $code = $language) { if ($code == $currentLanguage) { $links[] = $language; } else { $links[] = $this- Html- link($language, array( lang = $code)); } } echo implode( - , $links); ? /div 270 Rozdziaá 9. • Internacjonalizacja aplikacji Wykorzystywane w kodzie ustawienie Config.language zostaïo ustawione w pliku app/config/ bootstrap.php w ramach przykïadu „Tïumaczenie rekordów baz danych za pomocÈ zachowania Translate”. 3. Utwórz plik app/app_controller.php o nastÚpujÈcej treĂci: ?php class AppController extends Controller { public $components = array( Language , Session ); } ? 4. Utwórz plik app/controller/components/language.php o nastÚpujÈcej treĂci: ?php class LanguageComponent extends Object { public $controller = null; public $components = array( Cookie ); public $languages = array(); public function initialize($controller) { $this- controller = $controller; if (empty($languages)) { $this- languages = Configure::read( Config.languages ); } $this- set(); } public function set($language = null) { $saveCookie = false; if (empty($language) isset($this- controller)) { if (!empty($this- controller- params[ named ][ lang ])) { $language = $this- controller- params[ named ][ lang ]; } elseif (!empty($this- controller- params[ url ][ lang ])) { $language = $this- controller- params[ url ][ lang ]; } if (!empty($language)) { $saveCookie = true; } } if (empty($language)) { $language = $this- Cookie- read( language ); if (empty($language)) { $saveCookie = true; } } if (empty($language) !array_key_exists($language, $this- ´languages)) { $language = Configure::read( Config.language ); } Configure::write( Config.language , $language); if ($saveCookie) { 271 CakePHP 1.3. Programowanie aplikacji. Receptury $this- Cookie- write( language , $language, false, 1 year ); } } } ? Przejdě na stronÚ http://localhost/articles. PowinieneĂ zobaczyÊ listÚ artykuïów, a w prawym górnym rogu powinno siÚ pojawiÊ ïÈcze, które pozwoli na zmianÚ aktywnego jÚzyka na polski. KlikniÚcie ïÈcza spowoduje wyĂwietlenie polskich wersji artykuïów. Efekt zostaï przedsta- wiony na poniĝszym rysunku. Jak to dziaïa Zaczynamy od zadeklarowania listy wszystkich dostÚpnych jÚzyków, dziÚki czemu moĝemy bez problemu umieĂciÊ ïÈcze do zmiany aktywnego jÚzyka. Lista sïuĝy nam do stworzenia li- sty hiperïÈczy, która nastÚpnie jest umieszczana w pliku ukïadu default.ctp. JednoczeĂnie faktyczne ïÈcza (a nie teksty) sÈ generowane dla wszystkich jÚzyków poza aktywnym. Aktywny jÚzyk ustawiamy w zmiennej konfiguracyjnej CakePHP o nazwie Config.language. Otrzymuje ona pewnÈ wartoĂÊ — w naszym przypadku eng — w pliku konfiguracyjnym bootstrap.php. JeĂli konieczna jest zmiana jÚzyka, wartoĂÊ tego ustawienia powinna ulec zmianie przed pierwszym uĝyciem funkcji tïumaczenia. Aby zachowaÊ porzÈdek w kontrolerze, postanowiliĂmy utworzyÊ komponent Language, który obsïuguje zmianÚ jÚzyka. Komponent ten przeszuka parametry nazwane, a takĝe te przekaza- ne w adresie URL, pod kÈtem parametru lang. JeĂli jÚzyk nie zostaï okreĂlony w ten sposób, komponent spróbuje znaleěÊ jÚzyk, korzystajÈc z ciasteczka. JeĂli nie zostaïo ustawione ĝadne ciasteczko, a takĝe w sytuacji, gdy nastÈpiïo ĝÈdanie zmiany jÚzyka, komponent zapisze aktywny jÚzyk w ciasteczku language, które bÚdzie przechowywa- ne przez okres jednego roku. 272 Skorowidz __(), 254 __n(), 254, 255 _authorize(), 151 _checkArgs(), 228 _findMethods, wïaĂciwoĂÊ, 92 _help(), 238 _helpCommand(), 238 _importCSV(), 229 _isJSON(), 207 _parseCSV(), 228 _randomPassword(), 223 _restLogin(), 212 _stop(), 223, 318 _usageCommand(), 238 A Access Control Layer, Patrz warstwa kontroli dostÚpu ACL, Patrz warstwa kontroli dostÚpu acl_extras, plugin, 45 add(), 228 afterFind(), 77, 83, 114 AJAX, 96, 98 allow(), 23 allowedActions, parametr, 23 analyze(), 318 AppController, klasa, 24, 26 AppException, klasa, 322, 323 ArticlesController, klasa, 196, 254, 261 ArticlesController::index(), 191 assertEqual(), 283 assertFalse(), 283 assertIsA(), 283 assertNull(), 283 assertPattern(), 283 assertTags(), 284, 289 assertTrue(), 283 Auth, komponent, 23, 24, 26, 30, 33, 212 haszowanie haseï, 224 schemat autoryzacji, 27 uĝywanie i konfiguracja, 24 authorize, parametr, 23 automatyzacja zadañ, 243 autoryzacja przy uĝyciu tokenu, 213 schemat, 27 wykorzystanie warstwy kontroli dostÚpu, 38 B backAutoCommit, wïaĂciwoĂÊ, 159 beforeFilter(), 23, 26 beforeFind(), 77, 83, 114 beforeRender, wywoïanie zwrotne, 133 beforeSave, wywoïanie zwrotne, 117, 122 beforeValidate(), 318 bindModel(), 50, 63, 65, 71 blackHole(), 213, 217 C Cache, klasa, 114 CakePHP, 13, 14, 15, 16 ekstraktor, 261 konwencja nazewnicza, 68 powïoki, 219 reguïy walidacji, 104 tïumaczenia, 254 trasy domyĂlne, 162 wyjÈtki, 319 wyszukiwanie, 73, 74 CakeTestCase, klasa, 282, 283 CakeTestFixture, klasa, 281 catch-all, trasy, 175 dodawanie walidacji, 179 ciasteczka, 270 ClassRegistry::init(), 282 cleanInsert(), 306 commands, wïaĂciwoĂÊ, 237, 238 comma-separated values, Patrz CSV Config.language, 271, 272 Configure, klasa, 292 Configure::listObjects(), 182 ConnectionManager::getDataSo urce(), 133 contain(), 58 contain, parametr, 58 format, 57 Containable, zachowanie, 50, 51, 53, 55, 56, 57, 59, 63, 65 cookies, Patrz ciasteczka COUNT, 74, 83 Crookes, Neil, 142 CSV, 136 dynamiczne ïadowanie plików, 137 parsowanie plików, 134 Skorowidz D dane testowe, 273, 278, 281 datasources, wtyczka, 134, 136, 139 diff(), 305 Dispatcher, klasa, 294 download(), 317, 318 E e-mail wysyïanie, 308 wysyïanie z poziomu powïoki, 239 Email, komponent, 239, 308, 311, 312, 313 wïaĂciwoĂci, 242 endCase(), 283 endTest(), 283 error(), 223 execute(), 236, 238 expectAtLeastOnce(), 293 expectException(), 283 expectNever(), 293 expectOnce(), 293 EXPLAIN, 133 extract(), 237, 301 F fclose(), 228 fgetcsv(), 228 fiksturki, 278, 281, 283, 284 filter(), 305 fixture, zadanie, 284 fixtures, Patrz dane testowe fopen(), 228 foreignKey, ustawienie, 68 G Geocodable, 15, 100, 122 Geocode, wtyczka, 122, 124, 126 geokodowanie adresów, 122 GET, parametr, 162, 166 get_class_vars(), 238 getInfo(), 323 getLog(), 134 326 getMagicDb(), 318 Google Maps, 122, 124, 126 GROUP, 74 K Kairys, Donatas, 139 konwencja nazewnicza, 68 H L hasïa hasz, 20 haszowanie, 223, 224 szyfrowanie, 24 help(), 228, 236 HelpTask, klasa, 236, 238 HttpSocket, klasa, 107, 194 HttpSocket::get(), 197 HttpSocketOauth, klasa, 142 I I18n, klasa, 255 import(), 228, 237 in(), 222, 223 index(), 311 initialize(), 238 INNER JOIN, 66 InnoDb, 152 inputs, metoda, 23 insert(), 306, 307 internacjonalizacja, 249 komunikatów walidacji w modelach, 256 tekstów w kontrolerach i widokach, 250 isAuthorized, metoda, 23 isInterfaceSupported(), 133 J JavaScript Object Notation, Patrz JSON jÚzyk ustawianie, 270 zapamiÚtywanie, 270 JOIN, zïÈczenia, 66 jQuery, 96 JSON, 194 konsumowanie usïugi, 194 json_decode(), 151, 198 json_encode(), 207 JSON-C, 194 Language, komponent, 272 layout, wïaĂciwoĂÊ, 312 LEFT JOIN, 66 LIKE, 87, 88 listSources(), 138 lock(), 159 lockTimeoutErrorCode, wïaĂciwoĂÊ, 159 logException(), 323 login(), 22, 23, 30 logout(), 22, 23 logowanie, 28 pobieranie informacji o zalogowanym uĝytkowniku, 33 zapisanie informacji o uĝytkowniku, 31 ’ ïañcuchy znaków, 305 ïÈcza trwaïe, 118 M MagicDb, 314, 317, 318 main(), 222, 236 mapowanie obiektowo- relacyjne, Patrz ORM merge(), 305 mocks, Patrz zaĂlepki Model, klasa, 50 Model-View-Controller, Patrz MVC model-widok-kontroler, Patrz MVC MVC, 196 MyISAM, 152 MySQL blokady w ěródle danych, 152 transakcje, 152 N named parameters, Patrz parametry nazwane named, parametr, 162, 166 numeric(), 305 ProfileRoute, klasa, 184 ProfilesController, klasa, 172, 217 przypadki testowe, 273, 282 pushDiff(), 305 Q O QueryLog, komponent, 133 OAuth, 142, 149, 151 OpenAuth, komponent, 46, 47 OpenID, 45 biblioteka, 45 integracja, 45, 46 plugin, 46, 47 options(), 98 optymalizacja dla wyszukiwarek internetowych, 161 ORM, 298 P paginate(), 95 Paginator, 98 pamiÚÊ podrÚczna, 192 parametry nazwane, 164, 166 parsowanie parametrów wiersza poleceñ, 224 plików CSV, 134 partial mocks, Patrz zaĂlepki czÚĂciowe permanent links, Patrz ïÈcza trwaïe PHP OAuth, biblioteka, 142 Poedit, 262, 263, 264, 265, 266 pola wirtualne, 80, 82, 83 PostsController, klasa, 193 powiÈzania, 49 anulowanie zmian, 58 powïoki, 219 tworzenie, 220 tworzenie zadañ wielokrotnego uĝytku, 229 uruchamianie, 220, 221, 222 wysyïanie wiadomoĂci e-mail, 239 prefiksy, 36, 168, 172 printf(), 261, 262 R read(), 151 readfile(), 318 redirect(), 291, 292 renderException(), 323 Representational State Transfer, Patrz REST RequestHandler, komponent, 191, 207 requireLogin(), 212 reset(), 242 resetBindings(), 58 REST, 199, 207 dodawanie uwierzytelniania, 208 reverse(), 305 RIGHT JOIN, 66 Robot, wtyczka, 243, 246 RobotTask, model, 246 Router::connect(), 174 Router::connectNamed(), 167 Router::parseExtensions(), 190 Routing.prefixes, 172 RSS, 138, 188 a pamiÚÊ podrÚczna, 192 tworzenie kanaïu, 188 RssHelper, klasa, 192 RssHelper::item(), 192 S schedule(), 246 schema(), 82 Search Engine Optimization, Security, komponent, 212, Patrz SEO 213, 217 Security.salt, parametr, 24 Skorowidz Security::hash(), 223, 224 send(), 242, 312, 313 SEO, 118, 161 Session, komponent, 261 Set, klasa, 298, 301, 305 Set::combine(), 303 Set::extract(), 301, 302, 303 Set::format(), 304 Set::map(), 304 Set::matches(), 137 setAutoCommit(), 160 setConfig(), 138, 141, 151 setFlash(), 261 setup(), 113 Shell, klasa, 222 SimpleTest, biblioteka, 276, 278 slug, 118, 122 Sluggable, 15, 100, 118, 122 sort(), 305 sprintf(), 261, 304 startCase(), 283 startTest(), 283 startup(), 236 Story, Mark, 45, 294 String, klasa, 305, 306 stronicowanie, 93, 95 AJAX, 96 Syrup, wtyczka, 120 szperacze sieciowe, 192 T TagsController::view(), 162 tekst, manipulacja, 305 template, wïaĂciwoĂÊ, 313 test cases, Patrz przypadki testowe test jednostkowy, 282 test_suite, 282 testAction(), 288, 289 testowanie, 273 akcji kontrolera i ich widoków, 286 konfiguracja frameworka, 274 tworzenie danych testowych, 278 zaĂlepki, 290 testRedirect, wïaĂciwoĂÊ, 292 testsuite, powïoka, 294 327 uwierzytelnianie, 19 konfiguracja prostego systemu, 20 uĝytkownik pobieranie informacji, 33 zapisanie informacji po zalogowaniu, 31 zmiana domyĂlnego modelu, 27 V validate, wïaĂciwoĂÊ, 102, 259 validateTwitter(), 106, 107 Validation, klasa, 104 Video::search(), 198 W walidacja, 99 dodawanie wielu reguï, 100, tworzenie wïasnych reguï, 102 104, 107 warstwa kontroli dostÚpu, 38 web crawlers, Patrz szperacze web services, Patrz usïugi sieciowe sieciowe welcome(), 246 wiÈzania modeli, 49 modyfikowanie parametrów, 59 modyfikowanie warunków, 63 tworzenie wielu powiÈzañ, 66 wiersz poleceñ, parsowanie parametrów, 224 wirtualne pola, 80, 82, 83 write(), 151 wyjÈtki, 319 wyszukiwanie, 73, 74, 87 stronicowanie, 93, 95 wïasne typy, 89, 92, 93 wywoïania zwrotne, 109 X Xdebug, 285 XmlHelper, klasa, 192 X-Path 2.0, 301, 302 Z zachowania, 99 dodawanie nowych pól, 116 zadania, automatyzacja, 243 zaĂlepki, 290, 292, 293 czÚĂciowe, 293 zïÈczenia, 65, 66 zïÈczenia doraěne, 84 ½ ěródïa danych, 127 konsumowanie kanaïów RSS, 138 parsowanie plików CSV, 134 tworzenie, 142 Skorowidz testy jednostkowe, 273 uruchamianie w konsoli, 294 timeline(), 113, 114 tïumaczenie, 254, 262 rekordów baz danych, 266 tekstów zawierajÈcych dynamicznie generowanÈ treĂÊ, 259 token(), 151 tokenize(), 306, 307 tokeny, 213, 217 transakcje, 152 translate(), 255 Translate, zachowanie, 266, 268 trasowanie, 161, 168, 172 odwrotne, 175 tworzenie wïasnych klas, 182 Twitter, rejestracja aplikacji, TwitterAccountBehavior, 143, 144 klasa, 113 U unbindModel(), 50, 56, 57 uniwersalnie unikalny identyfikator, Patrz UUID unlock(), 159, 160 UploadsController, klasa, 322 User::useToken(), 218 UsersController, klasa, 217 UserShell, klasa, 222, 237, 238 useToken(), 217 usïugi sieciowe, 187 UUID, 217, 307 uuid(), 307 328
Pobierz darmowy fragment (pdf)

Gdzie kupić całą publikację:

CakePHP 1.3. Programowanie aplikacji. Receptury
Autor:

Opinie na temat publikacji:


Inne popularne pozycje z tej kategorii:


Czytaj również:


Prowadzisz stronę lub blog? Wstaw link do fragmentu tej książki i współpracuj z Cyfroteką: