<?php
/**
 * -------------------------------------------------------------------------
 *
 * Модуль субконтроллера Login.
 *
 * -------------------------------------------------------------------------
 *
 * @package    MimimiFramework
 * @subpackage Examples / Repost Vacancies
 * @license    GPL-2.0
 *             https://opensource.org/license/gpl-2-0/
 * @copyright  2022 MiMiMi Community
 *             https://mimimi.software/
 *
 * -------------------------------------------------------------------------
 */

    /**
     * ---------------------------------------------------------------------
     *
     * Подключаем из папки ядра фреймворка файл "mimimi.core/Module.php".
     * Там объявлен класс "MimimiModule", являющийся простейшей модульной
     * заготовкой. Этот класс подходит как основа для реализуемого ниже
     * модуля.
     *
     * ---------------------------------------------------------------------
     */

    mimimiInclude ( 'Module.php' );

    /**
     * ---------------------------------------------------------------------
     *
     * Создаём на основе класса той заготовки новый класс, в котором напишем
     * программный код текущего модуля. Обратите внимание как задано имя
     * нового класса - оно сложено из имени класса вышестоящего модуля, то
     * есть "MyMimimiControllersDashboard", и имени текущего PHP-файла без
     * расширения.
     *
     * ---------------------------------------------------------------------
     */

    class MyMimimiControllersDashboardLogin extends MimimiModule {

        /**
         * -----------------------------------------------------------------
         *
         * Метод: Маршрутизировать запрос к сопоставленному макету шаблона.
         *
         * -----------------------------------------------------------------
         *
         * Этот метод обслуживает следующие URL-ы:
         *
         *     https://ваш.сайт/login
         *     https://ваш.сайт/logout
         *     https://ваш.сайт/password/change
         *
         * Генерация HTML-кода страницы пройдёт на основе одного из таких
         * макетов:
         *
         *     repost.vacancies/Themes/default/dashboard/login.tpl
         *     repost.vacancies/Themes/default/dashboard/logout.tpl
         *     repost.vacancies/Themes/default/dashboard/password-change.tpl
         *
         * -----------------------------------------------------------------
         *
         * @public
         * @param   string  $url  (необязательный) Относительный URL запрошенной страницы.
         * @return  void
         *
         * -----------------------------------------------------------------
         */

        public function run ( $url = '' ) {
            $me = $this->owner;
            switch ( $url ) {
                // когда страница "Вход на сайт"
                case 'login':
                     $error = $me->hasForm ( ) ? $this->onLogin ( )
                                               : $this->getDemoNote ( );
                     $data  = [ 'error'       => $error   ,
                                'input_name'  => 'secret' ,
                                'button_name' => 'form'   ];
                     $me->render ( 'dashboard/login.tpl', $data );
                     return;
                // когда страница "Выход с сайта"
                case 'logout':
                     if ( $me->hasAdmin ( ) ) {
                         if ( $me->hasAgreed ( ) ) {
                             $this->onLogout ( );
                         } else {
                             $error = $me->hasForm ( ) ? 'Ошибка: Вы не выполнили обязательное действие с флажком ниже!'
                                                       : '';
                             $data  = [ 'error'       => $error ,
                                        'button_name' => 'form' ];
                             $me->render ( 'dashboard/logout.tpl', $data );
                         }
                         return;
                     }
                     break;
                // когда страница "Сменить пароль"
                case 'password/change':
                     if ( $me->hasAdmin ( ) ) {
                         $success = '';
                         $error   = $me->hasForm ( ) ? $this->onChange ( $success )
                                                     : '';
                         $data    = [ 'success'     => $success ,
                                      'error'       => $error   ,
                                      'input_name'  => 'secret' ,
                                      'button_name' => 'form'   ];
                         $me->render ( 'dashboard/password-change.tpl', $data );
                         return;
                     }
                     break;
            }
            // в противном случае перебрасываем пользователя на главную
            $me->gotoHome ( );
        }

        /**
         * -----------------------------------------------------------------
         *
         * Метод: Получить сообщение о демо режиме.
         *
         * -----------------------------------------------------------------
         */

        protected function getDemoNote ( ) {
            return $this->owner->isDemo ( ) ? 'Вы сейчас в демо режиме. Его пароль по умолчанию: demo'
                                            : '';
        }

        /**
         * -----------------------------------------------------------------
         *
         * Метод: Проверить что введённый пароль правильный.
         *
         * -----------------------------------------------------------------
         */

        protected function validatePassword ( ) {
            $pass   = md5 ( mimimiPost ( 'secret' ) );
            $params = [ 'password_hash'   ,
                        'supervisor_hash' ];
            $count  = count ( $params );
            foreach ( $params as $param ) {
                $count--;
                $hash = $this->app->models->settings->get ( $param );
                if ( $hash != '' ) {
                    if ( $hash == $pass ) {
                        return '';
                    } else if ( $count == 0 ) {
                        return 'Ошибка: Пароль неверный!';
                    }
                }
            }
            return 'Ошибка: В базе данных нет записей о паролях администратора и супервизора!';
        }

        /**
         * -----------------------------------------------------------------
         *
         * Метод: Обработчик формы входа в аккаунт.
         *
         * -----------------------------------------------------------------
         *
         * В случае успешной авторизации администратор будет принудительно
         * перенаправлен на главную страницу сайта. В противном случае он
         * останется на той же форме ввода, в которую будет возвращён текст
         * сообщения об ошибке.
         *
         * -----------------------------------------------------------------
         */

        protected function onLogin ( ) {
            $this->app->session->remove ( 'user_marker' );
            $result = $this->validatePassword ( );
            if ( $result == '' ) {
                $pass = mimimiPost ( 'secret' );
                $this->app->session->set ( 'user_marker', md5 ( $pass ) );
                $this->owner->gotoHome ( );
            }
            return $result;
        }

        /**
         * -----------------------------------------------------------------
         *
         * Метод: Обработчик формы выхода из аккаунта.
         *
         * -----------------------------------------------------------------
         *
         * В конце обработки администратор будет принудительно перенаправлен
         * на главную страницу сайта.
         *
         * -----------------------------------------------------------------
         */

        protected function onLogout ( ) {
            $this->app->session->remove ( 'user_marker' );
            $this->owner->gotoHome ( );
        }

        /**
         * -----------------------------------------------------------------
         *
         * Метод: Обработчик формы смены пароля.
         *
         * -----------------------------------------------------------------
         *
         * В случае успешного изменения администратор будет принудительно
         * перенаправлен на главную страницу сайта. В противном случае он
         * останется на той же форме ввода, в которую будет возвращён текст
         * сообщения об ошибке или демо успехе.
         *
         * -----------------------------------------------------------------
         */

        protected function onChange ( & $success ) {
            $result = $this->validatePassword ( );
            if ( $result == '' ) {
                $new = mimimiPost ( 'secret_new' );
                $check = mimimiPost ( 'secret_check' );
                if ( $new == $check ) {
                    if ( $new != '' ) {
                        $pass = mimimiPost ( 'secret' );
                        if ( $new != $pass ) {
                            if ( ! $this->owner->isDemo ( ) ) {
                                $param = $this->owner->hasSupervisor ( ) ? 'supervisor_hash'
                                                                         : 'password_hash';
                                $this->app->session->remove ( 'user_marker' );
                                $this->app->models->settings->set ( $param, md5 ( $new ) );
                                $this->owner->gotoHome ( );
                            }
                            $success = 'Ок! Но так как Вы сейчас в демо режиме, сайт игнорирует сохранение любых изменений. Чтобы увидеть, как это работает в действительности, скачайте приложение и запустите у себя на сайте, отключив демо режим.';
                            return '';
                        }
                        return 'Ошибка: Новый пароль должен отличаться от прежнего!';
                    }
                    return 'Ошибка: Вы не ввели новый пароль!';
                }
                return 'Ошибка: Новый пароль и его повтор должны совпадать!';
            }
            return $result;
        }
    }
