Модель
Скелет
<?php namespace IPS\yourapp; class _YourClass extends \IPS\Content\Item { /** * @brief Multiton Store */ protected static $multitons; /** * @brief Default Values */ protected static $defaultValues = NULL; /** * @brief Application */ public static $application = 'yourapp'; /** * @brief Module */ public static $module = 'yourmodule'; /** * @brief Database Table */ public static $databaseTable = 'table'; /** * @brief Database Prefix */ public static $databasePrefix = 'prefix_'; /** * @brief Database Column Map */ public static $databaseColumnMap = array( 'author' => 'author' ); /** * @brief Title */ public static $title = ‘thing’; /** * Get URL * * @param string|NULL $action Action * @return \IPS\Http\Url */ public function url( $action=NULL ) { $url = \IPS\Http\Url::internal( ... ); if ( $action ) { $url = $url->setQueryString( 'do', $action ); } return $url; } }
Введение
Модель Элемента Содержимого (Content Item) представляет собой контент, созданный пользователями (например, в IP.Board тема является элементом содержимого).
Если Вы добавляете дополнительные функции для Элементов Содержимого, то Вы будете их добавлять и редактировать в этом скелетоне.
Наследование
Ваша модель расширяет количество классов. В свою очередь, они: -
\IPS\Content\Item
Обеспечивает функции элементов содержимого. Он содержит весь код для различных дополнительных функций элементов содержимого, которые вы сможете активировать, добавив свойства и интерфейсы к своей модели.
\IPS\Content
Обеспечивает небольшое количество функций, общих и для моделей Элемента Содержимого, и для моделей Комментария к Содержимому (пояснено позже), например можно узнать автора и работать с $databaseColumnMap.
\IPS\Patterns\ActiveRecord
Обеспечивает функции для загрузки элементов из базы данных, работы с их свойствами, их сохранения и удаления.
Необходимые свойства
string $application;
Ключ приложения, к которому принадлежит Элемент Содержимого.
string $module;
Ключ модуля, к которому принадлежит Элемент Содержимого.
array $multitons array $defaultValues;
Простые требования \IPS\Patterns\ActiveRecord - Вам не нужно делать ничего кроме как определить их.
string $databaseTable
Название таблицы базы данных, где хранится ваш Элемент Содержимого.
string $databasePrefix
Если все колонки в таблице вашей базы данных начинаются с одного и того же префикса, Вы можете определить его здесь, и тогда Вам не потребуется указывать его каждый раз, когда Вы будете искать значение в колонке. Важно, чтобы в таблице вашей базы данных была колонка {$databasePrefix}id, содержащая числовое значение первичного ключа.
array $databaseColumnMap
Функции, предоставляемые более высокими классами вашей модели, будут изучать этот массив на предмет того что хранится в определенных колонках базы данных.
Обязательные элементы:
- author должен содержать название колонки (без $databasePrefix), которая содержит ID пользователя, который опубликовал контент.
- title должен содержать название колонки (без $databasePrefix), которая содержит заголовок контента.
- date должна содержать название колонки (без $databasePrefix), которая содержит unix-временную отметку о том, когда был создан контент.
- ip_address должен содержать название колонки (без $databasePrefix), которая содержит IP адрес пользователя, который опубликовал контент.
string $title
Ключ для языковой строки, который описывает чем является ваш элемент содержимого (например, "Тема", "Файл", "Изображение", "Событие", и т.д.)
Имеющиеся методы
В дополнение к методам, предоставляемым \IPS\Patterns\ActiveRecord (что точно так же работает и для Узлов), доступно несколько дополнительных методов:
static getItemsWithPermission( ... )
Получает элементы содержимого. См. phpDocs для полной информации.
mapped( string $key )
Возвращает значение столбца, заданного $databaseColumnMap.
author()
Получает объект \IPS\Member для пользователя, который опубликовал контент. Например:
$item = YourClass::load( 1 ); $user = $item->author(); echo $user->name;
canView()
Возвращает логическое значение, указывающее может ли $member (NULL, если вошедший в данный момент пользователь) просматривать элемент содержимого. По-умолчанию будет возвращать значение TRUE, но на это влияет тот факт, включены ли Права доступа или Скрытие.
canEdit( \IPS\Member $member )
Возвращает логическое значение, указывающее может ли $member (NULL если вошедший в данный момент пользователь) редактировать элемент содержимого.
canDelete( \IPS\Member $member )
Возвращает логическое значение, указывающее может ли $member (NULL если вошедший в данный момент пользователь) удалить элемент содержимого.
static modPermission( $type, \IPS\Member $member = NULL, \IPS\Node\Model $container = NULL )
Возвращает логическое значение, указывающее имеет ли $member (пользователь, вошедший в данный момент, если NULL) права для выполнения действия, указанного $type в узле, указанном $container (если NULL, будет проверять есть ли у них права на всех узлах).
Приемлемые значения для $type:
- edit
- delete
- move
- feature (если разрешено Рекомендуемое)
- unfeature (если разрешено Рекомендуемое)
- pin (если разрешено Закрепление)
- unpin (если разрешено Закрепление)
- lock (если разрешена Блокировка)
- unlock (если разрешена Блокировка)
- hide (если разрешено Скрытие / Восстановление)
- unhide (если разрешено Скрытие / Восстановление)
- view_hidden (если разрешено Скрытие / Восстановление)
modAction( $action, \IPS\Member $member = NULL )
Выполняет действия модератора, указанные в $action. Сгенерирует OutOfRangeException если
$member (вошедший на данный момент пользователь, если NULL) не имеет права на совершение данного действия.
Контроллер
Скелетон
namespace IPS\yourapp\modules\front\yourmodule; class _yourcontroller extends \IPS\Content\Controller { }
Введение
Контроллер, сразу после того как определен, дает пользователям возможность удалять содержимое, если вы присоедините “&do=delete&id=X” к URL, необходимому для доступа к контроллеру (где “X” - ID номер). Он будет автоматически проверять есть ли у пользователя права на выполнение заданного действия (что, по умолчанию, правдиво только в том случае, если пользователь является модератором с правами на удаление всего контента).
Если вы добавляете дополнительные функции к своему Элементу Содержимого, контроллер будет выполнять больше действий. Естественно, вы также добавите собственные методы в целях содействия фактическому отображению содержимого.
Отображение таблицы
Вы можете использовать класс IPS\Helpers\Table\Content для отображения списка всех элементов содержимого в узле.
$table = new \IPS\Helpers\Table\Content( 'IPS\yourApp\YourClass', $node->url(), NULL, $node ); \IPS\Output::i()->output = $table;
Таблица будет автоматически разбита постранично и будет показывать только те элементы, на просмотр которых есть права у пользователей.
Если вы хотите отобразить элементы по-другому, вы можете указать пользовательский шаблон для использования:
$table->rowsTemplate = array( \IPS\Theme::i()->getTemplate( 'yourTemplateGroup' ), 'yourTemplate' );
См. пример в шаблоне по умолчанию (core —> front —> tables —> rows).
Создание формы добавления публикации
Вы можете создать форму для пользователей, чтобы они отправляли элементы просто вызывая метод create():
\IPS\Output::i()->output = \IPS\yourApp\YourClass::create( $node );
Вы должны передать узел, в котором создается элемент содержимого (или NULL, если ваши элементы содержимого не зависят от узлов или если вы добавите элемент в форме отправки), и метод будет автоматически обрабатывать отображение формы, создание элемента и перенаправление.
Формы элементов для отображения получаем из метода formElements(array $values, \IPS\Node\Model $node), который вы можете перезаписать для добавления дополнительных элементов формы (они также будут отображаться в форме редактирования). Он автоматически будет включать элементы для заголовка, тегов (если включен - см. раздел Теги) и первого комментария (если включены комментарии, то первый комментарий является обязательным - см. главу 3); поэтому убедитесь, что вы вызываете метод в родительском классе и не перезапишете это. Названия элементов формы имеют префикс статичного свойства
$formLangPrefix (которое является пустой строкой, если не переопределено) - таким образом, вы можете использовать это для настройки заголовков, используемых в элементах формы.
Есть несколько методов, которые вы также можете переопределить для выполнения действий в различных точках процесса создания:
canCreate( \IPS\Member $member, \IPS\Node\Model $container=NULL, bool $showError=FALSE )
Даже прежде чем будет отображена эта форма, запускается этот метод для проверки может ли пользователь создавать элемент в данном узле. Большая часть проверки прав доступа выполняется автоматически, так что вам обычно не нужно переопределять этот метод, если только нет конкретных особенностей (например, в мессенджере можно установить, чтобы пользователи могли отправлять только определенное количество сообщений в день - так что этот пункт проверяется в данном методе внутри мессенджера).
processBeforeCreate( array $values )
Этот метод запускается после того как был создан объект и установлены значения по умолчанию, такие как автор, дата и любые другие поля, которые могут быть установлены в силу того, что имеют тот же ключ, как и колонка базы данных, но перед тем как элемент добавлен в базу данных. Он получает значения из формы.
processForm( array $values )
Этот метод запускается сразу же после processBeforeCreate(). Он отличается от processAfterCreate() в том, что работает и для внесения изменений, и для добавления новых пунктов. Вы должны использовать его для установки любых полей, добавленных в formElements( ), которые более сложные, чем просто настройка прямого значения (что будет сделано автоматически).
По умолчанию, метод устанавливает заголовок, теги (если включены - см. раздел Теги) и другие данные, поэтому убедитесь, что вызываете метод в родительском классе и не перезапишите данную настройку.
processAfterCreate( \IPS\Content\Comment $comment=NULL, array $values )
Этот метод запускается после того как элемент содержимого был вставлен в базу данных и завершена вся обработка, включая создание первого комментария (если включено, см. главу 3). Если применимо, он получается объект для первого комментария и значения из формы.
Заметки
Подсчет постов
Количество постов будет автоматически увеличиваться, когда пользователь будет публиковать элемент содержимого. Это может быть нежелательным, особенно если ваши элементы содержимого являются просто контейнерами для комментариев, что также увеличивает количество постов (как тем в IP.Board). Вы можете отключить это поведение при помощи свойства:
public static $incrementPostCount = TRUE;
Контейнеры
Введение
Элементы Содержимого, которые принадлежат к Узлам, могут определять эту взаимосвязь.
Другие требования
Нет
Что меняется после внедрения
Нет
Дополнительные методы, доступные после внедрения
container()
Возвращает объект контейнера.
canMove( \IPS\Member $member=NULL )
Возвращает логическое значение, указывающее может ли $member (пользователь, вошедший в данный момент, если NULL) перемещать элемент в другой контейнер.
move( \IPS\Node\Model $container )
Перемещает элемент в другой контейнер.
Дополнительные методы, доступные для класса контейнера после внедрения
get_items() get_comments() get_reviews() get_unapprovedItems() get_unapprovedComments() get_unapprovedReviews() set_items( $val ) set_comments( $val ) set_reviews( $val ) set_unapprovedItems( $val ) set_unapprovedComments( $val ) set_unapprovedReviews( $val )
Получает/устанавливает количество (подтвержденных) элементов/комментариев/обзоров и количество неподтвержденных. Подтвержденный/неподтвержденный применимо только в том случае, если содержимое можно скрыть (объяснено далее).
По умолчанию, все get_ методы возвращают NULL и set_ методы ничего не делает. Вы можете изменить их, если вашему контейнеру необходимо отслеживать номера.
Для того чтобы неподтвержденные комментарии/обзоры надежно обследовались, ваши элементы содержимого должны иметь элементы “unapproved_comments” или “unapproved_reviews” в колонках базы данных (см. главу 3).
setLastItem( \IPS\Content\Item $item ) setLastComment( \IPS\Content\Comment $comment ) setLastReview( \IPS\Content\Review $review )
Эти методы вызываются автоматически при публикации нового элемента/комментария/обзора. По умолчанию, они ничего не делают, но вы можете изменить их, если вашему контейнеру необходимо отслеживать последний элемент/комментарий/обзору внутри него. В некоторых случаях, передаваемая переменная будет NULL, и в этом случае вы должны вручную извлечь последний элемент/комментарий/обзор.
Эти методы должны иметь соответствующие настройки, чтобы после применения вызывать такой же метод во всех дочерних узлах.
getLastCommentTime()
Если используется setLastComment( ), этот метод можно использовать в сочетании чтобы вернуть объект \IPS
\DateTime, отображающей время, когда был опубликован элемент, комментарий или обзор. Используется для считывания маркировки.
Как применить
1. Добавьте новое свойство:
/** * @brief Node Class */ protected static $containerNodeClass = 'IPS\yourapp\YourNodeClass';
2. Добавьте элемент container к $databaseColumnMap с указанием колонки в базе данных, которая содержит ID контейнера.
Права доступа
Введение
Элементы содержимого могут автоматически проверять есть ли у пользователя права на выполнение определенных действий, проверив контейнер.
См. главу 1 для получения дополнительной информации об определении прав доступа в Узлах.
Другие требования
Контейнеры
Что меняется после внедрения
- canView(…)вернет "ложь" для элемента внутри узла, если у пользователя нет прав на его просмотр. Это также приведет к тому, что loadAndCheckPerms(…)выдаст исключение OutOfRange, если будет загружен подобный объект.
- Везде, где функции что-либо выполняют, будут проверяться права доступа. Например, canCreate(... ) теперь вернет false, если у пользователя нет прав на создание элементов содержимого в указанном узле.
- getItemsWithPermission(…)теперь будет возвращать только те элементы, которые дозволено просматривать вошедшему в данный момент пользователю (или если у него есть иные права доступа, указанные в параметрах).
Дополнительные методы, доступные после внедрения
can( string $permission[, mixed $member ] )
Проверяет есть ли у пользователя права, необходимые для выполнения указанного действия. Действие должно совпадать со значением статичного свойства $permissionMap класса контейнера. $member может быть либо NULL (что будет проверять права доступа вошедшего в данный момент пользователя), или
\IPS\Member или объектом \IPS\Member\Group.
permId()
Возвращает ID числового значения прав доступа.
Как применить
1. Добавьте интерфейс:
implements \IPS\Content\Permissions
Перенаправление содержимого
Введение
Некоторые функции, такие как предупреждения, являются правами модератора и обрабатываются централизованно и автоматически. Для регистрации ваших элементов содержимого в ядре, вам нужно создать простой файл расширения, называемый Content Router .
Другие требования
Контейнеры
Что меняется после внедрения
- При создании модератора, администраторы смогут настроить права модератора для определенных элементов содержимого.
- При просмотре профиля пользователя, отображаемый весь контент, опубликованный этим пользователем, будет включать ваши элементы содержимого.
- Если у вас включены скрытые элементы содержимого, при просмотре панели управления администратора будет показан весь скрытый контент из вашего приложения.
- Когда модератор дает пользователю предупреждение, если это предупреждение выдано вследствие элемента содержимого, то тогда контент будет связан с предупреждением.
- При восстановлении количества постов пользователя, будут считать ваши элементы содержимого.
- При удалении всего контента, опубликованного пользователем, будут считать ваши элементы содержимого.
Дополнительные методы, доступные после внедрения
Нет
Как применить
1. Создайте новое расширение ContentRouter в своем приложении, используя следующий код:
namespace IPS\yourApp\extensions\core\ContentRouter; class _YourClass extends \IPS\Content\ModeratorPermissions { public $classes = array( 'IPS\yourApp\YourContentItemClass' ); }
2. Добавьте свойство $modPerm к своей модели Узла с ключом, который будет использоваться как ключ для хранения узлов, на которые модератор обладает правами доступа (любыми). Создать языковую строку с таким же ключом и значением, представляющем как называются Ваши узлы (например, "Категории").
3. Добавьте языковые строки для каждого из доступных действий модератора следующим образом:
can_<action>_<title>
Где “<title>” - это ключ, определяемый статичным свойством $title в вашей модели элемента содержимого. Если Ваши элементы содержимого поддерживают комментарии, повторите все действия, которые можно выполнить с комментариями (edit, delete, hide, unhide, view_hidden), где “<title>” - это ключ, определенный статичным свойством $title в вашей модели комментариев к контенту.
Введение в Content Items. Часть 2