Начать новую тему Ответить на тему
АвторСообщение

 Сообщение Конвертируем мод в расширение phpBB 3.1 / Ascraeus 
#1 

Аватар пользователя

Всем доброго времени суток :-00):
Итак, поняв и разобравшись с вопросом , мы приступаем к освоению новой, более сложной задачи, а именно Как сконвертировать модификацию phpBB 3.0 в расширение phpBB 3.1 :co_ol:

Разбираться с этим мы будем на примере модификации NV Newspage от отличного разработчика nickvergessen.

План действий

  1. Структура расширения
    1. Расположение
    2. Создание новых файлов (composer.json, ext.php)
    3. Встроенные классы и переменные
    4. Модуль в администраторском разделе
  2. Изменения в Базе Данных, замена UMIL на Миграции (Migrations)
    1. Изменения в Схеме (Schema)
    2. Изменения в Данных
    3. Зависимости и окончание миграции
  3. Подключение к расширению языковых файлов
  4. Использование Событий и Слушателей (Events and Listeners)
    1. php события
    2. События шаблонов
    3. Добавление событий
  5. Совместимость
    1. Пагинация (Pagination)


Начинаем по порядку ....

  • 1. Структура расширения
    Очевидное различие между модификациями phpBB 3.0 и расширениями phpBB 3.1 - это папка, в которой хранятся файлы. В phpBB 3.0 файлы модификаций раскидываются по всем папкам форума, а в phpBB 3.1 все файлы расширений хранятся в папке ext/. А это как минимум безпроблемное удаление ненужных расширений

    • 1.1. Расположение
      Хоть и для всех расширений существует единая папка, каждое расширение должно находиться в отдельной папке внутри этой папки (извиняюсь за каламбур ). Папка расширения включает имя автора, в этой папке уже папка с именем расширения. На нашем примере модификации NV Newspage от nickvergessen расположение будет таким
      корень форума/ext/nickvergessen/newspage/
       

      На том же примере, сравним расположение файлов по папкам
       Расположение файлов в расширении   | Расположение файлов в модификации
                  ------------------------+----------------
          .../newspage/                   |
                  acp/                    | корень форума/includes/acp/
                                          | корень форума/includes/acp/info/
                  adm/style/              | корень форума/adm/style/
                  config/                 |   ---
                  controller/             |   ---
                  event/                  |   ---
                  language/               | корень форума/language/
                  migrations/             |   ---
                  styles/                 | корень форума/styles/
       

      В расширении все выгодно и компактно. Добавление новых файлов (которых нет в модификациях) будет описано ниже.
    • 1.2. Создание новых файлов (composer.json, ext.php)
      При конвертации модификации в расширение необходимо создать файл composer.json, нужно это для того, чтобы система увидела (распознала) расширение. Содержание этого файла для нашего примера будет следующим
      {
         "name": "nickvergessen/newspage",
         "type": "phpbb-extension",
         "description": "Adds a extra-page to the board where a switchable number of news are displayed. The text can be shorten to a certain number of chars. Also the Icons can be switched of (post icons, user icons)",
         "homepage": "https://github.com/nickvergessen/phpbb-ext-newspage",
         "version": "1.1.0",
         "time": "2013-03-16",
         "licence": "GPL-2.0",
         "authors": [
            {
               "name": "Joas Schilling",
               "email": "nickvergessen@gmx.de",
               "homepage": "https://github.com/nickvergessen",
               "role": "Lead Developer"
            }
         ],
         "require": {
            "php": ">=5.3"
         },
         "extra": {
            "display-name": "phpBB 3.1 NV Newspage Extension",
            "soft-require": {
               "phpbb/phpbb": "3.1.*@dev"
            }
         }
      }
       

      Следующим новым файлом будет ext.php, позволяющий системе включать\выключать расширение, его содержание
      <?php

      // this file is not really needed, when empty it can be ommitted
      // however you can override the default methods and add custom
      // installation logic

      namespace nickvergessen\newspage;

      class ext extends \phpbb\extension\base
      {
      }
       
    • 1.3. Встроенные классы и переменные
      В то время как на phpBB 3.0 при обращении к модификации (на пользовательском уровне) вы переходили только по адресу адрес форума/newspage.php, в phpBB 3.1 есть больше свободы, по стандарту обращение идет по адресу адрес форума/app.php/newspage, но после небольшой правочки в корневом .htaccess адрес будет таким - адрес форума/newspage/

      Для правильного формирования внутренних ссылок в расширении необходимо прописать так называемые Правила в файле config/routing.yml. Для нашего сконвертированного расширения хватит 2-х правил: первое правило устанавливает основной страницей /newspage.php и требует от остальных вида newspage.php?start=N, где N - это целое число, которое требует второе правило. Все это приводит к формированию ссылок вида:/newspage- для главной страницы,/newspage/1, /newspage/2, /newspage/3 - и так далее для последующих страниц. Содержание файла config/routing.yml при таких правилах
      newspage_base_controller:
          pattern: /newspage
          defaults: { _controller: nickvergessen.newspage.controller:base, page: 1 }
      newspage_page_controller:
          pattern: /newspage/{page}
          defaults: { _controller: nickvergessen.newspage.controller:base }
          requirements:
              page:  \d+
       

      Еще один необходимый файл из папки config/ называется services.yml, он содержит информацию о том, какие классы будет использовать контроллер в нашем расширении. Его содержимое в нашем случае
      services:
          nickvergessen.newspage.controller:
              class: nickvergessen\newspage\controller\main
              arguments:
                  - @auth
                  - @cache
                  - @config
                  - @dbal.conn
                  - @request
                  - @template
                  - @user
                  - @controller.helper
                  - %core.root_path%
                  - %core.php_ext%
       

      где, nickvergessen.newspage.controller - имя нашего контроллера, а class: nickvergessen\newspage\controller\main путь до файла main.php. Который в свою очередь и содержит в себе все функции и переменные, использующиеся в расширении. Его содержание для нашего случая
      <?php
      /**
      *
      * @package NV Newspage Extension
      * @copyright (c) 2013 nickvergessen
      * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
      *
      */

      namespace nickvergessen\newspage\controller;

      class main
      {
         /**
         * Constructor
         * NOTE: The parameters of this method must match in order and type with
         * the dependencies defined in the services.yml file for this service.
         *
         * @param \phpbb\config   $config      Config object
         * @param \phpbb\template   $template   Template object
         * @param \phpbb\user   $user      User object
         * @param \phpbb\controller\helper      $helper            Controller helper object
         * @param string         $root_path   phpBB root path
         * @param string         $php_ext   phpEx
         */
         public function __construct(\phpbb\config\config $config, \phpbb\template\template $template, \phpbb\user $user, \phpbb\controller\helper $helper, $root_path, $php_ext)
         {
            $this->config = $config;
            $this->template = $template;
            $this->user = $user;
            $this->helper = $helper;
            $this->root_path = $root_path;
            $this->php_ext = $php_ext;
         }

         /**
         * Base controller to be accessed with the URL /newspage/{page}
         * (where {page} is the placeholder for a value)
         *
         * @param int   $page   Page number taken from the URL
         * @return Symfony\Component\HttpFoundation\Response A Symfony Response object
         */
         public function base($page = 1)
         {
            /*
            * Do some magic here,
            * load your data and send it to the template.
            */

            /*
            * The render method takes up to three other arguments
            * @param   string      Name of the template file to display
            *                  Template files are searched for two places:
            *                  - phpBB/styles/<style_name>/template/
            *                  - phpBB/ext/<all_active_extensions>/styles/<style_name>/template/
            * @param   string      Page title
            * @param   int         Status code of the page (200 - OK [ default ], 403 - Unauthorized, 404 - Page not found, etc.)
            */
            return $this->helper->render('newspage_body.html');
         }
      }
       

      Как видно из строки
      return $this->helper->render('newspage_body.html');
       

      В нашем расширении используется шаблон стиля newspage_body.html, он должен располагаться в папке расширения styles/имя стиля/template/
    • 1.4 Модуль в администраторском разделе
      Информация из этого пункта относится и к Модераторскому и к Пользовательскому разделу. Ранее, в модификации к 3.0 файл для модуля в админке инфо-файл находился по пути phpBB/includes/acp/info/acp_newspage.php, в расширении же имя файла и путь будут такими - ext/nickvergessen/newspage/acp/main_info.php, аналогично для файла самого модуля - путь в 3.0 - phpBB/includes/acp/acp_newspage.php, в расширении же имя файла и путь будут такими - ext/nickvergessen/newspage/acp/main_module.php. Т.е. теперь оба файла модуля располагаются в одной папке и имеют схожие имена. Файл main_info.php (для нашего случая)
      <?php
      /**
      *
      * @package NV Newspage Extension
      * @copyright (c) 2013 nickvergessen
      * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
      *
      */

      namespace nickvergessen\newspage\acp;

      class main_info
      {
         function module()
         {
            return array(
               'filename'   => '\nickvergessen\newspage\acp\main_module',
               'title'      => 'ACP_NEWSPAGE_TITLE',
               'version'   => '1.0.1',
               'modes'      => array(
                  'config_newspage'   => array('title' => 'ACP_NEWSPAGE_CONFIG', 'auth' => 'acl_a_board', 'cat' => array('ACP_NEWSPAGE_TITLE')),
               ),
            );
         }
      }
       

      где строка
        'filename'   => '\nickvergessen\newspage\acp\main_module',
       

      Отвечает за расположение и имя основного файла модуля в админке, а
      'title'      => 'ACP_NEWSPAGE_TITLE',
       

      Переменная-имя нашего модуля в админке, а
         'version'   => '1.0.1',
       

      Версия расширения, а
       'config_newspage'   => array('title' => 'ACP_NEWSPAGE_CONFIG', 'auth' => 'acl_a_board', 'cat' => array('ACP_NEWSPAGE_TITLE')),
       

      Переменная-имя нашего модуля и подмодуля, метод авторизации.

      Файл main_module.php
      <?php
      /**
      *
      * @package NV Newspage Extension
      * @copyright (c) 2013 nickvergessen
      * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
      *
      */

      namespace nickvergessen\newspage\acp;

      class main_module
      {
         var $u_action;

         function main($id, $mode)
         {
            \\\\\здесь ваши функции для модуля в админке\\\\
         }
      }
       

      Таким образом мы создали (сконвертировали) модуль для админки, двигаем дальше
  • 2. Изменения в Базе Данных, замена UMIL на Миграции
    Миграция выполняет те же функции что и UMIL в тройке, автоматические запросы к БД. Самое важное отличие - для миграции необходим один файл, вместо кучи от UMIL. В нашем случае UMIL содержал в себе основу
    $versions = array(
          '1.0.0'   => array(
             'config_add' => array(
                array('news_number', 5),
                array('news_forums', '0'),
                array('news_char_limit', 500),
                array('news_user_info', 1),
                array('news_post_buttons', 1),
             ),
             'module_add' => array(
                array('acp', 'ACP_CAT_DOT_MODS', 'NEWS'),

                array('acp', 'NEWS', array(
                      'module_basename'   => 'newspage',
                      'module_langname'   => 'NEWS_CONFIG',
                      'module_mode'      => 'overview',
                      'module_auth'      => 'acl_a_board',
                   ),
                ),
             ),
          ),
          '1.0.1'   => array(
             'config_add' => array(
                array('news_pages', 1),
             ),
          ),
          '1.0.2'   => array(),
          '1.0.3' => array(
             'config_add' => array(
                array('news_attach_show', 1),
                array('news_cat_show', 1),
                array('news_archive_per_year', 1),
             ),
          ),
       );
     

    Посмотрим, каким образом воспроизвести это же, но с помощью миграции
    • 2.1 Изменения в Схеме (Schema)
      В миграции используются 2 метода-функции, один - public function update_schema() - для добавления данных в БД
      public function update_schema()
      {
         return array(
            'add_columns'        => array(
               $this->table_prefix . 'groups'        => array(
                  'group_teampage'    => array('UINT', 0, 'after' => 'group_legend'),
               ),
               $this->table_prefix . 'profile_fields'    => array(
                  'field_show_on_pm'        => array('BOOL', 0),
               ),
            ),
            'change_columns'    => array(
               $this->table_prefix . 'groups'        => array(
                  'group_legend'        => array('UINT', 0),
               ),
            ),
         );
      }
       

      Другой же - public function revert_schema() - для удаления данных из БД при деинсталляции расширения
      public function revert_schema()
      {
         return array(
            'drop_columns'        => array(
               $this->table_prefix . 'groups'        => array(
                  'group_teampage',
               ),
               $this->table_prefix . 'profile_fields'    => array(
                  'field_show_on_pm',
               ),
            ),
            'change_columns'    => array(
               $this->table_prefix . 'groups'        => array(
                  'group_legend'        => array('BOOL', 0),
               ),
            ),
         );
      }
       
    • 2.2 Изменения в Данных
      Данные могут быть нескольких типов - создание модулей (Админка, Модераторский раздел, Пользовательский раздел) module.add, обновление версии расширения config.add, создание прав доступа permission.add и заполнение первоначальными данными config.add. Суммарно все для нашего случая будет таким
         public function update_data()
         {
            return array(
               array('config.add', array('news_number', 5)),
               array('config.add', array('news_forums', '0')),
               array('config.add', array('news_char_limit', 500)),
               array('config.add', array('news_user_info', 1)),
               array('config.add', array('news_post_buttons', 1)),

               array('module.add', array(
                  'acp',
                  'ACP_CAT_DOT_MODS',
                  'ACP_NEWSPAGE_TITLE'
               )),
               array('module.add', array(
                  'acp',
                  'ACP_NEWSPAGE_TITLE',
                  array(
                     'module_basename'   => '\nickvergessen\newspage\acp\main_module',
                     'modes'            => array('config_newspage'),
                  ),
               )),

               array('config.add', array('newspage_mod_version', '1.0.0')),
            );
         }
       

    • 2.3 Зависимости и окончание миграции
      Финишными операциями являются проверки БД на предмет уже существующих записей о нашем расширении (ведь неизвестно, есть ли на конкретном форуме данное расширение. Обычно это и применяется при конвертации модификаций в расширения). Проверяется это с помощью функции public function effectively_installed()
      public function effectively_installed()
         {
            return isset($this->config['newspage_mod_version']) && version_compare($this->config['newspage_mod_version'], '1.0.0', '>=');
         }
       

      Так как миграционные файлы могут иметь различные имена и движок должен сам определить, что конкретный файл - миграционный, в 3.1 добавлена еще функция static public function depends_on().
         static public function depends_on()
         {
            return array('\phpbb\db\migration\data\v310\alpha1');
         }
       

      Отвечает она как раз таки за проверку корректности файлов в папке расширения migrations/ и теперь, с учетом всех функций, наш файл миграции имеет следующий вид
      <?php
      /**
      *
      * @package migration
      * @copyright (c) 2013 phpBB Group
      * @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
      *
      */

      namespace nickvergessen\newspage\migrations\v10x;

      class release_1_0_0 extends \phpbb\db\migration\migration
      {
         public function effectively_installed()
         {
            return isset($this->config['newspage_mod_version']) && version_compare($this->config['newspage_mod_version'], '1.0.0', '>=');
         }

         static public function depends_on()
         {
            return array('\phpbb\db\migration\data\v310\dev');
         }

         public function update_data()
         {
            return array(
               array('config.add', array('news_number', 5)),
               array('config.add', array('news_forums', '0')),
               array('config.add', array('news_char_limit', 500)),
               array('config.add', array('news_user_info', 1)),
               array('config.add', array('news_post_buttons', 1)),

               array('module.add', array(
                  'acp',
                  'ACP_CAT_DOT_MODS',
                  'ACP_NEWSPAGE_TITLE'
               )),
               array('module.add', array(
                  'acp',
                  'ACP_NEWSPAGE_TITLE',
                  array(
                     'module_basename'   => '\nickvergessen\newspage\acp\main_module',
                     'modes'            => array('config_newspage'),
                  ),
               )),

               array('config.add', array('newspage_mod_version', '1.0.0')),
            );
         }
      }
       
  • 3. Подключение к расширению языковых файлов
    Метод тройки $user->add_lang() в 3.1 не распознается, вместо него используется метод $user->add_lang_ext(), для примера
    $user->add_lang_ext('nickvergessen/newspage', 'newspage');
     

    Строка прописывается в файл событий (об этом чуть ниже), в ней nickvergessen/newspage определяет папку расширения в общей папке ext/, а newspage - имя языкового файла, в итоге, для нашего случая, языковой файл будет по адресу и с именем - /ext/nickvergessen/newspage/language/языковая папка(en, ru и тд.)/newspage.php
  • 4. Использование Событий и Слушателей (Events and Listeners) ()
    Забудьте в phpBB 3.1 / Ascraeus что такое правки файлов, с новой системой расширений вам не нужно будет проводить долгие часы устанавливая нужный функционал. Вместо правок используйте события и слушателей
    • 4.1 php события
      Вообщем, опять же на примере нашего мода и его конвертации, вместо добавления в код форума такой строки
       $template->assign_vars(array(
            'U_NEWSPAGE'   => append_sid($phpbb_root_path . 'app.' . $phpEx, 'controller=newspage/'),
         ));
       

      для функции page_header() мы создадим файл слушателей event/main_listener.php со следующим содержимым (с некоторыми классами из Symfony)
      <?php
      /**
      *
      * @package NV Newspage Extension
      * @copyright (c) 2013 nickvergessen
      * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
      *
      */

      namespace nickvergessen\newspage\event;

      /**
      * Event listener
      */
      use Symfony\Component\EventDispatcher\EventSubscriberInterface;

      class main_listener implements EventSubscriberInterface
      {
         /**
         * Instead of using "global $user;" in the function, we use dependencies again.
         */
         public function __construct(\phpbb\controller\helper $helper, \phpbb\template\template $template, \phpbb\user $user)
         {
            $this->helper = $helper;
            $this->template = $template;
            $this->user = $user;
         }
      }
       

      где в методе getSubscribedEvents() мы говорим системе какой набор слушателей ("подписчиков") нам нужен для нашего расширения, в нашем случае нам необходим такой "подписчик" как core.page_header (аналог того же page_header() из тройки) и загрузчик языковых файлов.
      static public function getSubscribedEvents()
         {
            return array(
               'core.user_setup'            => 'load_language_on_setup',
               'core.page_header'            => 'add_page_header_link',
            );
         }
       

      Теперь для ранее указанных слушателей добавим функции
       public function load_language_on_setup($event)
         {
            $lang_set_ext = $event['lang_set_ext'];
            $lang_set_ext[] = array(
               'ext_name' => 'nickvergessen/newspage',
               'lang_set' => 'newspage',
            );
            $event['lang_set_ext'] = $lang_set_ext;
         }

         public function add_page_header_link($event)
         {
            // I use a second language file here, so I only load the strings global which are required globally.
            // This includes the name of the link, aswell as the ACP module names.
            $this->user->add_lang_ext('nickvergessen/newspage', 'newspage_global');

            $this->template->assign_vars(array(
               'U_NEWSPAGE'   => $this->helper->route('newspage_base_controller'),
            ));
       

      Последним этапом является регистрация наших слушателей в системе. Это делается с помощью тега event.listener в service.yml (См. пункт 1.3 нашей статьи):
       nickvergessen.newspage.listener:
              class: nickvergessen\newspage\event\main_listener
              arguments:
                  - @controller.helper
                  - @template
                  - @user
              tags:
                  - { name: event.listener }
       

      И с этим шагом мы завершили правки php-кода.
    • 4.2 События шаблонов
      Теперь нам остается добавить правки в html-код, опять таки с помощью событий в шаблонах. Использование событий в шаблонах рассмотрим на примере:
      - для нашего расширения мы хотим добавить ссылку в шапку ссылку рядом с FAQ-ссылкой, потому среди мы находим нужное нам событие overall_header_navigation_prepend. Чтобы его применить нужно создать и поместить по следующему адресу следующий файл /ext/nickvergessen/newspage/styles/prosilver/template/event/overall_header_navigation_prepend_listener.html. То есть для применения события нужно создать файл с аналогичным событию именем, а вот в его содержании будет код, который вы хотите вставить в конкретное место в шаблоне, для нашего примера это
      <li class="icon-newspage"><a href="{U_NEWSPAGE}">{L_NEWSPAGE}</a></li>
       

      Аналогичным образом пихаем нужные куски кода в любое место на форуме. Можно для этих целей создавать мини-расширения дабы не загаживать код форума, используя знания из статьи
    • 4.3 Добавление событий
      Разумеется команда разработчиков не в состоянии учесть все возможные пожелания для событий, потому вы сами вольны подсказать им какое событие необходимо включить в следующие версии phpBB 3.1 / Ascraeus. А сделать это можно
  • 5. Совместимость
    С течением времени в разработке старые функции сменяются на новые, внимательно следите за всем этим в новостях разработки (можно еще посмотреть)
    • 5.1 Пагинация
      При создании пагинации по старому способу из тройки вы получите такую ошибку
      Цитата:
      Fatal error: Call to undefined function generate_pagination() in ...\phpBB3\ext\nickvergessen\newspage\controller\main.php on line 534

      Проблема в том, что пагинация страниц теперь не возвращается функцией, вместо того, чтобы автоматически генерироваться в шаблоне. В том же шаге, имя функции было обновлено ​​с PHPBB-префиксом. Старый код пагинации страниц был таким (приблизительно):
      $pagination = generate_pagination(append_sid("{$phpbb_root_path}app.$phpEx", 'controller=newspage/'), $total_paginated, $config['news_number'], $start);

         $this->template->assign_vars(array(
            'PAGINATION'      => $pagination,
            'PAGE_NUMBER'      => on_page($total_paginated, $config['news_number'], $start),
            'TOTAL_NEWS'      => $this->user->lang('VIEW_TOPIC_POSTS', $total_paginated),
         ));
       

      Правильный код таков
        $pagination = $phpbb_container->get('pagination');
         $pagination->generate_template_pagination(
            array(
               'routes' => array(
                  'newspage_base_controller',
                  'newspage_page_controller',
               ),
               'params' => array(),
            ), 'pagination', 'page', $total_paginated, $this->config['news_number'], $start);

         $this->template->assign_vars(array(
            'PAGE_NUMBER'      => $pagination->on_page($total_paginated, $this->config['news_number'], $start),
            'TOTAL_NEWS'      => $this->user->lang('VIEW_TOPIC_POSTS', $total_paginated),
         ));
       


_________________
Подпись:
-_- -_-
На вопросы, связанные с phpBB, по ЛС не отвечаю !!!
          Вернуться наверх  
 
 
Начать новую тему Ответить на тему


Дополнительные возможности

  Похожие темы  Автор  Ответов  Просмотров  Последнее сообщение 
Аватар пользователя Что такое расширение в phpBB 3.1 / Ascraeus ?
Разбираемся в понятии и струтуре расширений в phpBB 3.1 / Ascraeus

DeaDRoMeO

0

135

Аватар пользователя

01 мар 2017, 13:56

DeaDRoMeO

Аватар пользователя Как установить\обновить\удалить расширение phpBB 3.1
Правильная последовательность в работе с расширениями phpBB 3.1 / Ascraeus

DeaDRoMeO

2

411

Аватар пользователя

19 мар 2017, 20:31

DeaDRoMeO

Аватар пользователя phpBB 3.1.x/Ascraeus
Итак, дорогие дамы и господа, данная тема носит статус открывающей раздел и возможно эру нового phpBB - phpBB 3.1.x/Ascraeus. phpBB 3.1.x/Ascraeus - это продолжение серии популярных форумов phpBB, новая версия, скачок в будущее.
Тема закрыта
Аватар пользователя Инструменты миграции phpBB 3.1 / Ascraeus
Статья о работе с Базой Данных при создании расширения phpBB 3.1 / Ascraeus

DeaDRoMeO

0

76

Аватар пользователя

02 мар 2017, 17:56

DeaDRoMeO

Аватар пользователя Требования к хостингу phpBB 3.1 / Ascraeus
Минимальные системные требования для установки phpBB 3.1 / Ascraeus

DeaDRoMeO

0

115

Аватар пользователя

28 фев 2017, 18:44

DeaDRoMeO

Оставить свой комментарий

Поделиться темой с помощью

Ссылки на тему

Прямая ссылка:
BB-код для форумов, сайтов, блогов:
HTML ссылка:
 


Самая неформальная поддержка phpBB :P