Расширения - это просто!

Форум для авторов расширений для phpBB. Здесь можно попросить помощи в разработке у коллег.
Правила форума
Местная Конституция | Шаблон запроса | Документация (phpBB3) | Мини [FAQ] по phpBB3.1.x/3.3.x | FAQ | Как задавать вопросы | Как устанавливать расширения

Ваш вопрос может быть удален без объяснения причин, если на него есть ответы по приведённым ссылкам (а вы рискуете получить предупреждение ;) ).
Аватара пользователя
rxu
phpBB Guru
phpBB Guru
Сообщения: 14489
Зарегистрирован: 12.05.2006 18:16
Откуда: Красноярск
Благодарил (а): 347 раз
Поблагодарили: 1546 раз
Контактная информация:

Расширения - это просто!

Сообщение rxu » 22.03.2014 9:53

Что такое расширение?

Расширение - это новая система изменения и дополнения функционала phpBB, представленная в версии phpBB 3.1, пришедшая на смену модам, использовавшимся в версии phpBB 3.0. Представляет из себя набор файлов, копируемых в папку /ext. Включение и настройка расширения осуществляется через администраторский раздел.
Основное преимущество системы расширений - отсутствие необходимости вручную вносить изменения в исходный код и базу данных phpBB. Первое основано на так называемых "событиях".

Что такое событие?

Событие (event) - это строка (как правило, одна или две) в исходном коде, добавленная разработчиками. События подразделяются на два вида: событие ядра и событие шаблона. Каждое событие имеет собственный идентификатор, по которому определяется, код каких расширений и в каком месте будет выполняться.
Пример: событие ядра в posting.php

Код: Выделить всё

$vars = array('post_id', 'topic_id', 'forum_id', 'draft_id', 'lastclick', 'submit', 'preview', 'save', 'load', 'delete', 'cancel', 'refresh', 'mode', 'error');
extract($phpbb_dispatcher->trigger_event('core.modify_posting_parameters', compact($vars)));
В данном случае, идентификатором события является имя core.modify_posting_parameters. Массив $vars содержит список переменных, которые будут переданы расширению и могут быть им использованы, в том числе изменены/дополнены их значения.

Пример: событие шаблона в quickreply_editor.html

Код: Выделить всё

<!-- EVENT quickreply_editor_message_before -->
В данном случае идентификатором события является имя quickreply_editor_message_before. О том, как работают события шаблонов, будет описано позже.

В свою очередь, в расширениях имеются так называемые "слушатели" (или подписчики) событий ядра (listeners, event subscribers), представляющая собой сопоставление идентификатора события с именем функции в расширении, которая должна быть вызвана при возникновении данного события.
Например:

Код: Выделить всё

	static public function getSubscribedEvents()
	{
		return array(
			'core.page_header'					=>	'show_quicknick',
			'core.viewtopic_modify_page_title'	=>	'show_bbcodes_and_smilies',
			'core.modify_posting_parameters'	=>	'change_subject',
			'core.posting_modify_template_vars'	=>	'delete_re',
		);
	}
Функция static public function getSubscribedEvents() является стандартной для перечисления подписчиков (или слушателей) события ядра. Как видно, при возникновении события core.page_header будет вызвана функция function show_quicknick(), которая задается в самом расширении. И так далее.

События шаблона
Для событий шаблона система обработки немного отличается. При возникновении такого события, система пытается найти html файл, названный по имени данного события, в подпапках расширения, связанных со стилями. Например, для события <!-- EVENT quickreply_editor_message_before --> будет предпринята попытка найти файл quickreply_editor_message_before.html в папках /ext/tatiana5/quickreply/styles/prosilver/template/event/, /ext/tatiana5/quickreply/styles/subsilver2/template/event/ и аналогичных для других стилей, либо /ext/tatiana5/quickreply/styles/all/template/event/, если данный шаблон события будет общим для всех стилей.

Где находятся расширения?

Расширения должны располагаться в папке /ext. Внутри этой папки располагаются папки, названные по именам авторов (вендоров) расширений. Например, все расширения автора tatiana5 будут располагаться в папке /ext/tatiana5.
Вы можете сами выбрать для себя имя вендора, которое хотите использовать в этих целях. Оно будет необходимо и в коде самого расширения, но об этом чуть позже.

Из чего состоит расширение?

Расширения должны иметь определенную структуру - т.е. минимально необходимый набор папок и файлов, определяющих его работу:

Код: Выделить всё

config\
event\
migrations\
composer.json
ext.php
Начнем с самого начала.

Папка config.
В ней расположен единственный файл - services.yml, который передает системе основные сведения о расширении, его расположении и используемых им так называемых "сервисах" - т.е. встроенных классах и переменных phpBB. Например:

Код: Выделить всё

services:
    tatiana5.quickreply.listener:
        class: tatiana5\quickreply\event\listener
        arguments:
            - @auth
            - @config
            - @dbal.conn
            - @template
            - @user
            - %core.root_path%
            - %core.php_ext%
        tags:
            - { name: event.listener }
Оператор services является стандартным и не подлежит изменению.

Строка tatiana5.quickreply.listener: задает основной сервис расширения - имя класса слушателя события listener для расширения, находящегося в папке /ext/tatiana5/quickreply.

Строка class: tatiana5\quickreply\event\listener задает имя файла, в котором располагается класс. В данном случае это файл ext/tatiana5/quickreply/event/listener.php.

Блок arguments: задает перечень аргументов, которые будут использованы в конструкторе класса. Аргументы в конструкторе должны следовать исключительно в том же порядке, в котором они указаны здесь.
В данном случае мы видим, что конструктор расширения будет использовать стандартные классы phpBB: auth, config, db, template, user, а также переменные phpbb_root_path и php_ext. А вот как это выглядит на практике:

Код: Выделить всё

	public function __construct(\phpbb\auth\auth $auth, \phpbb\config\config $config, \phpbb\db\driver\driver $db, \phpbb\template\template $template, \phpbb\user $user, $phpbb_root_path, $php_ext)
	{
		$this->auth = $auth;
		$this->config = $config;
		$this->db = $db;
		$this->template = $template;
		$this->user = $user;
		$this->phpbb_root_path = $phpbb_root_path;
		$this->php_ext = $php_ext;
	}
Еще раз обратите внимание, что аргументы следуют в том порядке, в котором они указаны в файле services.yml.

Блок tags: является для слушателей событий стандартным и не подлежит изменению.

Внимание: синтаксис языка YAML позволяет использовать в качестве отступов исключительно пробелы. Знаки табуляции не допускаются.
Изображение

Аватара пользователя
rxu
phpBB Guru
phpBB Guru
Сообщения: 14489
Зарегистрирован: 12.05.2006 18:16
Откуда: Красноярск
Благодарил (а): 347 раз
Поблагодарили: 1546 раз
Контактная информация:

Расширения - это просто!

Сообщение rxu » 23.03.2014 16:58

Папка migrations.
Здесь находятся файлы с инструкциями, ответственными за внесение дополнений и изменений в базу данных (добавление новых таблиц, столбцов в имеющихся таблицах, изменение и добавление новых конфигурационных параметров в таблицу _config, и так далее).
Как правило, файл именуется в соответствии с версией расширения, например, v_0_0_1.php.
Внутри файла находится класс, являющийся потомком класса \phpbb\db\migration\migration, имя которому присваивается также исходя из версии расширения, например: v_0_0_1.
Таким образом, получаем определение класса: class v_0_0_1 extends \phpbb\db\migration\migration.

Класс миграции состоит из набора стандартных функций, но могут быть и нестандартные.

Стандартными функциями являются:

public function effectively_installed() - отвечает за проверку версии расширения;
static public function depends_on() - отвечает за определение встроенного класса миграции, необходимого для внесения изменений в БД;
public function update_schema() - отвечает за внесение изменений в схему БД;
public function revert_schema() - отвечает за возврат схемы БД в начальное состояние при удалении расширения;
public function update_data() - отвечает за внесение новых данных в БД (в том числе конфигурационных данных, добавление новых модулей в администраторский/модераторский/личный разделы, добавление новых прав доступа и пр.);
public function revert_data() - отвечает за восстановление данных в исходном виде при удалении расширения.

Также могут присутствовать и пользовательские функции, вызываемые внутри указанных выше стандартных. Например, инструкция array('custom', array(array($this, 'purge_cache'))), говорит о том, что должна быть вызвана пользовательская (custom) функция $this->purge_cache().

Подробно о миграциях можно прочесть на соответствующей странице phpBB Development wiki (English).

Файл composer.json.
Отвечает за предоставление системе основной информации о расширении - его названии, версии, лицензии, авторе (или группе авторов), системных требованиях.
Подробнее о синтаксисе файла можно прочесть на соответствующей странице домашнего ресурса Composer (English).

Пример:

Код: Выделить всё

{
    "name": "gfksx/thanks_for_posts",
    "type": "phpbb-extension",
    "description": "Adds the ability to thank the author (thanks to cancel), and use the rating system posts/topics/forums based on the issued of thanks.",
    "homepage": "http://www.phpbbguru.net",
    "version": "2.0.0",
    "time": "2014-03-09",
    "licence": "GPL-2.0",
    "authors": [
        {
            "name": "Палыч",
            "homepage": "http://www.phpbbguru.net",
            "role": "Developer"
        },
        {
            "name": "rxu",
            "homepage": "http://www.phpbbguru.net",
            "role": "Converting to extension"
        }
    ],
    "require": {
        "php": ">=5.3.3",
    },
    "extra": {
        "display-name": "Thanks for posts"
        "soft-require": {
           "phpbb/phpbb": "3.1.*@dev"
         }
    }
}
Файл ext.php.
Является опциональным (необязательным), служит для расширения класса \phpbb\extension\base в случаях, когда необходимо выполнить дополнительные действия при установке/удалении/очистке данных расширения. Пример:

Код: Выделить всё

<?php
/**
*
* Board Rules extension for the phpBB Forum Software package.
*
* @copyright (c) 2013 phpBB Limited <https://www.phpbb.com>
* @license GNU General Public License, version 2 (GPL-2.0)
*
*/

namespace phpbb\boardrules;

/**
* Extension class for custom enable/disable/purge actions
*
* NOTE TO EXTENSION DEVELOPERS:
* Normally it is not necessary to define any functions inside the ext class below.
* The ext class may contain special (un)installation commands in the methods
* enable_step(), disable_step() and purge_step(). As it is, these methods are defined
* in phpbb_extension_base, which this class extends, but you can overwrite them to
* give special instructions for those cases. Board Rules must do this because it uses
* the notifications system, which requires the methods enable_notifications(),
* disable_notifications() and purge_notifications() be run to properly manage the
* notifications created by Board Rules when enabling, disabling or deleting this
* extension.
*/
class ext extends \phpbb\extension\base
{
	/**
	* Single enable step that installs any included migrations
	*
	* @param mixed $old_state State returned by previous call of this method
	* @return mixed Returns false after last step, otherwise temporary state
	*/
	function enable_step($old_state)
	{
		switch ($old_state)
		{
			case '': // Empty means nothing has run yet

				// Enable board rules notifications
				$phpbb_notifications = $this->container->get('notification_manager');
				$phpbb_notifications->enable_notifications('boardrules');
				return 'notifications';

			break;

			default:

				// Run parent enable step method
				return parent::enable_step($old_state);

			break;
		}
	}

	/**
	* Single disable step that does nothing
	*
	* @param mixed $old_state State returned by previous call of this method
	* @return mixed Returns false after last step, otherwise temporary state
	*/
	function disable_step($old_state)
	{
		switch ($old_state)
		{
			case '': // Empty means nothing has run yet

				// Disable board rules notifications
				$phpbb_notifications = $this->container->get('notification_manager');
				$phpbb_notifications->disable_notifications('boardrules');
				return 'notifications';

			break;

			default:

				// Run parent disable step method
				return parent::disable_step($old_state);

			break;
		}
	}

	/**
	* Single purge step that reverts any included and installed migrations
	*
	* @param mixed $old_state State returned by previous call of this method
	* @return mixed Returns false after last step, otherwise temporary state
	*/
	function purge_step($old_state)
	{
		switch ($old_state)
		{
			case '': // Empty means nothing has run yet

				// Purge board rules notifications
				$phpbb_notifications = $this->container->get('notification_manager');
				$phpbb_notifications->purge_notifications('boardrules');
				return 'notifications';

			break;

			default:

				// Run parent purge step method
				return parent::purge_step($old_state);

			break;
		}
	}
}
И, наконец, последняя необходимая для работы расширения папка - event с файлом, содержащим слушатели событий ядра. Если говорить проще - тут находится весь рабочий PHP код расширения.
Исходя из информации, обозначенной в служебных файлах выше в данной статье, файл должен называться /event/listener.php.
Внутри файла находится основной класс расширения, фактически отвечающий за весь его функционал, являющийся потомком встроенного класса EventSubscriberInterface:
class listener implements EventSubscriberInterface.

Первой и второй стандартными функциями, с которыми мы встречаемся в данном классе, являются уже упомянутые выше конструктор класса public function __construct() и список событий, на которые подписано расширение static public function getSubscribedEvents().
Все остальные функции являются пользовательскими, их имена, структура и исполняемый код зависят непосредственно от той задачи, которую решает расширение.

Другие папки, встречающиеся в расширениях.

Если расширение использует пользовательские языковые переменные, то они должны быть помещены в отдельный языковой файл (или файлы), которые располагаются в подпапках расширения /language/en, language/ru и так далее.

Если расширение использует события шаблонов, соответствующие файлы шаблонов, названные по имени событий (о чём уже было сказано выше) располагаются в подпапке расширения /styles/prosilver/template/event. Если используются события шаблонов администраторского раздела, то файлы помещаются в подпапку расширения /styles/adm/template/event.

Как выбрать нужное событие ядра?
Говоря простым языком, представьте, что вместо события находится оператор include, куда вы можете добавить нужный вам файл с кодом.

Полный список имеющихся в настоящий момент событий ядра и шаблонов находится на соответствующей странице phpBB Development wiki - Event list (English).

Если для работы написанного вами расширения отсутствует нужное событие, и нет возможности обойти данное ограничение - можно создать запрос в багтрекере phpBB и отправить пулл реквест в основной репозиторий. Как правило, это приветствуется разработчиками. Если вы не имеете возможности сделать это самостоятельно, можно обратиться к команде phpBB Guru, и мы технически поможем с добавлением нового события в исходный код phpBB. Если команда разработчиков одобрит - событие будет обязательно добавлено.

Примеры работающих расширений, разработанных членами команды phpBB Guru (ссылки на репозитории в Github):
Posts merging
List subforums in columns
Topic actions
First post on every page
Detailed viewonline

А первым расширением, разработанным командой phpBB Guru, стал Quick reply от Tatiana5, добавляющий новый функционал во встроенный быстрый ответ. Кстати, для его работы в исходный код phpBB в официальном репозитории были добавлены новые события шаблона - в этом можно убедиться самостоятельно. :)
Изображение

Аватара пользователя
xisp
phpBB 3.0.0 RC7
Сообщения: 1799
Зарегистрирован: 19.05.2012 19:00
Благодарил (а): 152 раза
Поблагодарили: 215 раз
Забанен: Бессрочно

Re: Расширения - это просто!

Сообщение xisp » 25.03.2014 16:35

По тексту- для примера лучше использовать однообразные имена, к примеру тут сейчас для примера имени папки автора используется вначале /ext/rxu, а потом /ext/tatiana5/quickreply. Лучше привести к одному знаменателю.
rxu писал(а):Внимание: синтаксис языка YAML позволяет использовать в качестве отступов исключительно пробелы. Знаки табуляции не допускаются.
Фи, мерзость какая. Придётся автозаменой проходить.
В остальном ничего так. Куча файлов, папок, но без этого не как.
phpBBex

Аватара пользователя
rxu
phpBB Guru
phpBB Guru
Сообщения: 14489
Зарегистрирован: 12.05.2006 18:16
Откуда: Красноярск
Благодарил (а): 347 раз
Поблагодарили: 1546 раз
Контактная информация:

Re: Расширения - это просто!

Сообщение rxu » 25.03.2014 16:52

xisp писал(а):Лучше привести к одному знаменателю.
Согласен.
xisp писал(а):В остальном ничего так. Куча файлов, папок, но без этого не как.
Есть достаточно много нюансов и фишек, но изложить их все сразу практически невозможно.
Например, как подключить служебные файлы, содержащие набор функций, или создать собственную cron задачу, и т.п.

Будем разбираться по мере появления вопросов.
Изображение

Аватара пользователя
xisp
phpBB 3.0.0 RC7
Сообщения: 1799
Зарегистрирован: 19.05.2012 19:00
Благодарил (а): 152 раза
Поблагодарили: 215 раз
Забанен: Бессрочно

Re: Расширения - это просто!

Сообщение xisp » 31.03.2014 3:08

Вопрос- изменять шаблоны как-то можно, или только дополнять? Вот к примеру колонка "Последнее сообщение" на главной сделана в три строчки, хотя можно сделать красиво в две.
phpBBex

Аватара пользователя
rxu
phpBB Guru
phpBB Guru
Сообщения: 14489
Зарегистрирован: 12.05.2006 18:16
Откуда: Красноярск
Благодарил (а): 347 раз
Поблагодарили: 1546 раз
Контактная информация:

Re: Расширения - это просто!

Сообщение rxu » 31.03.2014 19:31

Можно и изменить, но это нелинейный процесс. Все события, как правило, парные (но есть исключения).
Таким образом, если в шаблоне для первого события открыть комментарий <!--, в парном событии его закрыть --> и после этого дописать свой код замены, получится, что исходный код закомментирован и заменен другим.
Изображение

Аватара пользователя
xisp
phpBB 3.0.0 RC7
Сообщения: 1799
Зарегистрирован: 19.05.2012 19:00
Благодарил (а): 152 раза
Поблагодарили: 215 раз
Забанен: Бессрочно

Re: Расширения - это просто!

Сообщение xisp » 31.03.2014 20:12

О ужас. Это же сколько всего будет передаваться лишнего в браузер. А я понимаете ли табы при кешировании удаляю, чтобы страницы легче были))
Я уж лучше по старинке буду править. К примеру не считая админки и добавления значений конфигурации в БД мод Quote Post Back Link отлично встал и работает.
Думаю, всё же появится расширение наподобие автомода с UMIL, которое позволит другим расширениям вносить правки сразу в код. Это более гибко и производительно.
Что же, благодарю за ответ.
phpBBex

Аватара пользователя
rxu
phpBB Guru
phpBB Guru
Сообщения: 14489
Зарегистрирован: 12.05.2006 18:16
Откуда: Красноярск
Благодарил (а): 347 раз
Поблагодарили: 1546 раз
Контактная информация:

Re: Расширения - это просто!

Сообщение rxu » 31.03.2014 20:20

xisp
Да нет здесь никакого ужаса. Prosilver - таков, каков он есть. Под все вкусы его не приспособишь.
Поэтому есть возможность создать и/или установить альтернативные стили, где можно разгуляться как душе угодно.
Изображение

Аватара пользователя
xisp
phpBB 3.0.0 RC7
Сообщения: 1799
Зарегистрирован: 19.05.2012 19:00
Благодарил (а): 152 раза
Поблагодарили: 215 раз
Забанен: Бессрочно

Re: Расширения - это просто!

Сообщение xisp » 31.03.2014 20:32

Понятно, что для себя я перекурочу стиль как хочу, но в данном случае я пишу в контексте модификаций.
Вот к примеру захочу я сделать расширение- меню на все страницы с заменой стандартного.
В итоге мне либо придётся каким- то образом менять файлы стиля, либо заставлять пересылать кучу форумов килобайты комментариев в коде, или просто скрытых через стили блоки.
Хотя да, к сожалению, мне более гибкого и простого механизма в голову не приходит.
phpBBex

Аватара пользователя
xisp
phpBB 3.0.0 RC7
Сообщения: 1799
Зарегистрирован: 19.05.2012 19:00
Благодарил (а): 152 раза
Поблагодарили: 215 раз
Забанен: Бессрочно

Re: Расширения - это просто!

Сообщение xisp » 28.04.2014 21:08

xisp писал(а):По тексту- для примера лучше использовать однообразные имена, к примеру тут сейчас для примера имени папки автора используется вначале /ext/rxu, а потом /ext/tatiana5/quickreply. Лучше привести к одному знаменателю.
Продолжаю- во втором сообщении в качестве примера используется "gfksx/thanks_for_posts".
phpBBex

Аватара пользователя
Алг
Former team member
Сообщения: 878
Зарегистрирован: 31.07.2012 23:11
Откуда: Израиль
Благодарил (а): 84 раза
Поблагодарили: 279 раз
Контактная информация:

Re: Расширения - это просто!

Сообщение Алг » 10.05.2014 12:30

возникла проблема при попытке подключить через ACP готовое расширение(любое)
получаю сообщение
Required meta field 'licence' has not been set.
Кто-то сталкивался? И что делать?
Там упёртость и инертность, могут, кстати, в морду дать.
А ты проявляй интеллигентность, постарайся убеждать...

Т. Шаов

Аватара пользователя
Татьяна5
Поддержка
Поддержка
Сообщения: 9712
Зарегистрирован: 08.08.2011 2:02
Благодарил (а): 175 раз
Поблагодарили: 2700 раз
Контактная информация:

Re: Расширения - это просто!

Сообщение Татьяна5 » 10.05.2014 12:33

В файле composer.json заменить licence на license (с версии phpBB 3.1 beta2)

Аватара пользователя
Алг
Former team member
Сообщения: 878
Зарегистрирован: 31.07.2012 23:11
Откуда: Израиль
Благодарил (а): 84 раза
Поблагодарили: 279 раз
Контактная информация:

Re: Расширения - это просто!

Сообщение Алг » 10.05.2014 12:54

Татьяна5, спасибо. Я поставила beta1 и мне, наоборот, пришлось заменить license на licence..
А где б нам взять бета 2 и 3?

Добавлено спустя 5 минут 36 секунд:
нашла https://area51.phpbb.com/downloads/
Там упёртость и инертность, могут, кстати, в морду дать.
А ты проявляй интеллигентность, постарайся убеждать...

Т. Шаов


Аватара пользователя
Алг
Former team member
Сообщения: 878
Зарегистрирован: 31.07.2012 23:11
Откуда: Израиль
Благодарил (а): 84 раза
Поблагодарили: 279 раз
Контактная информация:

Re: Расширения - это просто!

Сообщение Алг » 10.05.2014 13:13

c beta3 всё нормально работает, спасибо ещё раз
Там упёртость и инертность, могут, кстати, в морду дать.
А ты проявляй интеллигентность, постарайся убеждать...

Т. Шаов

Ответить

Вернуться в «Для авторов»