01	Soft - Вступление и подготовка.
	Установить OpenServer, PHPStorm, Git

02	Web - Первый кирпич сайта.
	Запустить консоль
	Создать папку school и web
	Создать файл web/index.php
	Настроить домен OpenServer на school/web
	Проверить работу сайта через браузер

03	Git - Все ходы записываются.
	Создать GIT-репозиторий
	Запустить PHPStorm
	Создать файл .gitignore
	Добавить остальные файлы
	Закоммитить через PHPStorm

04	Composer - Установка пустоты.
	Загрузить composer-asset-plugin
	Загрузить yiisoft/yii2
	Создать файл config/web.php
	Переписать файл web/index.php
	Проверить в браузере - ошибка 404
	Закоммитить

05	Controller - Точка входа программиста.
	Создать файл controllers/SiteController.php
	Создать функцию actionIndex с выводом Welcome
	Проверить и закоммитить

06	Views - Представления начинаются.
	Сделать в контроллере вызов представления
	Включить режим отладки YII_DEBUG
	Проверить в браузере, изучить текст ошибки
	Создать views/site/index.php
	Создать views/layouts/main.php
	Проверить и закоммитить

07	Codeception - Пошаговое тестирование.
	Загрузить codeception/codeception
	Проинициализировать систему тестирования
	Настроить конфиг acceptance.suite.yml
	Сгенерировать TestGuestPages
	Вписать первые тесты
	Запустить тесты
	Закоммитить
	
08	Bootstrap - Пусть будет красиво!
	Загрузить yiisoft/yii2-bootstrap
	Добавить в layout/main.php строчку меню
	Создать папку web/assets с файлом .gitignore
	Решить проблему с папкой bower-asset
	Добавить вызов триггеров в layouts/main.php
	Поместить вывод $content в div с отступом
	Проверить и закоммитить	

09	Menu - Богатый выбор.
	Добавить пункты меню в layouts/main.php
	Скопировать actionIndex() из SiteController
	в два новых метода actionJoin() и actionLogin()
	Проверить и закоммитить	

10	Join/login - Полёт Навигатора.
	Сделать красивую адресную строку
	Создать файл web/.htaccess
	Создать представления views/join.php и login.php
	Сменить виды в action-функциях контроллера
	Проверить и закоммитить	

11	Debug - Следы на песке.
	Загрузить yiisoft/yii2-debug
	Дописать config/web.php
	Добавить .gitignore в runtime/debug
	Проверить и закоммитить	

12	User - Помещение регистратуры.
	Переписать тесты под /user/ ссылки
	Создать controllers/UserController.php
	Перенести методы из контроллера Site в User
	Перенести представления в views/user
	Поменять ссылки в layouts/main.php
	Проверить и закоммитить

13	Panel - Красивые анкеты.
	Добавить дизайн в файлы join.php и login.php
	Зафиксировать на экране список полей в формах
	Проверить и закоммитить

14	Model - Модели на подиуме.
	Нарисовать на бумаге UML-схему по памяти
	Модели: User, UserRecord, UserIdentity
	Формы: UserJoinForm, UserLoginForm

15	Tests - Обоснование необходимости.
	Создать stepobject тест TestUserJoin
	Вписать имена всех нужных методов
	Добавить параметры в нужные методы
	Прописать все вызовы в приёмочном тесте
	Проверить и закоммитить

16	Steps - Пошаговая инструкция.
	Реализовать все методы класса TestUserJoin
	Проверить и закоммитить

17	Console - Есть ли жизнь в Консоли?
	Создать консольный скрипт /yii.php
	Создать config/console.php
	Запустить скрипт с параметром help migrate
	Закоммитить

18	Migration - Архитектура таблицы.
	Сгенерировать файл миграции для создания таблицы user
	Дописать код создания таблицы со всеми полями.
	Закоммитить

19	DBase - Подключение к Матрице.
	Открыть менеджер баз данных HeidiSQL
	Создать базу данных school
	Создать config/db.php
	Подключить базу в config/console.php
	Выполнить миграцию
	Проверить таблицы в базе
	Закоммитить

20	UserRecord - Очень активная модель.
	Создать models\UserRecord.php
	Написать статичную функцию tableName()
	Реализовать метод setTestUser() 
	Написать код для создания записи в actionJoin()
	Подключить базу в config/web.php
	Открыть страницу и проверить базу
	Закоммитить

21	Faker - Тысяча фантазёров!
	Загрузить fzaninotto/faker
	Переписать метод setTestUser()
	Добавить в web/index.php подключение скрипта autoload.php
	Добавить несколько разных пользователей
	Убрать добавление записей из контроллера
	Закоммитить

22	UserIdentity - Посторонним В.
	Создать модель UserIdentity 
	Реализовать методы findIdentity() и getId()
	Добавить в config/web.php запись components/user
	Добавить вызов функции авторизации в actionLogin()
	Проверить и закоммитить

23	Logout - Выход из лабиринта.
	Изменить меню в main\layouts.php
	Добавить в UserController метод actionLogout()
	Протестировать вход/выход
	Закоммитить

24	UserJoinForm - Модель для формы.
	Создать модель UserJoinForm
	Добавить поля ввода в представление join.php
	Передать модель из actionJoin() в join
	Перевести подписи к полям на русский язык
	Проверить и закоммитить

25	Rules - Валидация без правил.
	Написать функцию валидации rules()
	Добавить индивидуальные параметры валидации
	Перевести сообщения об ошибках на русский язык
	Проверить и закоммитить	

26	JoinPost - Вторая сторона модели.
	Cоздать и вызвать метод actionJoinPost()
	Отобразить данные в первой фазе формы Join
	Создать метод setUserRecord() в классе UserJoinForm
	Проверить и закоммитить	

27	IfEmailUsed - Почта закрыта.
	Добавить пользовательскую валидацию email
	Написать метод проверки errorIfEmailUsed()
	Добавить в actionJoinPost() вызов validate()
	Написать код проверки наличия почты в UserRecord
	Проверить и закоммитить

28	HasErrors - Где водятся волшебники?
	Добавить тестовую проверку errorIfMagic
	Поэкспериментироваться с последовательностью проверок
	Проверить и откатить изменения
	Этот урок при повторе можно пропустить

29	Save - Запись в книгу.
	Вписать в actionJoinPost() регистрацию пользователя
	Реализовать метод setUserJoinForm() в модели UserRecord
	Добавить редирект после регистрацию на /user/login
	Пройти регистрацию и проверить базу
	Запустить тест и закоммитить

30	UserLoginForm - Модель на входе.
	Создать модель UserLoginForm
	Добавить метод rules() с проверками
	Подготовить поля формы в views/user/login.php
	Переделать метод actionLogin() в UserController
	Протестировать и закоммитить

31	IfEmailNotFound - На деревню дедушке.
	Добавить правило errorIfEmailNotFound в UserLoginForm
	Создать метод errorIfEmailNotFound()
	Написать статичный метод findUserByEmail() в UserRecord()
	Дописать метод actionLoginPost() в UserController
	Написать метод login() в модели UserLoginForm
	Проверить и закоммитить

32	IfPasswordWrong - Пароль? Пароль! Проходи.
	Добавить правило errorIfPasswordWrong в UserLoginForm
	Создать метод errorIfPasswordWrong()
	Залогиниться разными пользователями
	Посмотреть логи запросов к Базе данных
	Запустить тесты и закоммитить

33	Refactoring - Нет дубликатам!
	Создать приватное поле $userRecord в модели UserLoginForm
	Использовать это поле вместо переменных в трёх методах.
	Добавить проверку на null
	Запустить тесты и закоммитить

34	Test - Запуск функциональных тестов.
	Запустить vendor\bin\codecept generate:test functional PasswordHasher
	Добавить демо-функциональный тест в testSomeFeature()
	Подключить использование Yii2 в файле tests\functional.suite.yml 
	Добавить использование стартового скрипта в codeception.yml
	Создать файлы _bootstrap.php в каждой папке тестов
	Запустить тесты и закоммитить

35	PasswordIsHashed - Покажите-ка ваш хэш.
	Добавить в класс UserRecord новый метод setPassword()
	Использовать этот метод в коде вместо прямого присваивания
	Написать тест testPasswordIsHashed() для проверки хэшируемости пароля
	Написать тест testPasswordIsNotRehashed() /по желанию/
	Запустить тесты и закоммитить

36	Security - Кручу-верчу-захэшировать хочу!
	Очистить таблицу users запросом truncate
	Модифицировать метод UserRecord::setPassword()
	Добавить метод UserRecord::validatePassword()
	Модифицировать метод UserLoginForm::errorIfPasswordWrong()
	Запустить тесты и закоммитить

37	Hash - Как правильно солить пароли.
	Зарегистрироваться с разными значениями $cost: 14, 15, 16.
	Выполнить профилирование функции хэширования пароля
	Просмотреть в логах время выполнения запросов
	Откатить изменения
	Этот урок при повторе можно пропустить

38	Remember me - Печенька на память.
 	Добавить поле $remember в модель UserLoginForm
 	Добавить ['remember', 'boolean'] в метод rules()
 	Добавить checkbox «remember» на форму входа
 	Реализовать методы getAuthKey() и validateAuthKey()
 	Добавить параметр 'enableAutoLogin' в config/web.php
 	Добавить время хранения в UserLoginForm->login()
 	Залогиниться, закрыть/открыть браузер и проверить куки
 	Закоммитить изменения

39	Authokey - Ключи в сейфе.
	Создать миграцию с добавлением уникального столбца authokey
	Проверить наличие нового столбца в таблице user
	Добавить генерацию рандомного authokey в UserRecord->setPassword()
	Заменить email на authokey в UserIdentity->getAuthKey()
	Проверить регистрацию и сохранение автовхода в кукисах
	Закоммитить изменения