<?php
/**
 * -------------------------------------------------------------------------
 *
 * Модуль для представления, генерирующего данные в виде HTML-разметки.
 *
 * -------------------------------------------------------------------------
 *
 * @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' );

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

    class MyMimimiViewsHtml extends MimimiModule {

        /**
         * -----------------------------------------------------------------
         *
         * Метод: Сгенерировать страницу по макету и отправить в браузер
         *        со статусом "200 OK".
         *
         * -----------------------------------------------------------------
         *
         * Отличается от следующего метода тем, что помимо сгенерированной
         * HTML-разметки шлёт в браузер ещё и HTTP-код состояния, являющийся
         * признаком успешного выполнения запроса.
         *
         * -----------------------------------------------------------------
         *
         * @public
         * @param   string|array  $file  (необязательный) Относительное имя желаемого макетного файла.
         *                                                Указывается относительно шаблона сайта, то есть папки "repost.vacancies/Themes/default"
         *                                                Может быть представлено как:
         *                                                    STRING = Имя файла.
         *                                                    ARRAY  = Имя файла, входные параметры для этого файла.
         * @return  void
         *
         * -----------------------------------------------------------------
         */

        public function run ( $file = '' ) {
            sendHeaderHTML ( 200 );
            $this->page ( $file );
        }

        /**
         * -----------------------------------------------------------------
         *
         * Метод: Сгенерировать страницу по макету и отправить в браузер
         *        с неким статусом ошибки.
         *
         * -----------------------------------------------------------------
         *
         * Этот метод я использовал для генерации контента страницы "Ошибка
         * 404", известную как "Страница не найдена". Метод также шлёт в
         * браузер серверный заголовок, запрещающий кешировать текущую (то
         * есть ошибочную) страницу.
         *
         * -----------------------------------------------------------------
         *
         * @public
         * @param   string|array  $file    (необязательный) Относительное имя желаемого макетного файла.
         *                                                  Указывается относительно шаблона сайта, то есть папки "repost.vacancies/Themes/default"
         *                                                  Может быть представлено как:
         *                                                      STRING = Имя файла.
         *                                                      ARRAY  = Имя файла, входные параметры для этого файла.
         * @param   int           $status  (необязательный) HTTP код состояния.
         * @return  void
         *
         * -----------------------------------------------------------------
         */

        public function error ( $file, $status = 404 ) {
            sendHeaderHTML ( $status );
            sendHeaderExpires ( );
            $this->page ( $file );
        }

        /**
         * -----------------------------------------------------------------
         *
         * Метод: Сгенерировать страницу по макету и отправить в браузер
         *        как некешируемую со статусом "200 OK".
         *
         * -----------------------------------------------------------------
         *
         * Этот метод предназначен для генерации контента административных
         * страниц, когда требуются серверные заголовки, запрещающие кешировать
         * отправленные данные, и HTTP код состояния, являющийся признаком
         * успешного выполнения запроса.
         *
         * -----------------------------------------------------------------
         *
         * @public
         * @param   string|array  $file  Относительное имя желаемого макетного файла.
         *                               Указывается относительно шаблона сайта, то есть папки "repost.vacancies/Themes/default"
         *                               Может быть представлено как:
         *                                   STRING = Имя файла.
         *                                   ARRAY  = Имя файла, входные параметры для этого файла.
         * @return  void
         *
         * -----------------------------------------------------------------
         */

        public function administrative ( $file ) {
            $this->nothing ( );
            $this->page ( $file );
        }

        /**
         * -----------------------------------------------------------------
         *
         * Метод: Сгенерировать страницу по макету и отправить в браузер.
         *
         * -----------------------------------------------------------------
         *
         * Отличается от предыдущих методов тем, что шлёт в браузер только
         * сгенерированную HTML-разметку, полагаясь что HTTP код состояния
         * м прочие серверные заголовки для текущего запроса были отправлены
         * ранее или не требовались вовсе.
         *
         * Напомню, протоколом HTTP определено, что серверные заголовки
         * должны быть отправлены пользователю прежде любого байта самого
         * контента. Поэтому я разделил методы на несколько похожих, но цели
         * разной: run(), error(), administrative(), page().
         *
         * -----------------------------------------------------------------
         *
         * @public
         * @param   string|array  $file  Относительное имя желаемого макетного файла.
         *                               Указывается относительно шаблона сайта, то есть папки "repost.vacancies/Themes/default"
         *                               Может быть представлено как:
         *                                   STRING = Имя файла.
         *                                   ARRAY  = Имя файла, входные параметры для этого файла.
         * @return  void
         *
         * -----------------------------------------------------------------
         */

        public function page ( $file ) {
            mimimiModule ( $file );
        }

        /**
         * -----------------------------------------------------------------
         *
         * Метод: Ответить браузеру пустой страницей со статусом "200 OK".
         *
         * -----------------------------------------------------------------
         *
         * Этот метод используется для случая, когда CRON (то есть серверный
         * менеджер задач по расписанию) или обычный пользователь обратился
         * к странице запуска парсера вакансий. Тогда парсер отрабатывает
         * свои действия, а ответ никому не интересен, то есть как бы должен
         * выполняться в тихом режиме.
         *
         * -----------------------------------------------------------------
         *
         * @public
         * @return  void
         *
         * -----------------------------------------------------------------
         */

        public function nothing ( ) {
            sendHeaderHTML ( 200 );
            sendHeaderExpires ( );
        }

        /**
         * -----------------------------------------------------------------
         *
         * Метод: Ответить браузеру текстовым документом на основе макета.
         *
         * -----------------------------------------------------------------
         *
         * Эта версия приложения генерирует единственный текстовый документ,
         * макет которого располагается в следующем файле:
         *
         *     repost.vacancies/Themes/default/robots.tpl
         *
         * А входной параметр $file сделан лишь для универсальности метода.
         * Мало ли, вдруг при доработке приложения под себя Вам понадобятся
         * другие текстовые документы.
         *
         * -----------------------------------------------------------------
         *
         * @public
         * @param   string  $file  Относительное имя желаемого макетного файла.
         *                         Указывается относительно шаблона сайта, то есть папки "repost.vacancies/Themes/default"
         *                         Может быть представлено как:
         *                             STRING = Имя файла.
         *                             ARRAY  = Имя файла, входные параметры для этого файла.
         * @return  void
         *
         * -----------------------------------------------------------------
         */

        public function text ( $file ) {
            sendHeaderTEXT ( );
            mimimiModule ( $file );
        }

        /**
         * -----------------------------------------------------------------
         *
         * Метод: Ответить браузеру XML документом на основе макета.
         *
         * -----------------------------------------------------------------
         *
         * Эта версия приложения генерирует единственный XML документ, так
         * называемую карту сайта, макет которой располагается в следующем
         * файле:
         *
         *     repost.vacancies/Themes/default/sitemap.tpl
         *
         * А входной параметр $file сделан лишь для универсальности метода.
         *
         * -----------------------------------------------------------------
         *
         * @public
         * @param   string  $file  Относительное имя желаемого макетного файла.
         *                         Указывается относительно шаблона сайта, то есть папки "repost.vacancies/Themes/default"
         *                         Может быть представлено как:
         *                             STRING = Имя файла.
         *                             ARRAY  = Имя файла, входные параметры для этого файла.
         * @return  void
         *
         * -----------------------------------------------------------------
         */

        public function xml ( $file ) {
            sendHeaderXML ( );
            mimimiModule ( $file );
        }
    }

    /**
     * ---------------------------------------------------------------------
     *
     * Создаём несколько процедур, которые станем использовать в макетах
     * шаблона сайта. Эти процедуры представляют собой подобие динамического
     * HTMl-тега, который выведет некую информацию вместо себя. Тег пишется
     * в макете следующим образом:
     *
     *     «?php имяПроцедуры($параметры) ?»
     *
     * Для пимера использованы кавычки "ёлочка" вместо углобых скобок, чтобы
     * избежать сейчас распознавания угловых скобок как блока исходного кода
     * для интерпретатора PHP.
     *
     * ---------------------------------------------------------------------
     */

    // отправить браузеру HTTP статус
    function sendHeaderStatus ( $code ) {
        $protocol = mimimiServer ( 'SERVER_PROTOCOL' );
        switch ( $code ) {
            case 200: $text = '200 OK';        break;
            case 404: $text = '404 Not Found'; break;
            default:  $rexr = $code;
        }
        header ( $protocol . ' ' . $code, TRUE, $code );
    }

    // отправить браузеру заголовок о типе контента
    function sendHeaderHTML ( $status ) {
        sendHeaderStatus ( $status );
        header ( 'Content-Type: text/html; charset=UTF-8' );
    }

        function sendHeaderTEXT ( ) {
            sendHeaderStatus ( 200 );
            header ( 'Content-Type: text/plain; charset=UTF-8' );
        }

        function sendHeaderXML ( ) {
            sendHeaderStatus ( 200 );
            header ( 'Content-Type: text/xml; charset=UTF-8' );
        }

    // отправить браузеру заголовок о некешировании страницы
    function sendHeaderExpires ( ) {
        header ( 'Cache-Control: no-cache, must-revalidate' );
        header ( 'Expires: 0' );
    }

    // вывести значение безопасно (для использования в атрибуте HTML тега)
    function printValue ( $value ) {
        echo htmlspecialchars ( $value, ENT_QUOTES, 'UTF-8' );
    }

    // вывести URL домена безопасно (для использования в атрибуте HTML тега)
    function printDomainUrl ( ) {
        printValue ( mimimiSite ( FALSE ) );
    }

    // вывести URL сайта безопасно (для использования в атрибуте HTML тега)
    function printSiteUrl ( ) {
        printDomainUrl (                      );
        printValue     ( mimimiRoot ( FALSE ) );
    }

    // вывести URL папки приложения безопасно (для использования в атрибуте HTML тега)
    function printAppUrl ( ) {
        printSiteUrl (                   );
        printValue   ( MIMIMI_APP_FOLDER );
    }

    // вывести URL шаблона сайта безопасно (для использования в атрибуте HTML тега)
    function printThemeUrl ( ) {
        printAppUrl (                                    );
        printValue  ( 'Themes/' . MIMIMI_APP_THEME . '/' );
    }

    // вывести URL списка записей
    function printListUrl ( $row ) {
        printSiteUrl (                    );
        printValue   ( $row[ 'url_root' ] );
    }

    // вывести URL этой записи
    function printUrl ( $row, $idColumn = 'item_id' ) {
        printListUrl   ( $row            );
        printUrlDetail ( $row, $idColumn );
    }

        function printUrlDetail ( $row, $idColumn = 'item_id' ) {
            printValue ( '?item=' . ( empty ( $row[ $idColumn ] ) ? $row[ 'id'      ]
                                                                  : $row[ $idColumn ] ) );
        }

    // вывести URL кнопки администратора для этой записи
    function printToolUrl ( $row, $toolname ) {
        printListUrl ( $row            );
        printValue   ( $toolname . '/' );
        if ( $toolname != 'add' ) {
            printUrlDetail ( $row );
        }
    }

    // вывести для Телеграм значение колонки записи
    function printForTelegram ( $label, $row, $column, $margin = "\n" ) {
        if ( ! empty ( $row[ $column ] ) ) {
            $openTag  = '<b>';
            $closeTag = '</b>';
            if ( $label == '' ) {
                $openTag  = '';
                $closeTag = '';
            }
            $value = preg_replace ( '~^(\s*<[a-z][^>]*>)+~ui',  '',     $row[ $column ] );
            $value = preg_replace ( '~(</[a-z][^>]*>\s*)+$~ui', '',     $value          );
            $value = preg_replace ( '~(\s*</?[a-z][^>]*>)+~ui', "\n\n", $value          );
            global $app;
            echo $openTag . $app->views->telegram->escapeForHtml ( $label ) . $closeTag . $margin
                          . $app->views->telegram->escapeForHtml ( $value )             . "\n";
        }
    }

    // проверка что текущий пользователь уже авторизован
    function hasAdmin ( ) {
        global $app;
        return $app->controllers->dashboard->hasAdmin ( );
    }

    // проверка что сайт находится в демо режиме
    function isDemo ( ) {
        global $app;
        return $app->controllers->dashboard->isDemo ( );
    }
