# Aktualizacja z wersji 1.1 ¶

Pomiędzy wersjami 1.1 i 2.0 Yii jest ogrom różnic, ponieważ framework został całkowicie przepisany w 2.0. Z tego też powodu aktualizacja z wersji 1.1 nie jest tak trywialnym procesem, jak w przypadku aktualizacji pomiędzy pomniejszymi wersjami. W tym przewodniku zapoznasz się z największymi różnicami dwóch głównych wersji.

Jeśli nie korzystałeś wcześniej z Yii 1.1, możesz pominąć tę sekcję i przejść bezpośrednio do "Pierwszych kroków".

Zwróć uwagę na to, że Yii 2.0 wprowadza znacznie więcej nowych funkcjonalności, niż wymienionych jest w tym podsumowaniu. Wskazane jest zapoznanie się z treścią całego przewodnika, aby poznać je wszystkie. Jest bardzo prawdopodobne, że niektóre z mechanizmów, które poprzednio musiałeś stworzyć samemu, teraz są częścią podstawowego kodu.

## Instalacja ¶

Yii 2.0 w pełni korzysta z udogodnień Composera, będącego de facto menadżerem projektów PHP. Z jego pomocą odbywa się zarówno instalacja podstawowego frameworka, jak i wszystkich rozszerzeń. Aby zapoznać się ze szczegółową instrukcją instalacji Yii 2.0, przejdź do sekcji Instalacja Yii. Jeśli chcesz stworzyć nowe rozszerzenie lub zmodyfikować istniejące w wersji 1.1, aby było kompatybilne z 2.0, przejdź do sekcji Tworzenie rozszerzeń.

## Wymagania PHP ¶

Yii 2.0 wymaga PHP w wersji 5.4 lub nowszej, która została znacząco ulepszona w stosunku do wersji 5.2 (wymaganej przez Yii 1.1). Z tego też powodu już na poziomie samego języka pojawiło się sporo różnic, na które należy zwrócić uwagę. Poniżej znajdziesz krótkie podsumowanie głównych różnic dotyczących PHP:

- Przestrzenie nazw.
- Funkcje anonimowe.
- Skrócona składnia zapisu tablic `[...elementy...]` używana zamiast `array(...elementy...)`.
- Krótkie tagi echo `<?=` używane w plikach widoków. Można ich używać bezpiecznie, począwszy od PHP 5.4.
- Klasy i interfejsy SPL.
- Opóźnione statyczne wiązania.
- Data i czas.
- Traity.
- Rozszerzenie intl. Yii 2.0 korzysta z rozszerzenia PHP `intl` do wsparcia obsługi internacjonalizacji.

## Przestrzeń nazw ¶

Najbardziej oczywista zmiana w Yii 2.0 dotyczy używania przestrzeni nazw. Praktycznie każda z podstawowych klas je wykorzystuje, np. `yii\web\Request`. Prefiks "C" nie jest już używany w nazwach, a sam schemat nazewnictwa odpowiada teraz strukturze folderów - dla przykładu `yii\web\Request` wskazuje, że plik klasy to `web/Request.php` znajdujący się w folderze frameworka Yii.

Dzięki mechanizmowi ładowania klas Yii możesz użyć dowolnej podstawowej klasy frameworka bez konieczności bezpośredniego dołączania jej kodu.

## Komponent i obiekt ¶

Yii 2.0 rozdzielił klasę `CComponent` z 1.1 na dwie: BaseObject i Component. Lekka klasa BaseObject pozwala na zdefiniowanie właściwości obiektu poprzez gettery i settery. Klasa Component dziedziczy po BaseObject i dodatkowo wspiera obsługę zdarzeń oraz zachowań.

Jeśli Twoja klasa nie wymaga ww. wsparcia, rozważ użycie BaseObject jako klasy podstawowej. Tak jest zazwyczaj w przypadku klas reprezentujących najbardziej podstawową strukturę danych.

## Konfiguracja obiektu ¶

Klasa BaseObject wprowadza ujednoliconą formę konfigurowania obiektów. Każda klasa dziedzicząca po BaseObject powinna zadeklarować swój konstruktor (jeśli tego wymaga) w następujący sposób, dzięki czemu zostanie poprawnie skonfigurowana:

    class MyClass extends \yii\base\BaseObject
    {
        public function __construct($param1, $param2, $config = [])
        {
            // ... inicjalizacja przed skonfigurowaniem

            parent::__construct($config);
        }

        public function init()
        {
            parent::init();

            // ... inicjalizacja po skonfigurowaniu
        }
    }

W powyższym przykładzie ostatnim parametrem konstruktora musi być tablica konfiguracyjna, zawierająca pary nazwa-wartość służące do zainicjowania właściwości na końcu konstruktora. Możesz nadpisać metodę init(), aby wykonać dodatkowy proces inicjalizacyjny po zaaplikowaniu konfiguracji.

Dzięki tej konwencji możesz tworzyć i konfigurować nowe obiekty, używając tablicy konfiguracyjnej:

    $object = Yii::createObject([
        'class' => 'MyClass',
        'property1' => 'abc',
        'property2' => 'cde',
    ], [$param1, $param2]);

Więcej szczegółów na temat konfiguracji znajdziesz w sekcji Konfiguracje.

## Zdarzenia (Events) ¶

W Yii 1 zdarzenia były tworzone poprzez definiowanie `on`-metody (np., `onBeforeSave`). W Yii 2 możesz użyć dowolnej nazwy. Uruchomienie zdarzenia następuje poprzez wywołanie metody trigger():

    $event = new \yii\base\Event;
    $component->trigger($eventName, $event);

Aby dołączyć uchwyt do zdarzenia, użyj metody on():

    $component->on($eventName, $handler);
    // a aby odłączyć uchwyt użyj:
    // $component->off($eventName, $handler);

Zdarzenia zostały wzbogacone w wiele udoskonaleń. Więcej szczegółów na ten temat znajdziesz w sekcji Zdarzenia (Events).

## Aliasy ścieżek ¶

Yii 2.0 rozszerza funkcjonalność aliasów ścieżek zarówno na ścieżki plików oraz folderów, jak i adresy URL. Yii 2.0 wymaga teraz też, aby nazwa aliasu zaczynała się znakiem `@` w celu odróżnienia jej od zwyczajnych ścieżek plików/folderów lub URLi. Dla przykładu: alias `@yii` odnosi się do folderu instalacji Yii. Aliasy ścieżek są wykorzystywane w większości miejsc w podstawowym kodzie Yii, choćby cachePath - można tu przekazać zarówno zwykłą ścieżkę, jak i alias.

Alias ścieżki jest mocno powiązany z przestrzenią nazw klasy. Zalecane jest, aby zdefiniować alias dla każdej podstawowej przestrzeni nazw, dzięki czemu mechanizm automatycznego ładowania klas Yii nie będzie wymagał dodatkowej konfiguracji. Dla przykładu: dzięki temu, że `@yii` odwołuje się do folderu instalacji Yii, klasa taka jak `yii\web\Request` może być automatycznie załadowana. Jeśli używasz zewnętrznych bibliotek, jak np. Zend Framework, możesz zdefiniować alias `@Zend` odnoszący się do folderu instalacji tego frameworka. Od tej pory Yii będzie również w stanie automatycznie załadować każdą klasę z tej biblioteki.

Więcej o aliasach ścieżek dostępne jest w sekcji Aliasy.

## Widoki ¶

Najbardziej znaczącą zmianą dotyczącą widoków w Yii 2 jest użycie specjalnej zmiennej `$this`. W widoku nie odnosi się ona już do aktualnego kontrolera lub widżetu, lecz do obiektu widoku, nowej koncepcji przedstawionej w 2.0. Obiekt widoku jest klasą typu View, która reprezentuje część wzorca MVC. Jeśli potrzebujesz odwołać się do kontrolera lub widżetu w widoku, możesz użyć `$this->context`.

Aby zrenderować częściowy widok wewnątrz innego widoku, możesz użyć `$this->render()` zamiast dotychczasowego `$this->renderPartial()`. Wywołanie `render` musi teraz też być bezpośrednio wyechowane, ponieważ metoda `render()` zwraca rezultat renderowania zamiast od razu go wyświetlać.

    echo $this->render('_item', ['item' => $item]);

Oprócz wykorzystania PHP jako podstawowego języka szablonów, Yii 2.0 oficjalnie wspiera dwa popularne silniki szablonów: Smarty i Twig (The Prado nie jest już wspierany). Aby użyć któregokolwiek z tych silników, musisz skonfigurować komponent aplikacji `view` poprzez ustawienie właściwości $renderers. Po więcej szczegółów przejdź do sekcji Silniki szablonów.

## Modele ¶

Yii 2.0 korzysta z Model jako bazowego modelu, podobnie jak `CModel` w 1.1. Klasa `CFormModel` została całkowicie usunięta, w Yii 2 należy rozszerzyć Model, aby stworzyć klasę modelu formularza.

Yii 2.0 wprowadza nową metodę scenarios(), służącą do deklarowania scenariuszy, jak i do oznaczania, w którym scenariuszu atrybut będzie wymagał walidacji, może być uznany za bezpieczny lub nie itp. Dla przykładu:

    public function scenarios()
    {
        return [
            'backend' => ['email', 'role'],
            'frontend' => ['email', '!role'],
        ];
    }

Widzimy tutaj dwa zadeklarowane scenariusze: `backend` i `frontend`. W scenariuszu `backend` obydwa atrybuty, `email` i `role`, są traktowane jako bezpieczne i mogą być przypisane zbiorczo. W przypadku scenariusza `frontend`, `email` może być przypisany zbiorczo, ale `role` już nie. Zarówno `email` jak i `role` powinny przejść proces walidacji.

Metoda rules() wciąż służy do zadeklarowania zasad walidacji. Zauważ, że z powodu wprowadzenia scenarios(), nie ma już walidatora `unsafe`.

Jeśli metoda rules() deklaruje użycie wszystkich możliwych scenariuszy i jeśli nie masz potrzeby deklarowania atrybutów `unsafe` (niebezpiecznych), w większości przypadków nie potrzebujesz nadpisywać metody scenarios().

Aby dowiedzieć się więcej o modelach, przejdź do sekcji Modele.

## Kontrolery ¶

Yii 2.0 używa Controller jako bazowej klasy kontrolera, podobnie do `CController` w Yii 1.1. Action jest bazową klasą dla akcji.

Najbardziej oczywistą implikacją tych zmian jest to, że akcja kontrolera powinna zwracać zawartość, którą chcesz wyświetlić, zamiast wyświetlać ją bezpośrednio:

    public function actionView($id)
    {
        $model = \app\models\Post::findOne($id);
        if ($model) {
            return $this->render('view', ['model' => $model]);
        } else {
            throw new \yii\web\NotFoundHttpException;
        }
    }

Przejdź do sekcji Kontrolery, aby poznać więcej szczegółów na ten temat.

## Widżety ¶

Yii 2.0 korzysta z Widget jako bazowej klasy widżetów, podobnie jak `CWidget` w Yii 1.1.

Dla lepszego wsparcia frameworka w aplikacjach IDE Yii 2.0 wprowadził nową składnię używania widżetów. Używane są teraz metody begin(), end() i widget() w następujący sposób:

    use yii\widgets\Menu;
    use yii\widgets\ActiveForm;

    // Zwróć uwagę na konieczność użycia "echo", aby wyświetlić rezultat
    echo Menu::widget(['items' => $items]);

    // Przekazujemy tablicę, aby zainicjalizować właściwości obiektu
    $form = ActiveForm::begin([
        'options' => ['class' => 'form-horizontal'],
        'fieldConfig' => ['inputOptions' => ['class' => 'input-xlarge']],
    ]);
    ... pola formularza w tym miejscu ...
    ActiveForm::end();

Więcej szczegółów na ten temat znajdziesz w sekcji Widżety.

## Skórki i motywy (Theming) ¶

Skórki działają zupełnie inaczej w 2.0. Oparte są teraz na mechanizmie mapowania ścieżki, który przekształca źródłowy plik widoku w plik widoku skórki. Dla przykładu, jeśli mapa ścieżki dla skórki to `['/web/views' => '/web/themes/basic']`, to skórkowa wersja pliku widoku `/web/views/site/index.php` to `/web/themes/basic/site/index.php`. Dzięki temu skórki mogą być użyte dla dowolnego pliku widoku, nawet w przypadku widoku wyrenderowanego poza kontekstem kontrolera lub widżetu.

Nie ma również już komponentu `CThemeManager`. Zamiast tego `theme` jest konfigurowalną właściwością komponentu aplikacji `view`.

Sekcja Skórki i motywy (Theming) zawiera więcej szczegółów na ten temat.

## Aplikacje konsolowe ¶

Aplikacje konsolowe używają teraz kontrolerów tak jak aplikacje webowe. Kontrolery konsolowe powinny rozszerzać klasę yii\console\Controller, podobnie jak `CConsoleCommand` w 1.1.

Aby uruchomić polecenie konsoli, użyj `yii <route>`, gdzie `<route>` oznacza ścieżkę kontrolera (np. `sitemap/index`). Dodatkowe anonimowe argumenty są przekazywane jako parametry do odpowiedniej metody akcji kontrolera, natomiast nazwane argumenty są przetwarzane według deklaracji zawartych w options().

Yii 2.0 wspiera automatyczne generowanie informacji pomocy poprzez bloki komentarzy.

Aby dowiedzieć się więcej na ten temat, przejdź do sekcji Komendy konsolowe.

## I18N ¶

Yii 2.0 usunął wbudowany formater dat i liczb na rzecz modułu PECL intl PHP.

Tłumaczenia wiadomości odbywają się teraz poprzez komponent aplikacji `i18n`, w którym można ustalić zestaw źródeł treści, dzięki czemu możliwy jest ich wybór dla różnych kategorii wiadomości.

W sekcji Internacjonalizacja znajdziesz więcej szczegółów na ten temat.

## Filtry akcji ¶

Filtry akcji są implementowane od teraz za pomocą zachowań (behavior). Aby zdefiniować nowy filtr, należy rozszerzyć klasę ActionFilter. Użycie filtru odbywa się poprzez dołączenie go do kontrolera jako zachowanie. Dla przykładu: aby użyć filtra yii\filters\AccessControl, dodaj poniższy kod w kontrolerze:

    public function behaviors()
    {
        return [
            'access' => [
                'class' => 'yii\filters\AccessControl',
                'rules' => [
                    ['allow' => true, 'actions' => ['admin'], 'roles' => ['@']],
                ],
            ],
        ];
    }

Więcej informacji na ten temat znajdziesz w sekcji Filtry.

## Zasoby (Assets) ¶

Yii 2.0 wprowadza nowy mechanizm tzw. pakietów zasobów, który zastąpił koncepcję pakietów skryptowych z Yii 1.1.

Pakiet zasobów jest kolekcją plików zasobów (np. plików JavaScript, CSS, obrazków, itd.) zgromadzoną w folderze. Każdy pakiet jest reprezentowany przez klasę rozszerzającą AssetBundle. Zarejestrowanie pakietu poprzez metodę register() pozwala na udostępnienie go publicznie. W przeciwieństwie do rozwiązania z Yii 1, strona rejestrująca pakiet będzie automatycznie zawierać referencje do plików JavaScript i CSS wymienionych na jego liście.

Sekcja Zasoby (Assets) zawiera szczegółowe informacje na ten temat.

## Klasy pomocnicze ¶

Yii 2.0 zawiera wiele powszechnie używanych statycznych klas pomocniczych (helperów), takich jak:

- Html
- ArrayHelper
- StringHelper
- FileHelper
- Json

W sekcji Klasy pomocnicze znajdziesz więcej informacji na ten temat.

## Formularze ¶

Yii 2.0 wprowadza koncepcję pola do budowy formularzy, korzystając z klasy ActiveForm. Pole jest kontenerem składającym się z etykiety, pola wprowadzenia danych formularza, informacji o błędzie i/lub tekstu podpowiedzi, reprezentowanym przez obiekt klasy ActiveField. Używając pól, możesz stworzyć formularz w sposób o wiele prostszy i bardziej przejrzysty niż do tej pory:

    <?php $form = yii\widgets\ActiveForm::begin(); ?>
        <?= $form->field($model, 'username') ?>
        <?= $form->field($model, 'password')->passwordInput() ?>
        <div class="form-group">
            <?= Html::submitButton('Login') ?>
        </div>
    <?php yii\widgets\ActiveForm::end(); ?>

Aby dowiedzieć się więcej na ten temat, przejdź do sekcji Tworzenie formularzy.

## Konstruktor kwerend ¶

W 1.1 budowanie kwerend było rozrzucone pomiędzy kilka klas, tj. `CDbCommand`, `CDbCriteria` i `CDbCommandBuilder`. Yii 2.0 reprezentuje kwerendę bazodanową w postaci obiektu Query, który może być zamieniony w komendę SQL za pomocą QueryBuilder. Przykładowo:

    $query = new \yii\db\Query();
    $query->select('id, name')
          ->from('user')
          ->limit(10);

    $command = $query->createCommand();
    $sql = $command->sql;
    $rows = $command->queryAll();

Co najlepsze, taki sposób tworzenia kwerend może być również wykorzystany przy pracy z Active Record.

Po więcej szczegółów udaj się do sekcji Konstruktor kwerend.

## Active Record ¶

Yii 2.0 wprowadza sporo zmian w mechanizmie Active Record. Dwie najbardziej znaczące to konstruowanie kwerend i obsługa relacji.

Klasa `CDbCriteria` z 1.1 została zastąpiona przez ActiveQuery w Yii 2. Klasa ta rozszerza Query, dzięki czemu dziedziczy wszystkie metody konstruowania kwerend. Aby rozpocząć budowanie kwerendy, wywołaj metodę find():

    // Pobranie wszystkich *aktywnych* klientów i posortowanie po ich ID:
    $customers = Customer::find()
        ->where(['status' => $active])
        ->orderBy('id')
        ->all();

Deklaracja relacji polega na prostym zdefiniowaniu metody gettera, który zwróci obiekt ActiveQuery. Nazwa właściwości określonej przez tego gettera reprezentuje nazwę stworzonej relacji. Dla przykładu: w poniższym kodzie deklarujemy relację `orders` (w 1.1 konieczne było zadeklarowanie relacji wewnątrz wydzielonej specjalnie metody `relations()`):

    class Customer extends \yii\db\ActiveRecord
    {
        public function getOrders()
        {
            return $this->hasMany('Order', ['customer_id' => 'id']);
        }
    }

Od tej pory można posługiwać się `$customer->orders`, aby uzyskać dostęp do tabeli zamówień klientów poprzez relację. Dodatkowo można również posłużyć się następującym kodem, aby wywołać relacyjną kwerendę dla zadanych warunków:

    $orders = $customer->getOrders()->andWhere('status=1')->all();

Przy "gorliwym" pobieraniu relacji ("eager", w przyciwieństwie do leniwego pobierania "lazy") Yii 2.0 działa inaczej niż w wersji 1.1. W 1.1 tworzono kwerendę JOIN, aby pobrać zarówno główne, jak i relacyjne rekordy. W Yii 2.0 wywoływane są dwie komendy SQL bez użycia JOIN - pierwsza pobiera główne rekordy, a druga relacyjne, filtrując je przy użyciu kluczy głównych rekordów.

Aby zmniejszyć zużycie CPU i pamięci, zamiast zwracać obiekty ActiveRecord, do kwerendy pobierającej dużą ilość rekordów możesz podpiąć metodę asArray(), dzięki czemu zostaną one pobrane jako tablice. Przykładowo:

    $customers = Customer::find()->asArray()->all();

Inną istotną zmianą jest to, że nie można już definiować domyślnych wartości atrybutów poprzez publiczne właściwości. Jeśli potrzebujesz takich definicji, powinieneś przypisać je wewnątrz metody `init` w klasie rekordu.

    public function init()
    {
        parent::init();
        $this->status = self::STATUS_NEW;
    }

Nadpisywanie konstruktora klasy ActiveRecord w 1.1 wiązało się z pewnymi problemami, co nie występuje już w wersji 2.0. Zwróć jednak uwagę na to, że przy dodawaniu parametrów do konstruktora możesz potrzebować nadpisać metodę instantiate().

W nowym rekordzie aktywnym znajdziesz wiele innych zmian i udogodnień. Aby zapoznać się z nimi, przejdź do sekcji Rekord aktywny.

## Zachowania Active Record ¶

W 2.0 zrezygnowaliśmy z bazowej klasy zachowania `CActiveRecordBehavior`. Jeśli chcesz stworzyć zachowanie dla rekordu aktywnego, musisz rozszerzyć bezpośrednio klasę Behavior. Jeśli klasa zachowania ma reagować na zdarzenia, powinna nadpisywać metodę events(), jak zaprezentowano poniżej:

    namespace app\components;

    use yii\db\ActiveRecord;
    use yii\base\Behavior;

    class MyBehavior extends Behavior
    {
        // ...

        public function events()
        {
            return [
                ActiveRecord::EVENT_BEFORE_VALIDATE => 'beforeValidate',
            ];
        }

        public function beforeValidate($event)
        {
            // ...
        }
    }

## Klasa User i IdentityInterface ¶

Klasa `CWebUser` z 1.1 została zastąpiona przez User i nie ma już klasy `CUserIdentity`. Zamiast tego należy zaimplementować interfejs IdentityInterface, który jest znacznie bardziej wygodny i oczywisty w użyciu. Szablon zaawansowanego projektu zawiera przykład takiego właśnie użycia.

Po więcej szczegółów zajrzyj do sekcji Uwierzytelnianie, Autoryzacja i Szablon zaawansowanego projektu.

## Zarządzanie adresami URL ¶

Zarządzanie adresami URL w Yii 2 jest bardzo podobne do tego znanego z 1.1. Głównym ulepszeniem tego mechanizmu jest teraz wsparcie dla parametrów opcjonalnych. Dla przykładu: warunek dla adresu zadeklarowany poniżej obejmie zarówno `post/popular` jak i `post/1/popular`. W 1.1 konieczne byłoby napisanie dwóch warunków, aby osiągnąć to samo.

    [
        'pattern' => 'post/<page:\d+>/<tag>',
        'route' => 'post/index',
        'defaults' => ['page' => 1],
    ]

Przejdź do sekcji Zarządzania adresami URL po więcej informacji.

Istotną zmianą konwencji nazw dla adresów jest to, że nazwy kontrolerów i akcji typu "camel case" są teraz konwertowane do małych liter, z każdym słowem oddzielonym za pomocą myślnika, np. ID kontrolera `CamelCaseController` zostanie przekształcone w `camel-case`.

Zapoznaj się z sekcją dotyczącą ID kontrolerów i ID akcji.

## Korzystanie z Yii 1.1 i 2.x jednocześnie ¶

Jeśli chciałbyś skorzystać z kodu napisanego dla Yii 1.1 w aplikacji Yii 2.0, prosimy o zapoznanie się z sekcją Używanie Yii 1.1 i 2.0 razem.