Перейти к содержанию

invisionbyte

Администраторы
  • Постов

    962
  • Зарегистрирован

  • Посещение

  • Победитель дней

    130

Весь контент invisionbyte

  1. invisionbyte

    Отображение формы

    Приведение объекта $form в строку возвращает HTML код для отображения формы. Обычно вам не нужно приводить форму явно, просто добавьте её в буфер отображения, например \IPS\Output::i()->output. \IPS\Output::i()->output .= $form; Добавление собственного CSS в форму По умолчанию форма горизонтальная. Чтобы сделать её вертикальной, или применить какой-либо класс, вы должны сделать следующее: $form->class = 'ipsForm_vertical'; Свойство class представляет собой простую строку (не массив), поэтому просто используйте список имен классов CSS, разделенных пробелами. Если вы используете свои собственные стили CSS, а не встроенные классы, не забудьте также добавить свой CSS файл! Использование шаблонов пользовательских форм По умолчанию для отображения формы используются стандартные встроенные шаблоны форм. Однако для дальнейшей настройки вы можете вызвать $form->customTemplate() передавая обратный вызов с шаблоном для использования. Это позволяет полностью настроить внешний вид формы. Это необходимо для использования шаблона, который выглядит лучше в модальном окне: \IPS\Output::i()->output = $form->customTemplate( array( call_user_func_array( array( \IPS\Theme::i(), 'getTemplate' ), array( 'forms', 'core' ) ), 'popupTemplate' ) ); Создаваемый шаблон должен содержать следующий заголовок шаблона, включая следующие параметры: <ips:template parameters="$id, $action, $elements, $hiddenValues, $actionButtons, $uploadField, $class='', $attributes=array(), $sidebar, $form=NULL" /> Передача пользовательских параметров Если вам нужно передать дополнительные настраиваемые параметры в шаблон формы, вы можете сделать это во втором параметре метода customTemplate, например: $templateToUse = array( call_user_func_array( array( \IPS\Theme::i(), 'getTemplate' ), array( 'forms', 'core' ) ), 'popupTemplate' ); $form->customTemplate( $templateToUse, $myCustomParameter, $anotherParameter ); Ваши параметры добавляются в начало списка параметров шаблона, то есть в этом случае заголовок вашего шаблона будет выглядеть следующим образом: <ips:template parameters="$myCustomParameter, $anotherParameter, $id, $action, $elements, $hiddenValues, $actionButtons, $uploadField, $class='', $attributes=array(), $sidebar, $form=NULL" />
  2. Назначение Помощника форм Большая часть пользовательского интерфейса в Invision Community содержит формы, будь то многочисленные страницы настроек в админцентре, публикация контента в фронтэнде, настройка профиля и многое другое. Invision Community имеет мощный класс Помощника формы, который упрощает внедрение форм в ваших приложениях и плагинах. Он предоставляет такие функции, как автоматическая проверка и встроенная безопасность, заботится о создании пользовательского интерфейса (в случае более сложных типов полей, таких как матрицы и селектор нод/деревьев) и динамического поведения для вас. Формы, созданные с помощью Помощника формы, поддерживают широкий диапазон типов полей, имеют встроенную поддержку вкладок, используют возможности HTML5, где это применимо, и многое другое. Если вам нужен ввод какой-либо информации от пользователей в вашем приложении или плагине, вы всегда должны использовать Помощник форм; никогда не реализуйте такую функциональность вручную и не обходите фреймворк. Основной фрагмент, показывающий, как в конечном итоге будет выглядеть код вашей формы: // Создать экземпляр формы $form = new \IPS\Helpers\Form; // Добавить поля формы $form->add( ... ); $form->add( ... ); if ( $values = $form->values() ) { // Форма отправлена; обрабатывайте значения формы здесь } // Отправить форму для вывода \IPS\Output::i()->output = $form; Создание формы Чтобы создать форму, вы просто создаете экземпляр из Помощника формы. К возвращенному объекту вы можете добавлять поля, вкладки и т.д. (описано в следующих разделах). // Создание формы с использованием значений по умолчанию $form = new \IPS\Helpers\Form; Никакие параметры не требуются, но есть несколько необязательных параметров, которые вы можете передать: \IPS\Helpers\Form( [ string $formID='form' [, string $submitLang='save' [, \IPS\Http\Url $actionURL=NULL [, array $attributes=array() ]]]] ); $formID (строка, необязательный) - Идентификатор для использования в HTML атрибуте id для этой формы. $submitLang (строка, необязательный) - Языковой ключ строки для использования в названии кнопки 'отправить'. $actionURL (\IPS\Http\Url, необязательный) - Объект URL-адреса, по которому должна быть отправлена форма (по умолчанию, формы отправляются на ту же страницу, которая их отображает). $attributes (массив, необязательный) - Массив ключ/значение других HTML атрибутов, которые вы хотели бы включить в тег <form>, например для функции javascript. Добавление элементов формы Добавление элемента формы выполняется методом $form->add(). Вы передаете ему объект элемента, который вы хотите - например, чтобы добавить текстовый ввод в свою форму, вы можете сделать следующее: $form->add( new \IPS\Helpers\Form\Text('name') ); Вы можете использовать широкий диапазон встроенных типов полей форм. Некоторые из доступных классов: \IPS\Helpers\Form\Text для обычного ввода текста. \IPS\Helpers\Form\Editor для ввода текста WYSIWYG. \IPS\Helpers\Form\Upload для загрузки файлов. \IPS\Helpers\Form\Date для дат. \IPS\Helpers\Form\Select для окна выбора. \IPS\Helpers\Form\YesNo для переключателей да/нет. Классы всех полей форм имеют похожий набор параметров. Каждый из них настраивается с помощью значений, которые вы передаете. Вот параметры, которые вы можете передать в классы полей форм: $name (строка, обязательный) - имя поля (используется в атрибуте имени в HTML). $defaultValue (mixed, необязательный) - стандартное значение поля, независимо от типа поля. $required (boolean, необязательный) - будет ли поле обязательным. Обратите внимание: передача true устанавливает HTML5 атрибут required, то есть форма не может быть отправлена, если она не заполнена. Передав NULL, вы отключите атрибут required, позволяя вместо этого проверять поле вручную на бэкэнд. $options (массив, необязательный) - Массив параметров. Допустимые значения зависят от типа поля; посмотрите документы по отдельным классам для получения дополнительной информации. $customValidationCode (функция, необязательный) - функция проверки значения поля. $prefix (строка, необязательный) - HTML строка для отображения перед полем HTML. $suffix (строка, необязательный) - HTML строка для отображения после поля HTML. $id (строка, необязательный) - Идентификатор, который будет использован в HTML атрибуте id. Для всех доступных классов, просмотрите файлы в директории system/Helpers/Form/. Значения, приемлемые для $options описаны в исходном коде каждого класса в директории. Имейте в виду, что некоторые классы расширяют другие (например, CheckboxSet расширяет Select и имеет те же $options). Например, чтобы создать окно с множественным выбором, вы должны сделать что-то вроде этого: $form->add( new \IPS\Helpers\Form\Select( 'my_select_box', NULL, TRUE, array( 'options' => array( 0 => 'Foo', 1 => 'Bar', 2=> 'Baz' ), 'multiple' => TRUE ) ) ); Метки и описания Свойство $name, в дополнение к имени, используемом для HTML поля, также используется для отображения метки (label). Помощник формы автоматически найдёт языковую строку с таким ключом, чтобы использовать её в качестве метки. Он также будет искать языковую строку с _desc для описания.Например, если $name для вашего поля - my_field, в качестве описания будет использоваться языковая строка my_field_desc. Если языковая строка с этим ключом не существует, описание не будет использоваться. Система также будет искать языковую строку с _warning для блока предупреждения (опять же, если строки не существует, не будет отображено). Обычно это всегда используется с переключателями (см. ниже), например, для отображения предупреждения, когда пользователь выбирает нежелательный вариант. В дополнение к меткам и описаниям с автоматическим использованием языковой строки, также можно переопределить это поведение и установить свои собственные значения в контроллере. Например: $input = new \IPS\Helpers\Form\Text( 'my_select_box', NULL, TRUE ); $input->description = "My Description"; $input->label = "My Label"; Важно отметить, что при установке описаний как данном случае, они будут добавлены точно такими же, как указаны, без дополнительной разметки. Если необходима разметка, вы должны установить свойство с помощью шаблона. Проверка Большинство классов будут автоматически проверять введённые данные, а параметр $options предоставляет способы настройки. Например, если вы создаёте элемент \IPS\Helpers\Form\Number, он будет автоматически проверен - является ли значение числом, и вы можете использовать $options для управления максимумом и минимумом вводимого числа вместе с количеством разрешенных десятичных знаков после точки. Система автоматически снова отобразит форму со встроенной ошибкой, если любой из элементов не пройдёт проверку, без необходимости предоставления дополнительного кода с вашей стороны. Однако, если вы хотите включить собственную проверку, вы можете сделать это с помощью свойства $customValidationCode - вы просто предоставляете метод обратного вызова, который генерирует исключение DomainException, если возникла ошибка. Например, если вы хотите сделать числовое поле, где число 7 не было разрешено, вы можете сделать это следующим образом: $form->add( new \IPS\Helpers\Form\Number( 'my_field', NULL, TRUE, array(), function( $val ) { if ( $val == 7 ) { throw new \DomainException('form_bad_value'); } } ) ); Обработка данных Когда ваша форма будет отправлена, $form->values() вернет массив со значениями каждого элемента (если форма не была отправлена или проверка не пройдена, она возвращает FALSE). Имейте в виду, что защита CSRF обрабатывается автоматически при использовании централизованного класса \IPS\Helpers\Form и будет показано сообщение об ошибке, если ключ CSRF не будет соответствовать ожидаемому значению. Значение, возвращаемое для каждого элемента, зависит от типа, а иногда и от параметров. Например, элемент \IPS\Helpers\Form\Text всегда возвращает строку в качестве значения. Однако \IPS\Helpers\Form\Number может вернуть целое число (int) или число с плавающей точкой (float). С другой стороны \IPS\Helpers\Form\Upload возвращает объект класса \IPS\File (или даже массив объектов, если это поле для загрузки нескольких файлов). Если вы предпочитаете получать только строковые значения (например, вы хотите сохранить значения как объект JSON), вы можете передать TRUE в метод $form->values(). Рекомендации Формы составляют большую часть пользовательского интерфейса в сообществе Invision Community. Важно представлять UI интерфейс как общую среду, согласующуюся с другими областями сайта. В связи с этим некоторые наши рекомендации: Всегда создавайте описание настроек положительно. Например, пишите "Включить функцию?" вместо "Отключить функцию?". Значение "Да" всегда должно означать, что и "Включить". Делайте метки короткими и понятными и используйте описания, если только оно необходимо. Например, для поля "Включить функцию?" не требуется добавлять описание в стиле "Установите значение в Да, чтобы включить функцию", т.к. это очевидно. Используйте префиксы и суффиксы, а не добавляйте информацию на ярлык или описание, где это возможно. Например, не используйте метку "Количество дней пред удалением" - сделайте метку более лаконичной - "Удалить после" и суффикс, который появится после поля - "дней". Никогда не обращайтесь в настройка в метках или описаниях. Например, не делайте такого описания "Применяется только, если настройка выше включена". Используйте переключатели для обозначения этого. Никогда не делайте указание определённого значения для какого-либо действия. Например, не делайте описание подобного этому "Оставьте поле пустым для неограниченного - используйте чекбокс "Неограниченно" или отдельную настройку, которая переключает другие настройки.
  3. 1. Создание e-mail шаблона Контент для e-mail сообщений хранится в директории dev/email приложения. Например, если посмотреть в директорию applications/core/dev/email (вам нужно находиться в режиме разработчика, чтобы увидеть эту папку), вы увидите все e-mail сообщения, отправляемые приложением core. Все e-mail сообщения, отправляемые Invision Community, могут быть в двух форматах: HTML (для большинства e-mail клиентов) и простой текст (для устаревших e-mail клиентов или пользователей, кто намеренно не желает получать письма в простом тексте). Для каждого отправляемого типа существует два файла key.phtml (содержит HTML версию письма) и key.txt (версия с простым текстом). Обратите внимание, что оба типа сообщений отправляются пользователю, и его почтовый клиент самостоятельно определит наиболее подходящий вариант для отображения. Для отправки собственных e-mail писем, вы должны создать оба варианта. Их ключи могут быть любыми, но уникальными. Первая строка обоих файлов должна быть тегом: <ips:template parameters="$parameter1, $parameter2, $email" /> Позже (на шаге 3), когда вы вызываете код для отправки своего e-mail письма, вы можете передать любые параметры, которые хотите использовать в ваших шаблонах. Внутри своих шаблонов вы можете использовать логику шаблонов и теги шаблонов, однако имейте ввиду, отправленное вами письмо, вероятно, будет с другим авторизованным пользователем при отправке сообщения, поэтому, поэтому не используйте ничего, что зависит от текущего авторизованного пользователя. И самое главное, не используйте тег шаблона {lang=""} (который всегда основывается на текущем авторизованном пользователе). Вместо этого вы можете получить использовать $email->language, являющийся объектом класса \IPS\Lang для правильного использования языка получателя. Также есть специальный тег {dir}, который также можно использовать в шаблоне. Это либо ltr, либо rtl, в зависимости от языка получателя и применяется (особенно для таблиц) для обеспечения правильного расположения e-mail письма для языка. Пример использования: <td dir='{dir}' valign='middle' align='center' style="..."> При создании своего шаблона HTML имейте в виду, что почтовые клиенты используют самые разные стандарты для браузеров, и многие обычные техники не могут быть использованы. Мы рекомендуем вам использовать шаблон из какого-либо приложения Invision Community в качестве основы, кроме того вы можете использовать такой инструмент, как Litmus. При создании шаблона с простым текстом, вы не должны использовать какие-либо HTML теги, а пробелы принимаются во внимание; то есть любые пробелы в шаблоне будут отображаться в письме. 2. Добавление языковой строки для темы письма Система будет автоматически искать языковую строку с ключом mailsub__<app>_<key>, чтобы использовать её в качестве темы, поэтому необходимо добавить её в файл dev/lang.php. Обратите внимание, что вы можете использовать параметры, которые вы передаете шаблону - например, в файле applications/core/dev/lang.php можно увидеть следующее: 'mailsub__core_notification_new_likes' => '{$member->name|raw} liked your post', 3. Отправка e-mail сообщения Фактический код для отправки электронной почты очень прост: \IPS\Email::buildFromTemplate( 'app', 'key', $params )->send( $member ); Метод send() может быть передан как объект \IPS\Member (это лучший способ, так как система будет автоматически настраивать e-mail для пользователя, включая выбор правильного языка) или e-mail адрес в виде строки (что вы должны сделать, если нужно отправить e-mail письмо незарегистрированным пользователям), или массив любого из них для отправки нескольким получателям. Вы также можете передавать второй и третий параметры для пользователей в CC (копия ) и BCC (скрытая копия) соответственно. Если вы хотите настроить контент сообщения в зависимости от пользователя, вы можете включить переменные в свой шаблон в формате *|key|* , а затем отправить так: <td> *|some_key|*<br> </td> PHP: \IPS\Email::buildFromTemplate( 'app', 'key', $params, TRUE )->mergeAndSend( array( 'user1@example.com' => array( 'some_key' => 'value for user 1', ), 'user2@example.com' => array( 'some_key' => 'value for user 2', ) ) );
  4. Создание расширения Первым шагом является создание расширения уведомлений. В Центре разработчика для вашего приложения перейдите на вкладку Extensions > Core и нажмите кнопку "+" справа от пункта Notifications. Будет создан файл в директории вашего приложения extensions/core/Notifications с изначальным скелетом. Откройте этот файл и следуйте инструкциям в нем, чтобы добавить свои типы уведомлений на страницу Настройки уведомлений и создать метод (-ы), который будет контролировать то, что будет отображено пользователю, когда он кликнет на иконку уведомлений в шапке сайта. Создание e-mail шаблона Вы должны создать e-mail шаблоны для тех случаев, когда пользователь включил возможность получать e-mail письма при получении уведомления. Следуйте инструкциям, приведенным в шагах 1-2 руководства по отправке e-mail сообщений. Для ваших шаблонов в качестве ключа используйте notification_key, где key это ключ уведомления, указанный вами в методе getConfiguration()). Например: тип уведомления new_status (в приложении core) использует e-mail шаблоны notification_new_status, которые для этого объекта используют строку языка mailsub__core_notification_new_status. Отправка уведомления Фактический код для отправки уведомления очень прост: $notification = new \IPS\Notification( \IPS\Application::load('app'), 'key', $item, $params ); $notification->recipients->attach( \IPS\Member::load(1) ); $notification->send(); $item - Должен быть объект того, о чём отправляется уведомление, что используется для предотвращения отправки одного и того же уведомления более одного раза или NULL, если это не применимо. Если это элемент контента (не обязательно, но будем так считать), уведомление автоматически удалит получателя, если у него нет разрешения на чтение элемента или игнорируется пользователь, который его опубликовал. $params - Любые параметры, которые вы хотите передать шаблону электронной почты. Вы вызываете $notification->recipients->attach() для каждого пользователя, которому хотите отправить уведомление, передавай объект \IPS\Member.
  5. Уведомления или e-mail? У вас есть несколько вариантов для отправки уведомлений своим пользователям: Подписка. Пользователи могут подписываться ну других пользователей, на контейнеры контента (например категории) и элементы контента (например темы), тем самым получая уведомления о контент, который их интересует. Уведомления - Пользователи могут настраивать способы уведомления о некоторых событиях (хочет ли он получать встроенное уведомление, письмо на e-mail или сразу оба способа уведомления) и вы можете отправлять им уведомления в соответствии с этими настройками. Например, уведомления отправляются, когда кто-то опубликует сообщение в профиле другого пользователя. Информацию о том, как это реализовать, смотрите ниже. E-mail - Вы также можете вручную отправить электронное письмо своему пользователю. Информацию о том, как это реализовать, смотрите ниже. Хотя все эти 3 системы взаимодействуют друг с другом, важно их не путать: система подписки отправляет уведомление, которое также может быть e-mail письмом. Вы также можете отправить уведомление, которое может быть электронным письмом, или вы можете просто отправить электронное письмо. Если вам нужно оповестить о чём-то пользователя, вы должны хорошо подумать о том, подходит ли уведомление или e-mail. Как правило, уведомления нужны для того, чтобы сообщить пользователю о том, что произошло то, что ему может быть интересно (Например, уведомления отправляются, когда кто-то опубликует сообщение в профиле другого пользователя), а e-mail письма лучше всего подходят для вещей, которые отвечают конкретному действию, или требуют действия от самого пользователя (например, отправляется e-mail письмо, когда отправляется товар, купленный пользователем в Коммерции).
  6. invisionbyte

    Дата и время

    Обработка даты и времени является важной функцией программного обеспечения, а класс \IPS\DateTime предоставляет несколько методов, которые помогают надежно обрабатывать даты и время. Важно отметить, что класс \IPS\DateTime расширяет встроенный PHP DateTime класс, поэтому все общие методы PHP для работы с датами и временем также доступны через этот интерфейс. Дата и время представлены в базе данных в виде UNIX-времени (timestamp). Однако, когда вы показываете дату пользователю, нам нужно преобразовать UNIX-время в удобную для чтения дату и время, локализованные в часовом поясе пользователя. Для этой цели можно использовать статический метод ts(): $time = \IPS\DateTime::ts( $timestamp ); Вы также можете использовать статический метод create() для создания нового экземпляра datetime (который будет по умолчанию использовать текущую дату/время). $time = \IPS\DateTime::create(); Основные методы, которые вы будете использовать для отображения даты и/или времени, следующие: /* Показывает время и дату в часовом поясе пользователя */ print (string) $time; Магический метод __toString() автоматически позаботится о преобразованиях часового пояса и т.д. /* Вывод HTML тега <time> HTML с отображением относительного времени */ print $time->html( TRUE, FALSE, NULL ); Первый параметр определяет, должна ли дата/время быть в формате capitalize (первый символ каждого слова будет заглавным; остальные символы свой вид не меняют) или нет (установите его в значение FALSE, если время будет использоваться в середине предложения, например), а второй параметр определяет, будет ли использоваться 'короткая' версия дата/время, даже не на мобильном устройстве (например 1д вместо 1 день). Последний параметр позволяет переопределить пользователя или язык для форматирования времени. /* Показывать только дату */ print $time->localeDate(); /* Показывать только время - первый параметр указывает, следует ли возвращать секунды, а второй параметр указывает, следует ли возвращать минуты */ print $time->localeTime( TRUE, TRUE ); /* Возвращает только месяц и день, без указания года (или времени) print $time->dayAndMonth(); /* Возвращает дату с 4-х значным годом */ print $time->fullYearLocaleDate(); /* Форматирует относительную дату/время */ print $time->relative( \IPS\DateTime::RELATIVE_FORMAT_NORMAL ); Для метода relative() распознаются следующие константы: RELATIVE_FORMAT_NORMAL: Вчера в 2 часа. RELATIVE_FORMAT_LOWER: вчера в 2 часа (например "Изменено вчера в 2 часа"). RELATIVE_FORMAT_SHORT: 1д (для мобильных устройств). Если вам нужно использовать полностью настраиваемый формат, вы можете использовать метод strFormat(). Хотя класс DateTime в PHP уже имеет встроенный метод format(), но он не понимает локали, поэтому используется метод strFormat() (который принимает любой формат, принятый strftime в PHP). print $time->strFormat( '%B' ); Наконец, есть некоторые стандартизированные форматы, которые поддерживаются что называется "из коробки", в первую очередь полезны, когда спецификации требуют, чтобы даты были отформатированы определенным образом (например, RSS): print $time->rfc3339(); // 2017-06-06T11:00:00Z print $time->rfc1123(); // Вторник, 6 Июня 2017 11:00:00 GMT Важно помнить при кешировании данных, что даты и время должны быть локализованы на основе текущего часового пояса пользователя (который определяется автоматически). По этой причине вы не должны кэшировать отформатированные даты и время, но можете форматировать при отображении. Наконец, существует плагин шаблона "datetime", который можно использовать для автоматического форматирования дат и времени в шаблонах. {datetime="$timestamp"} Это отобразит локализованную дату и время из вызова __toString(). Дополнительные атрибуты, поддерживаемые этим плагином: dateonly: Вернуть только дату. norelative: Не возвращать относительную дату. lowercase: Вернуть дату в нижнем регистре. short: Вернуть короткую форму даты.
  7. invisionbyte

    Запрос данных

    Invision Community имеет класс для работы с данными запроса, включая данные GET, POST, и REQUEST, куками и обнаружение определенной информации о запросе (например, были ли они отправлены через AJAX или нет). Вам нужно будет использовать этот класс для выполнения некоторых общих действий, работающих с программным обеспечением. Класс доступен с помощью \IPS\Requst::i() и реализует паттерн Одиночка (Singleton). Данные GET, POST и REQUEST Чтобы получить доступ к переменным запроса, вы просто вызываете их как свойства класса. Например, вы можете проверить, установлена ли переменная запроса и вывести её таким образом: if( isset( \IPS\Request::i()->someVariable ) ) { print \IPS\Request::i()->someVariable; } Данные запроса в основном не изменены из первоначально представленных данных, за исключением того, что нулевые байты и символы управления RTL удаляются из ввода, и удалены слэши, если включены магические кавычки. Это означает, что все данные запроса считаются потенциально зараженными, и вам нужно будет принять меры предосторожности, чтобы не создать проблемы в безопасности, полагаясь на 'чистые' данные запроса этого класса. Если запрос выполняется с использованием метода PUT (например в REST API в некоторых случаях), эти данные запроса также доступны через этот класс. Работа с cookie Значения Cookie доступны в свойстве cookie класса \IPS\Request. print \IPS\Request::i()->cookie['member_id']; Если ваш сайт использует префикс cookie, обратите внимание, что здесь он будет автоматически удалён. Чтобы установить cookie, вы можете использовать метод setCookie. Как и при извлечении cookie, вы не должны включать префикс cookie, который используется. /** * Set a cookie * * @param string $name Name * @param mixed $value Value * @param \IPS\DateTime|null $expire Expiration date, or NULL for on session end * @param bool $httpOnly When TRUE the cookie will be made accessible only through the HTTP protocol * @param string|null $domain Domain to set to. If NULL, will be detected automatically. * @param string|null $path Path to set to. If NULL, will be detected automatically. * @return bool */ public function setCookie( $name, $value, $expire=NULL, $httpOnly=TRUE, $domain=NULL, $path=NULL ) Обычно вы должны оставить $domain и $path как NULL, однако при необходимости они могут быть переопределены, например, если вы работаете над интеграцией с сторонним сервисом. Вы можете очистить все cookies авторизации с помощью метода \IPS\Request::i()->clearLoginCookies(), если необходимо, включая member_id и pass_hash, а также любые cookies пароля (где пользователь может иметь введённый пароль для доступа к форуму). Другие вспомогательные методы В классе \IPS\Request есть несколько вспомогательных методов, которые можно использовать при необходимости для проверки различных свойств запроса: \IPS\Request::i()->isAjax() - Возвращает логическое значение true или false, указывающее, был ли запрос выполнен через AJAX. \IPS\Request::i()->isSecure() - Возвращает логическое значение true или false, указывающее, был ли запрос выполнен через SSL (https). \IPS\Request::i()->url() - Возвращает объект \IPS\Http\Url, представляющий запрошенный URL-адрес. Обратите внимание, что фрагменты (значения после символа хеша в URL-адресе) не отправляются на сервер и не будут доступны для проверки на уровне сервера. \IPS\Request::i()->ipAddress() - Возвращает IP-адрес, используемый при выполнении текущего запроса, с учетом с учетом прокси-серверов и перенаправления, если администратор решил сделать это в админцентре. \IPS\Request::i()->ipAddressIsBanned() - Возвращает логическое значение true или false, указывающее, забанен ли текущий IP-адрес запроса в бан-фильтре IP-адресов в админцентре. \IPS\Request::i()->requestMethod() - Возвращает текущий метод запроса, в верхнем регистре. \IPS\Request::i()->isCgi() - Возвращает логическое значение true или false, указывающее, обрабатывается ли текущий запрос CGI-оболочкой в PHP. \IPS\Request::i()->floodCheck() - Проверяет настройку поискового флуда пользователя , чтобы определить, искал ли что-то пользователь в последнее время и что пользователь снова ищет через короткий промежуток времени. Если пользователь недавно выполнил поиск и этот метод вызывается до того, как завершился период времени контроля флуда, пользователю будет показана ошибка, в противном случае его время последнего поиска обновляется до текущего времени для последующих проверок. \IPS\Request::i()->confirmedDelete( $title, $message, $submit ) - Когда пользователь удаляет данные, разумно утверждать, что действие было предпринято осознано, а не случайно. Чтобы облегчить это, вы можете вызвать метод confirmedDelete(), который проверит подтвердил ли пользователь удаление контента, и если нет, покажет сначала скрин подтверждения.
  8. invisionbyte

    URL-адреса

    Фреймворк Invision Community предоставляет мощный вспомогательный класс для работы с URL-адресами, включая парсинг адресов и создание запросов (так же чтение ответов) URL-адресов. Программное обеспечение автоматически использует cURL, если доступно, и обратно возвращается к стандартным сокетам (это поведение также может быть переопределено константами, если среда хочет принудительно использовать cURL или сокеты). Работа с URL-адресами Класс \IPS\Http\Url используется для работы с URL-адресами, а два вспомогательных метода образуют основной интерфейс для создания объекта URL с этим классом: internal(): Используйте этот метод при создании внутреннего URL-адреса, например URL-адрес форума или темы. Этот метод автоматически создаёт дружественные URL-адреса, если необходимо. external(): Передайте полный URL-адрес этому методу для создания объекта URL-адреса из строки URL-адреса. // Создание URL-адреса на тему с ID = 1 $url = \IPS\Http\Url::internal( 'app=forums&module=forums&controller=topic&id=1', 'front', 'forums_topic', array( 'topic-friendly-slug' ) ); $url = \IPS\Http\Url::external( 'https://www.google.com' ); // Создание объекта URL для стандартной строки URL Внутренний метод принимает следующие параметры: Строка запроса URL-адреса. 'база' ('front' или 'admin', в зависимости от того, является ли URL-адрес на страницу админцентра или нет). SEO шаблон, если применимо. Массив SEO слагов, если шаблон их вызывает. Константу PROTOCOL_* из класса \IPS\Http\Url для переопределения должен ли быть сгенерирован http или https URL-адрес. Вы можете опустить этот параметр и позволить программному обеспечению правильно определить протокол, который будет использоваться автоматически. Внешний метод просто принимает строку URL-адреса. Если вы не уверены, что объект URL, который вы создаете, является внутренним или внешним, вы можете альтернативно использовать метод createFromString() (передавая полный URL-адрес так же, как и с помощью метода external()), однако обратите внимание, что этот метод является ресурсоёмким по производительности и предпочтительны непосредственно методы internal() и external(). Первым параметром для этого метода является URL-адрес, второй параметр - логический флаг, указывающий, может ли URL-адрес являться дружественным внутренним URL-адресом, а третий и последний параметр - логическим флагом, указывающим, хотите ли вы автоматически кодировать любые недопустимые компоненты вместо того, чтобы бросать ошибку (по умолчанию FALSE - установите значение TRUE, если URL-адрес предоставлен пользователем и не должен выдавать ошибку). Вы можете внести корректировки в URL-адрес после создания объекта URL-адреса, вызвав различные методы. setScheme(): Вы можете передать схему в (то есть http или https), или передать в NULL для использования относительной схемы (то есть без схемы вовсе). setHost(): Принимает полное имя хоста. setPath(): Принимает полный допустимый путь. setQueryString(): Принимает ключ строки запроса в качестве первого параметра и его значение как второй параметр ИЛИ массив пар ключ => значение в качестве первого параметра. setFragment(): Принимает фрагмент. stripQueryString(): Принимает ключ строки запроса или массив ключей скроки запроса и удаляет эти параметры строки запроса (если есть) из URL-адреса. Когда вы хотите вывести URL-адрес, вы можете использовать объект \IPS\Http\Url как строку: print (string) $urlObject; Класс имеет несколько дополнительных свойств и методов, на которые вы, возможно, захотите ссылаться или вызывать, описанные ниже: isInternal: свойство указывает, является ли URL-адрес внутренним или нет. isFriendly: свойство указывает, является ли URL-адрес дружественным (внутренним) URL-адресом или нет. queryString: свойство является массивом ключ => значение параметров строки запроса в URL-адресе. hiddenQueryString: свойство является массивом ключ => значение параметров строки запроса, которые были бы, если URL-адрес не был дружественным URL-адресом. Например, если вы создаете внутренний дружественный объект URL, это свойство будет содержать связанные параметры строки запроса, которые не отображаются (поскольку используется дружественный URL-адрес). csrf(): Вызовите этот метод, чтобы добавить ключ CSRF текущего пользователя в URL-адрес как аргумент строки запроса. Затем это будет проверено контроллерами для предотвращения атак типа CSRF. Если у вас есть запрос на изменение состояния, который не использует класс \IPS\Helpers\Form, обычно должны проверять ключ CSRF. (static) seoTitle(): Вы можете вызвать этот метод, чтобы создать допустимый дружественный URL слаг. Обычно это используется, когда контент уже добавлен и URL слаг сохранён для следующего обращения, однако вы можете также вызывать этот метод «на лету», если это необходимо. Создание запросов Создав объект класса \IPS\Http\Url, вы можете делать запросы к нему. Для этого вызывается метод request(). /** * Make a HTTP Request * * @param int|null $timeout Timeout * @param string $httpVersion HTTP Version * @param bool|int $followRedirects Automatically follow redirects? If a number is provided, will follow up to that number of redirects * @return \IPS\Http\Request */ public function request( $timeout=null, $httpVersion=null, $followRedirects=5 ) Он возвращает объект \IPS\Http\Request. Ниже приведены некоторые методы, которые вы можете вызвать перед выполнением запроса: login(): Принимает имя пользователя в качестве первого параметра и пароль в качестве второго параметра и выполняет основной запрос авторизации по URL. setHeaders(): Принимает массив пар ключ => значение заголовков, которые должны быть включены в запрос. sslCheck(): Принимает логическое значение true или false как единственный параметр, сигнализирующий, должны ли проверяться SSL сертификаты или нет. В большинстве случаев это должно быть оставлено по умолчанию (true), если только вы не знаете, что SSL URL-адрес, к которому вы делаете запрос, имеет недопустимый сертификат. forceTls(): Обязать TLS для запроса. Это прежде всего используется с некоторыми платежными шлюзами, которые обеспечивают выполнение запросов TLS. Впоследствии вы можете сделать запрос. Для этого вы вызываете метод запроса, который хотите выполнить (например для выполнения GET запроса, нужно вызвать метод get(), для PUT запроса соответственно put()), передавая любые параметры, которые должны быть включены в запрос (для запросов POST и PUT). $request = \IPS\Http\Url::external( "http://someurl.com" )->request()->get(); Это возвращает объект \IPS\Http\Response, который вы можете теперь проверять и манипулировать по мере необходимости. Во-первых, есть несколько полезных свойств, которые вам могут потребоваться: httpResponseVersion: Версия протокола HTTP запроса (1.0 или 1.1, обычно). httpResponseCode: Код ответа HTTP. Возможно, вам потребуется проверить, что после запроса был возвращен действительный код ответа (т.е. 200). httpResponseText: Это текст ответа HTTP. Например, для запроса 200 это будет "ОК". httpHeaders: Массив, содержащий все HTTP заголовки ответа в виде пар ключ => значение. cookies: Массив всех заголовков Set-Cookie в виде пар ключ => значение. content: Тело ответа. Отправка ответа в виде строки возвращает свойство содержимого, указанное выше. В классе \IPS\Http\Response есть несколько методов, которые можно использовать, чтобы упростить работу с некоторыми распространенными ответами. decodeJson(): Вызов этого метода запустит ответ через json_decode перед его возвратом. Если ответ не в формате JSON, будет выброшено исключение RuntimeException. decodeXml(): Вызов этого метода спарсит ответ как XML, если ответ не в формате XML, будет выброшено исключение RuntimeException. Кроме того, стоит отметить, что если запрос по какой-либо причине даёт сбой (например, тайм-аут подключения к удалённому серверу), выбрасывается исключение \IPS\Http\Request\Exception. С этой целью вы должны оборачивать запросы в блоки try/catch. // Create a URL object $url = \IPS\Http\Url::external( "http://someurl.com" )->setQueryString( 'key', 'value' ); // Построение и декодирование с помощью JSON try { $response = $url->request()->get()->decodeJson(); } catch( \IPS\Http\Request\Exception $e ) { die( "There was a problem fetching the request" ); } catch( \RuntimeException $e ) { die( "The response was not valid JSON" ); } var_dump( $response ); exit;
  9. invisionbyte

    Модели

    В приложении MVC модель отвечает за взаимодействие с данными и передачу их контроллеру. То же самое и в Invision Community. Вообще говоря, экземпляр модели относится к предмету. Например, если бы у вас были форумы и темы, Форум был бы модель, как и Тема. Модель для каждого из них предоставляет методы, позволяющие взаимодействовать с ними. При разработке моделей для вашего приложения перечислите, с чем работает ваше приложение, - это, скорее всего, и будут ваши модели. Название и местоположение Название модели всегда должно быть существительным в единственном числе; то есть модель всегда относится к одной вещи. Названия моделей так же должны быть в формате PascalCase. Модели расположены в директории /sources вашего приложения. Как обсуждалось в документе Автозагрузка классов, в этой директории должны быть подпапку с таким же названием, как и ваша модель, а сама модель должна находится в данной поддиректории (вместе с любыми поддерживающими модулями). /sources/topic/topic.php - некорректно: директория/модель в нижнем регистре. /sources/Topics/Topics.php - некорректно: множественное имя модели /sources/Topic/Topic.php - Корректно Еще раз обращаясь к руководству по автозагрузке, имя класса в файле PHP должно иметь префикс с подчеркиванием. Например, если ваш файл был назван Topic.php, класс модели, который он содержит, должен называться _Topic. Базовые модели Существует несколько базовых моделей, которые часто будут расширять ваши модели. Каждый из них будет рассмотрен более подробно - включая полный обзор методов, которые они предоставляют - в соответствующих разделах в этой документации. Базовыми являются: \IPS\Node\Model - Методы для работы с нодами, древовидная структура, применимая для категорий (и многое другое). \IPS\Content\Item - Методы для работы с элементами контента, например, темы, изображения галереи. \IPS\Content\Comment - Методы для работы с комментариями (включая сообщения форумов). \IPS\Content\Review - Методы для работы с отзывами. Эти четыре базовые модели реализуют паттерн Active Record в Invision Community. Пример: /exampleApp/sources/Counter/Counter.php Очень простая автономная модель, которая предоставляет метод для хранения и увеличения числа. <?php namespace IPS\exampleApp; class _Counter { protected $counter = 0; public function incrementCounter () { $this->counter++; } } /exampleApp/modules/front/example/index.php Контроллер, который создает экземпляр вышеуказанной модели, затем вызывает метод incrementCounter, который он предоставляет. namespace IPS\exampleApp\modules\front\example; class _index extends \IPS\Dispatcher\Controller { public function manage() { $myCounter = new \IPS\exampleApp\Counter(); $myCounter->incrementCounter(); } }
  10. Доступ к базе данных для записи и выборки данных является необходимостью почти всех приложений и плагинов, которые интегрируются с Invision Community. Класс \IPS\Db обрабатывает соединения с базой данных и расширяет стандартный класс mysqli в основной библиотеке PHP. Подключение к базе данных Стандартное соединение с базой данных (обозначенное деталями подключения в файле conf_global.php) может быть установлено автоматически с помощью вызова метода \IPS\Db::i(). Если соединение еще не было установлено, это будет сделано немедленно на лету, когда будет вызван этот метод. Стандартное соединение использует utf8 (или utf8mb4 в зависимости от вашей конфигурации), и все таблицы и столбцы базы данных должны быть настроены на utf8. Это обычно обрабатывается Invision Community, но об этом всё равно важно знать и помнить! Если вам нужно установить соединение с удаленной базой данных, это можно сделать, передав параметры методу i() класса \IPS\Db. Первый параметр - произвольный идентификатор строкового соединения, а второй параметр - массив с настройками соединения. $connection = \IPS\Db::i( 'external', array( 'sql_host' => 'localhost', 'sql_user' => 'username', 'sql_pass' => 'password', 'sql_database' => 'database_name', 'sql_port' => 3306, 'sql_socket' => '/var/lib/mysql.sock', 'sql_utf8mb4' => true, ) ); Вам нужно только указать параметры, необходимые для вашего подключения. Вы также можете автоматически поддерживать разделение чтения и записи, передавая те же параметры во второй раз с префиксом «sql_read_» вместо «sql_», указывая на ваш экземпляр MySQL только для чтения. Выборка данных Выборка данных из базы данных является одной из наиболее распространенных задач при взаимодействии с базой данных. /** * Build SELECT statement * * @param array|string $columns The columns (as an array) to select or an expression * @param array|string $table The table to select from. Either (string) table_name or (array) ( name, alias ) or \IPS\Db\Select object * @param array|string|NULL $where WHERE clause - see \IPS\Db::compileWhereClause() for details * @param string|NULL $order ORDER BY clause * @param array|int $limit Rows to fetch or array( offset, limit ) * @param string|NULL|array $group Column(s) to GROUP BY * @param array|string|NULL $having HAVING clause (same format as WHERE clause) * @param int $flags Bitwise flags * @li \IPS\Db::SELECT_DISTINCT Will use SELECT DISTINCT * @li \IPS\Db::SELECT_SQL_CALC_FOUND_ROWS Will add SQL_CALC_FOUND_ROWS * @li \IPS\Db::SELECT_MULTIDIMENSIONAL_JOINS Will return the result as a multidimensional array, with each joined table separately * @li \IPS\Db::SELECT_FROM_WRITE_SERVER Will send the query to the write server (if read/write separation is enabled) * @return \IPS\Db\Select * */ public function select( $columns=NULL, $table, $where=NULL, $order=NULL, $limit=NULL, $group=NULL, $having=NULL, $flags=0 ) Вы можете вызвать метод select() для выполнения SELECT запроса к вашей базе данных. Метод возвращает \IPS\Db\Select объект, который позволяет вам в дальнейшем усовершенствовать SELECT запрос. Например, в этом классе есть методы, позволяющие принудительно использовать определенный индекс, делать JOIN запросы к другим таблицам и указывать, какие поля ключ/значение использовать для результатов. // Получить объект выборки $select = \IPS\Db::i()->select( '*', 'some_table', array( 'field=?', 1 ), 'some_column DESC', array( 0, 10 ) ); // Использовать указанный индекс для запроса $select = $select->forceIndex( 'some_index' ); // Присоединить выборку из другой таблицы $select = $select->join( 'other_table_name', 'other_table_name.column=some_table.column', 'LEFT' ); // Теперь вернем количество полученных результатов $results = count( $select ); // Сообщить итератору, что ключ должны быть столбцом 'column_a', а значения 'column_b' $select = $select->setKeyField( 'column_a' )->setValueField( 'column_b' ); // Наконец, перейдем к результатам foreach( $select as $columnA => $columnB ) { print $columnA . ': ' . $columnB . '<br>'; } Здесь есть некоторые важные моменты. Параметр WHERE принимает много разных форматов, о которых вы должны знать. Вы можете передать строку в качестве оператора WHERE some_column='some value', или вы можете передать массив с первым элементом WHERE, используя ? в качестве плейсхолдеров для значений, а затем каждый плейсхолдер заменяется на последующие записи массива. Это использует подготовленные операторы в MySQL, чтобы избежать проблем с SQL-инъекциями и это рекомендуется array( 'some_column=? OR some_column=?', 'first value', 'second value' ), или, наконец, вы можете передать массив операторов, которые будут объединены вместе AND array( array( 'some_column=?', 'test value' ), array( 'other_column=?', 1 ) ). Вы можете вызвать setKeyField() без вызова setValueField(). Вместо значения, являющегося строкой в этом случае, это будет просто массив всех выбранных столбцов (или если выбран только один столбец, значение будет строкой с значением этого столбца). Обратите внимание, что вы должны выбрать столбцы, которые вы хотите использовать для setKeyField и/или setValueField. Определение метода для join() требует, чтобы первый параметр был название таблицы, к которой вы хотите присоединить данные, затем оператор 'on', затем тип присоединения (по умолчанию LEFT). Вы также можете использовать оператор для присоединения данных в качестве четвёртого параметра, если необходимо. Для контролирования по каким столбцам сделать выборку, вы должны изменить первый параметр оператора SELECT (если вы передаёте '*' MySQL вернёт все столбцы из всех таблиц, выбранных из и/или присоединения). \IPS\Db\Select реализует Iterator и Countable. Это означает, что вы можете рассматривать его как массив и использовать цикл foreach() для обработки результатов, а также вы можете вызвать count() для объекта, чтобы получить количество результатов. Помните, однако, что count() по умолчанию только возвращает количество результатов, возвращаемых запросом. Если у вас 1000 строк в таблице и вы используйте оператор limit, чтобы возвращать только 100 результатов, тогда count() покажет 100. Если вы хотите получить общее количество строк в таблице, как буд-то оператор limit не используется, вы можете передать флаг \IPS\Db::SELECT_SQL_CALC_FOUND_ROWS в стандартный метод select(), как отмечено блоком phpdoc выше. Часто вы выбираете только одну строку (то есть при выполнении запроса COUNT(*)), встроенный метод first() облегчает это. Однако имейте в виду, что если строка не существует, генерируется исключение UnderflowException, поэтому вы должны перенести такие запросы в оператор try/catch. try { $row = \IPS\Db::i()->select( '*', 'table', array( 'id=?', 2 ) )->first(); } catch( \UnderflowException $e ) { // В таблице нет строки с id = 2 } Вставка, обновление и удаление строк Вы также захотите периодически вставлять, обновлять и удалять строки в MySQL. Для этого вы можете использовать соответствующие методы insert(), update() и delete(). // Вставить строку $new_id = \IPS\Db::i()->insert( 'some_table', array( 'column_one' => 'value', 'column_two' => 'value2' ) ); // Обновить эту строку \IPS\Db::i()->update( 'some_table', array( 'column_two' => 'other value' ), array( 'id_column=?', $new_id ) ); // Удалить строку \IPS\Db::i()->delete( 'some_table', array( 'id_column=?', $new_id ) ); Первым параметром метода добавления строки является имя таблицы, далее следует ассоциативный массив названий столбцов => значения. Метод возвращает новый автоинкрементный (если применимо) ID. Обратите внимание, что существует также метод replace(), который ведет себя как insert(), только будет выполнено запрос REPLACE INTO вместо INSERT INTO (в этом случае, если встречается повторяющийся уникальный индекс, оригинал будет заменен новой строкой). Метод update() ожидает, что первым параметром будет имя таблицы, второй параметр будет ассоциативным массивом имен столбцов => значений, а третьим параметром будет оператор WHERE (если необходимо). Кроме того, при необходимости вы можете передать массив присоединений таблиц (оператор JOIN) в качестве четвёртого параметра, если он необходим, массив, представляющий оператор limit как пятый параметр и флаги для изменения запроса в качестве последнего параметра, в том числе: \IPS\Db::LOW_PRIORITY Использует LOW_PRIORITY \IPS\Db::IGNORE Использует IGNORE Метод delete() обычно вызывается только с первым параметром, именем таблицы, для удаления всей таблицы, а также со вторым параметром оператором where для удаления определенных строк. Метод дополнительно принимает третий параметр для управления упорядочивания результатов для запроса DELETE, четвёртый параметр для ограничения количества результатов удаления, и пятый столбце, который указывает столбец оператора, если оператор WHERE является оператором. О структуре базы данных Вы можете создавать таблицы базы данных, добавлять, изменять и удалять столбцы из существующих таблиц, изменять и удалять индекс из существующих таблиц с помощью библиотеки \IPS\Db. Кроме того, существуют методы, позволяющие определить, существует ли таблица, столбец или индекс, прежде чем использовать его. /** * Существует ли таблица? * * @param string $name Table Name * @return bool */ public function checkForTable( $name ) /** * Существует ли столбец? * * @param string $name Table Name * @param string $column Column Name * @return bool */ public function checkForColumn( $name, $column ) /** * Существует ли индекс? * * @param string $name Table Name * @param string $index Index Name * @return bool */ public function checkForIndex( $name, $index ) /** * Создать таблицу * * @code \IPS\Db::createTable( array( 'name' => 'table_name', // Table name 'columns' => array( ... ), // Column data - see \IPS\Db::compileColumnDefinition for details 'indexes' => array( ... ), // (Optional) Index data - see \IPS\Db::compileIndexDefinition for details 'comment' => '...', // (Optional) Table comment 'engine' => 'MEMORY', // (Optional) Engine to use - will default to not specifying one, unless a FULLTEXT index is specified, in which case MyISAM is forced 'temporary' => TRUE, // (Optional) Will sepcify CREATE TEMPORARY TABLE - defaults to FALSE 'if_not_exists' => TRUE, // (Optional) Will sepcify CREATE TABLE name IF NOT EXISTS - defaults to FALSE ) ); * @endcode * @param array $data Table Definition (see code sample for details) * @throws \IPS\Db\Exception * @return void|string */ public function createTable( $data ) /** * Создать копию структуры таблицы * * @param string $table The table name * @param string $newTableName Name of table to create * @throws \IPS\Db\Exception * @return void|string */ public function duplicateTableStructure( $table, $newTableName ) /** * Переименовать таблицу * * @see <a href='http://dev.mysql.com/doc/refman/5.1/en/rename-table.html'>Rename Table</a> * @param string $oldName The current table name * @param string $newName The new name * @return void * @see <a href='http://stackoverflow.com/questions/12856783/best-practice-with-mysql-innodb-to-rename-huge-table-when-table-with-same-name-a'>Renaming huge InnoDB tables</a> * @see <a href='http://www.percona.com/blog/2011/02/03/performance-problem-with-innodb-and-drop-table/'>Performance problem dropping huge InnoDB tables</a> * @note A race condition can occur sometimes with InnoDB + innodb_file_per_table so we can't drop then rename...see above links */ public function renameTable( $oldName, $newName ) /** * Изменить таблицу * Можно обновлять комментарии и движок * @note This will not examine key lengths and adjust. * * @param string $table Table name * @param string|null $comment Table comment. NULL to not change * @param string|null $engine Engine to use. NULL to not change * @return void */ public function alterTable( $table, $comment=NULL, $engine=NULL ) /** * Удалить таблицу * * @see <a href='http://dev.mysql.com/doc/refman/5.1/en/drop-table.html'>DROP TABLE Syntax</a> * @param string|array $table Table Name(s) * @param bool $ifExists Adds an "IF EXISTS" clause to the query * @param bool $temporary Table is temporary? * @return mixed */ public function dropTable( $table, $ifExists=FALSE, $temporary=FALSE ) /** * Добавить столбец в таблицу в базе данных * * @see \IPS\Db::compileColumnDefinition * @param string $table Table name * @param array $definition Column Definition (see \IPS\Db::compileColumnDefinition for details) * @return void */ public function addColumn( $table, $definition ) /** * Изменить существующий столбец * * @see \IPS\Db::compileColumnDefinition * @param string $table Table name * @param string $column Column name * @param array $definition New column definition (see \IPS\Db::compileColumnDefinition for details) * @return void */ public function changeColumn( $table, $column, $definition ) /** * Удалить столбец * * @param string $table Table name * @param string|array $column Column name * @return void */ public function dropColumn( $table, $column ) /** * Добавить индекс в таблицу в базе данных * * @see \IPS\Db::compileIndexDefinition * @param string $table Table name * @param array $definition Index Definition (see \IPS\Db::compileIndexDefinition for details) * @param bool $discardDuplicates If adding a unique index, should duplicates be discarded? (If FALSE and there are any, an exception will be thrown) * @return void */ public function addIndex( $table, $definition, $discardDuplicates=TRUE ) /** * Изменить существующий индекс * * @see \IPS\Db::compileIndexDefinition * @param string $table Table name * @param string $index Index name * @param array $definition New index definition (see \IPS\Db::compileIndexDefinition for details) * @return void */ public function changeIndex( $table, $index, $definition ) /** * Удалить индекс * * @param string $table Table name * @param string|array $index Column name * @return mixed */ public function dropIndex( $table, $index ) Большинство из этих методов описаны в phpdoc и редко используются, за исключением случаев использования центра разработчика для добавления запросов на обновлений. Разное Наконец, в классе есть несколько методов и свойств, которые могут оказаться полезными или актуальными при работе с драйвером базы данных. Если вам нужно получить префикс базы данных, используемый у таблиц (он же sql_tbl_prefix в conf_global.php), вы можете сделать это, вызвав \IPS\Db::i()->prefix . Если вы создаете запросы для запуска вручную, вам нужно будет добавить его к именам ваших таблиц. Если вам нужно построить SQL оператор и вернуть её вместо запуска, вы можете установить \IPS\Db::i()->returnQuery = TRUE перед вызовом драйвера для построения запроса. Для запуска MySQL запроса, который был полностью построен и представляет из себя строку, вы можете можете вызвать метод query(). Например: \IPS\Db::i()->query( "UPDATE some_table SET field_a='value' WHERE id_field=1" ); Обычно вам следует избегать непосредственного использования метода query(), поскольку другие встроенные методы автоматически обрабатывают такие вещи, как экранирование значений, добавление префикса таблицы базы данных и т.д. Если вам нужно создать инструкцию UNION, для облегчения этого метода также существует способ. /** * Построение инструкции UNION * * @param array $selects Array of \IPS\Db\Select objects * @param string|NULL $order ORDER BY clause * @param array|int $limit Rows to fetch or array( offset, limit ) * @param string|null $group Group by clause * @param bool $unionAll TRUE to perform a UNION ALL, FALSE (default) to perform a regular UNION * @param int $flags Bitwise flags * @param array|string|NULL $where WHERE clause (see example) * @param string $querySelect Custom select for the outer query * @li \IPS\Db::SELECT_SQL_CALC_FOUND_ROWS Will add SQL_CALC_FOUND_ROWS * @return \IPS\Db|Select */ public function union( $selects, $order, $limit, $group=NULL, $unionAll=FALSE, $flags=0, $where=NULL, $querySelect='*' ) Для построения оператора FIND_IN_SET(), который позволяет запросу искать определенные значения в поле MySQL, которое содержит значения, разделенные запятыми, вы можете использовать метод findInSet(). /** * FIND_IN_SET * Generates a WHERE clause to determine if any value from a column containing a comma-delimined list matches any value from an array * * @param string $column Column name (which contains a comma-delimited list) * @param array $values Acceptable values * @param bool $reverse If true, will match cases where NO values from $column match any from $values * @return string Where clause * @see \IPS\Db::in() More efficient equivilant for columns that do not contain comma-delimited lists */ public function findInSet( $column, $values, $reverse=FALSE ) Аналогичным образом вы можете построить оператор IN() с помощью метода in(): /** * IN * Generates a WHERE clause to determine if the value of a column matches any value from an array * * @param string $column Column name * @param array $values Acceptable values * @param bool $reverse If true, will match cases where $column does NOT match $values * @return string Where clause * @see \IPS\Db::findInSet() For columns that contain comma-delimited lists */ public function in( $column, $values, $reverse=FALSE ) Если вы выполняете запрос по побитовому столбцу и вам нужно проверить значение, вы можете использовать метод bitwiseWhere (или просто построить оператор WHERE вручную). /** * Bitwise WHERE clause * * @param array $definition Bitwise keys as defined by the class * @param string $key The key to check for * @param bool $value Value to check for * @return string * @throws \InvalidArgumentException */ public function bitwiseWhere( $definition, $key, $value=TRUE ) Вы обнаружите, что большинство этих разных методов не так часто используются, как методы ядра insert, update, delete, replace и select.
  11. Цепочка наследования Ваша модель комментариев расширяет несколько классов. А именно: \IPS\Content\Comment - Предоставляет возможности комментариев. Рассмотрим эти функции в данном разделе. \IPS\Content - Предоставляет небольшое количество функций, которые являются общими для моделей контента и моделей комментариев, таких как получение автора и работа с $databaseColumnMap. \IPS\Patterns\ActiveRecord - Обеспечивает функциональность загрузки элементов из базы данных, работы с их свойствами, сохранения и удаления. Дополнительную информацию об этом класс смотрите в документе Active Records. Основной скелет namespace IPS\yourApp; class _Comment extends \IPS\Content\Comment { /** * @brief [ActiveRecord] Multiton Store */ protected static $multitons; /** * @brief Default Values */ protected static $defaultValues = NULL; /** * @brief [Content\Comment] Item Class */ public static $itemClass = 'IPS\yourApp\YourClass'; /** * @brief [ActiveRecord] Database Table */ public static $databaseTable = 'yourapp_comments'; /** * @brief [ActiveRecord] Database Prefix */ public static $databasePrefix = 'comment_'; /** * @brief Title */ public static $title = ‘thing_comments’; /** * @brief Database Column Map */ public static $databaseColumnMap = array( 'item' => 'fid', 'author' => 'mid', 'author_name' => 'author', 'content' => 'text', 'date' => 'date', 'ip_address' => 'ip_address' ); } Указание свойств вашего класса Модели комментариев требуют нескольких статических свойств для настройки их поведения, большинство из которых идентичны модели элемента контента. Многие из них относятся к классу Active Records. public static $application = 'string'; Обязательное. Ключ приложения, к которому принадлежит комментарий. public static $module = 'string'; Обязательное. Ключ модуля, к которому принадлежит комментарий. public static $multitons = array(); public static $defaultValues = NULL; Обязательное. Унаследовано от \IPS\Patterns\ActiveRecord. Эти два свойтсва требуемы классом \IPS\Patterns\ActiveRecord. Они не нуждаются в переопределени; они просто должны быть определены. public static $databaseTable = 'string'; Обязательное. Унаследовано от \IPS\Patterns\ActiveRecord. Имя таблицы базы данных, в которой хранятся эти комментарии. public static $databasePrefix = 'string'; Необязательное. Унаследовано от \IPS\Patterns\ActiveRecord. Указывает префикс поля, используемый этой таблицей. public static $databaseColumnMap = array(); Обязательное. Возможности, предоставляемые расширяемыми классами вашей модели, будут проверять этот массив, чтобы узнать, какие столбцы какую информацию хранят в вашей базе данных. Требуются следующие элементы: item Обязательный. Должен содержать название столбца, который хранит ID элемента контента, к которому принадлежит этот комментарий. author Обязательный. Должен содержать название столбца, который хранит номер ID пользователя, опубликовавшего контент. content Обязательный. Должен содержать название столбца, который хранит фактический текст комментария. date Обязательный. Должен содержать название столбца, который хранит unix-время даты публикации комментария. ip_address Обязательный. Должен содержать название столбца, который хранит IP-адрес автора комментария. author_name Необязательный. Может содержать название столбца, который хранит имя пользователя, опубликовавшего комментарий. first Необязательный. Может содержать название столбца, который хранит логическое значение, указывающее, является ли этот комментарий первым у элемента. public static $commentTemplate = 'string'; Необязательный. Задает шаблон, который будет использоваться для отображения комментария (смотрите метод html() ниже). Например: array( array( 'global', 'core', 'front' ), 'commentContainer' ); public static $formTemplate = 'string'; Необязательный. Задает шаблон, который будет использоваться для отображения формы комментария. Например: array( array( 'forms', 'core', 'front' ), 'commentTemplate' ); public static $formLangPrefix = 'string'; Необязательный. Указывает префикс для добавления к языковым строкам, используемым моделью, что позволяет создавать собственные языковые строки для вашей цели. Доступные методы в модели комментариев В дополнение к тем, которые предоставляются классом \IPS\Patterns\ActiveRecord (которые работают точно так же, как и для моделей элементов контента), доступно несколько дополнительных методов. \IPS\Http\Url url( string $action ) Возвращает URL-адрес комментария, автоматически вычисляет правильный номер страницы, в том числе и якорь в нужном месте страницы. Этот метод уже определен для вас. $action (string, необязательный) если параметр будет передан, добавится параметр 'do=value' в URL-адрес. \IPS\Content\Item item() Возвращает элемент контента, которому принадлежит этот комментарий. IPS\Member author() Возвращает объект \IPS\Member для пользователя, разместившего элемент контента. Например: $comment = YourClass::load( 1 ); $user = $comment->author(); echo $comment->name; string truncated( [ boolean $oneLine ] ) Возвращает содержимое в формате, подходящем для использования с виджетом data-ipsTruncate. $oneLine (boolean, необязательный, по умолчанию FALSE) - По умолчанию абзацы превращаются в разрыв строки. Если этот параметр имеет значение TRUE, параграфы заменяются пробелами вместо разрывов строк, что делает усеченный контент подходящим для однострочного отображения. boolean canEdit( [ \IPS\Member $member ] ) Возвращает логическое значение, указывающее, может ли передаваемый пользователь редактировать элемент контента. $member (\IPS\Member, необязательный) - Если предоставлено, при выполнении проверки используются разрешения пользователя. По умолчанию используется текущий авторизованный пользователь. boolean canDelete( [ \IPS\Member $member ] ) Возвращает логическое значение, указывающее, может ли передаваемый пользователь удалить элемент контента. $member (\IPS\Member, необязательный) - Если предоставлено, при выполнении проверки используются разрешения пользователя. По умолчанию используется текущий авторизованный пользователь. boolean static modPermission( string $type [, \IPS\Member $member [, \IPS\Node\Model $container ] ] ) Возвращает логическое значение, указывающее, имеет ли передаваемый пользователь разрешение на выполнение действия, указанного в параметре $type в указанном контейнере $container (если указан). $type (string, обязательный) - Тип проверяемого разрешения. Допустимые значения: edit. delete. move. hide (если включено скрытие/одобрение). unhide (если включено скрытие/одобрение). view_hidden (если включено скрытие/одобрение) $member (\IPS\Member, необязательный) - Если предоставлено, использует разрешения этого пользователя при выполнении проверки. По умолчанию используется текущий авторизованный пользователь. $container (\IPS\Node\Model, необязательный) - Если предоставлено, проверяет разрешение именно в этом контейнере. void modAction( string $type [, \IPS\Member $member [, string $reason ] ] ) Выполняет указанное действие модерации. Выбрасывает исключение OutOfRangeException, если пользователь не имеет разрешения на выполнение этого действия. $type (строка, обязательный) - Тип выполняемого действия модерации. Обратитесь к списку в предыдущем методе для допустимых значений. $member (\IPS\Member, необязательный) - Если предоставлено, использует разрешения этого пользователя при выполнении проверки. По умолчанию используется текущий авторизованный пользователь. $reason (строка, необязательный) - Используется только для действий скрыть/показать; определяет причину, по которой предпринимается действие. boolean isFirst() Возвращает true или false, что указывает, является ли это первым комментарием элемента контента. boolean isIgnored( [ \IPS\Member $member ] ) Указывает, игнорирует ли пользователь автора комментария. $member (\IPS\Member, optional) - если указано, используются предпочтения данного пользователя при проверки на статус игнорирования. По умолчанию используется текущий авторизованный пользователь. string dateLine() Возвращает строку, которая может использоваться в шаблонах, чтобы показывать, когда был добавлен комментарий, например. "Добавлено 2 часа назад". string html() Возвращает HTML-код для отображения комментария, обёрнутый в шаблон комментария.
  12. Ниже приведен пример модели элемента контента, в которой используются несколько функций, обсуждаемых в этом разделе. <?php namespace IPS\downloads; /** * File Model */ class _File extends \IPS\Content\Item implements \IPS\Content\Permissions, \IPS\Content\Tags, \IPS\Content\Reputation, \IPS\Content\Followable, \IPS\Content\ReportCenter, \IPS\Content\ReadMarkers, \IPS\Content\Hideable, \IPS\Content\Featurable, \IPS\Content\Pinnable, \IPS\Content\Lockable, \IPS\Content\Shareable { /** * @brief Application */ public static $application = 'downloads'; /** * @brief Module */ public static $module = 'downloads'; /** * @brief Database Table */ public static $databaseTable = 'downloads_files'; /** * @brief Database Prefix */ public static $databasePrefix = 'file_'; /** * @brief Multiton Store */ protected static $multitons; /** * @brief Default Values */ protected static $defaultValues = NULL; /** * @brief Node Class */ public static $containerNodeClass = 'IPS\downloads\Category'; /** * @brief Comment Class */ public static $commentClass = 'IPS\downloads\File\Comment'; /** * @brief Review Class */ public static $reviewClass = 'IPS\downloads\File\Review'; /** * @brief Database Column Map */ public static $databaseColumnMap = array( 'container' => 'cat', 'author' => 'submitter', 'views' => 'views', 'title' => 'name', 'content' => 'desc', 'num_comments' => 'comments', 'num_reviews' => 'reviews', 'last_comment' => 'last_comment', 'last_review' => 'last_review', 'date' => 'submitted', 'updated' => 'updated', 'rating' => 'rating', 'approved' => 'open', 'approved_by' => 'approver', 'approved_date' => 'approvedon', 'pinned' => 'pinned', 'featured' => 'featured', 'locked' => 'locked', 'ip_address' => 'ipaddress' ); /** * @brief Title */ public static $title = 'downloads_file'; /** * @brief Icon */ public static $icon = 'download'; /** * @brief Form Lang Prefix */ public static $formLangPrefix = 'file_'; /** * @brief Reputation Type */ public static $reputationType = 'file_id'; /** * @brief Follow Area Key */ public static $followArea = 'file'; /** * Get URL * * @param string|NULL $action Action * @return \IPS\Http\Url */ public function url( $action=NULL ) { $url = \IPS\Http\Url::internal( "app=downloads&module=downloads&controller=view&id={$this->id}", 'front', 'downloads_file', $this->name_furl ); if ( $action ) { $url = $url->setQueryString( 'do', $action ); } return $url; } /** * Should new items be moderated? * * @param \IPS\Member $member The member posting * @param \IPS\Node\Model $container The container * @return bool */ public static function moderateNewItems( \IPS\Member $member, \IPS\Node\Model $container = NULL ) { if ( $container and $container->bitoptions['moderation'] and !static::modPermission( 'unhide', $member, $container ) ) { return TRUE; } return parent::moderateNewItems( $member, $container ); } /** * Should new comments be moderated? * * @param \IPS\Member $member The member posting * @return bool */ public function moderateNewComments( \IPS\Member $member ) { $commentClass = static::$commentClass; return $this->container()->bitoptions['comment_moderation'] and !$commentClass::modPermission( 'unhide', $member, $this->container() ); } /** * Should new reviews be moderated? * * @param \IPS\Member $member The member posting * @return bool */ public function moderateNewReviews( \IPS\Member $member ) { $reviewClass = static::$reviewClass; return $this->container()->bitoptions['reviews_mod'] and !$reviewClass::modPermission( 'unhide', $member, $this->container() ); } /** * Get elements for add/edit form * * @param \IPS\Content\Item|NULL $item The current item if editing or NULL if creating * @param int $container Container (e.g. forum) ID, if appropriate * @return array */ public static function formElements( $item=NULL, \IPS\Node\Model $container=NULL ) { $return = parent::formElements( $item, $container ); $return['file_desc'] = new \IPS\Helpers\Form\Editor( 'file_desc', $item ? $item->desc : NULL, TRUE, array( 'app' => 'downloads', 'key' => 'Downloads', 'autoSaveKey' => 'downloads-new-file' ) ); return $return; } }
  13. По всему Invision Community элементы контента могут быть встроены в другой контент, генерируя небольшой предварительный просмотр контента. Вы можете поддерживать такой тип встраивания для своих элементов контента, позволяя им встраиваться в другие области сообщества. Примечание. Вы должны были внедрить расширение ContentRouter для поддержки встраивания. Как реализовать встраивание Во-первых, вам необходимо реализовать интерфейс встаривания в вашей модели элементов контента, например: implements \IPS\Content\Embeddable
 Затем убедитесь, что URL-адреса вашего контента содержат параметр "id", который является основным идентификатором вашего контента. Если это не так, вам необходимо переопределить метод loadFromUrl() в вашем классе (это определено в \IPS\Patterns\ActiveRecord): public function loadFromUrl( \IPS\Http\Url $url ) { return static::load( ... ); } Контроллер и модель автоматически поддерживают встраивание с использованием общего шаблона. Если вы хотите использовать собственный шаблон, переопределите метод embedContent() в вашей модели и верните другой HTML: string embedContent( array $params ) $params (array, обязательный) - Дополнительные параметры, которые были переданы во встраиваемом URL.
  14. Рейтинги позволяют пользователям оценивать элементы контента из 5 или 10 (в зависимости от настроек) звёзд. Как реализовать рейтинги Во-первых, вам необходимо реализовать интерфейс рейтингов в своей модели контента, например: implements \IPS\Content\Ratings Далее добавьте следующие ключи в свойство $databaseColumnMap вашей модели. Это необязательно, но добавление их сделает ваше приложение намного более эффективным при возврате среднего рейтинга при просмотре. Как обычно, значение каждого ключа должно быть именем столбца базы данных, который содержит значение. rating_average - текущий средний рейтинг элемента. rating_total -общая сумма всех рейтингов элемента. rating_hits - количество полученных голосов элементом. Наконец, отобразите рейтинг в шаблоне просмотра контента. Например: {$item->rating()|raw} Дополнительные доступные методы модели boolean canRate( [ \IPS\Member $member ] ) Указывает, имеет ли пользователь разрешение на оценку этого элемента. $member (\IPS\Member, необязательный) - Пользователь, чьи разрешения должны быть проверены. По умолчанию используется текущий авторизованный пользователь. float averageRating() Возвращает средний рейтинг элементов (общий рейтинг, деленный на количество голосов). string rating() Отображает значки звездочек, представляющие текущий средний рейтинг. Если у пользователя есть разрешение на оценку элемента, эти значки будут интерактивными, позволяя пользователю кликнуть, чтобы оценить.
  15. Реализуя опросы в вашем приложении, пользователи смогут создать опрос при создании нового элемента контента. Процесс выполняется автоматически; новая вкладка будет отображаться в форме создания элемента, которая позволит управлять опросом. Как реализовать опросы Во-первых, ваша модель элемента контента должна реализовать интерфейс опроса, например: implements \IPS\Content\Polls Затем добавьте ключ в ваше свойство $databaseColumnMap со значением, являющимся названием столбца базы данных, хранящего ID опроса для данного элемента (обратите внимание, вы можете иметь только один опрос для одного элемента контента). Наконец, отобразите опрос в шаблоне просмотра элемента контента. Например: {$item->getPoll()|raw} Выполнение дополнительных действий после голосования При желании, ваша модель может быть оповещена, когда пользователь голосует в опросе. Для добавления поддержки этого, вы должны реализовать SPL Observer: implements \SplObserver В вашей модели добавьте метод обновления, который будет вызван, когда опрос получает голоса: void update( \IPS\Poll $poll ) $poll (\IPS\Poll) - Опрос, на который проголосовали. Наконец, при отображении вашего элемента контента присоедините элемент к опросу. Например: if ( $poll = $item->getPoll() ) { $poll->attach( $item ); } Дополнительные доступные методы модели boolean static canCreatePoll( [ \IPS\Member $member [, \IPS\Node\Model $container ] ] ) Указывает, может ли пользователь создать опрос. $member (\IPS\Member, необязательный) - Пользователь, разрешения которого должны быть проверены. По умолчанию будет использоваться текущий авторизованный пользователь. $container (\IPS\Node\Model, необязательный) - Проверяет, могут ли быть созданы опросы в этом контейнере. \IPS\Poll getPoll() Возвращает опрос для этого элемента (или NULL, если опроса у элемента нет).
  16. Реализация маркеров прочитанности в Элементах Контента Маркеры прочитанности контента позволяют пользователям легко видеть, какие элементы контента уже были просмотрены с помощью небольшой иконки в списке контента. Они являются стандартной функцией Invision Community и вы должны реализовать их, если ваше приложение каким-либо образом связано с пользовательским контентом. Как реализовать маркеры прочитанности Во-первых, ваша модель элемента контента должна реализовать интерфейс маркера прочитанности, например: implements \IPS\Content\ReadMarkers Затем вы должны добавить ключ в свойство $databaseColumnMap вашей модели. Ключ (и), который вы должны использовать, зависит от других функций, которые вы можете реализовать, но во всех случаях значение должно быть именем столбца базы данных, который хранит unix-время для соответствующего действия. Добавьте ключ updated. Добавьте ключ last_comment, если вы используете комментарии. Добавьте ключ last_review, если вы используете отзывы. Наконец, убедитесь, что, когда пользователь просматривает элемент, учитывается маркировка прочитанности. В методе manage() вашего контроллера вы должны вызвать родительский метод: parent::manage(); или вручную вызвать $item->markRead() для запуска действия маркировки. Дополнительные доступные методы модели Примечание: Чтобы использовать методы containerUnread() и markContainerRead(), описанные ниже, ваша модель ноды контейнера должна реализовать следующие методы. Дополнительную информацию см. в руководстве Контейнеры. get__items() get__comments() setLastComment() getLastCommentTime() boolean static containerUnread( \IPS\Node\Model $container [, \IPS\Member $member ] ) Указывает, имеет ли указанный контейнер (включая дочерние) какой-либо непрочитанный контент для пользователя. $container (\IPS\Node\Model, обязательный) - контейнер для проверки. $member (\IPS\Member, необязательный) - Пользователь, чей статус прочитанности должен проверяться. По умолчанию будет использоваться текущий авторизованный пользователь. void static markContainerRead( \IPS\Node\Model $container [, \IPS\Member $member [, boolean $children ] ] ) Помечает контейнер (и, необязательно, потомков) как прочитанный. $container (\IPS\Node\Model, обязательный) - Контейнер для маркировки прочтения. $member (\IPS\Member, необязательный) - Пользователь, чей статус прочитанности должен быть изменён. По умолчанию будет использоваться текущий авторизованный пользователь. $children (boolean, необязательный, по умолчанию TRUE) - Должны ли потомки контейнера стать также прочитанными? integer unread( [ \IPS\Member $member ] ) Возвращает целое число, указывающее статус прочтения элемента. Возвращаемые значения: 0 если элемент прочитан. -1 если элемент не прочитан и никогда не читался. 1 если элемент не прочитан, но был прочитан ранее (т. е. с момента последнего прочтения появилась новая активность). Применяется только при использовании комментариев. $member ( \IPS\Member, необязательный ) - Пользователь, чей статус прочитанности должен проверяться. По умолчанию будет использоваться текущий авторизованный пользователь. void markRead( [ \IPS\Member $member [, integer $time [, mixed $extraContainerWhere ] ] ] ) Помечает элемент как прочитанный. $member (\IPS\Member, необязательный) - Пользователь, чей статус прочитанности должен быть обновлён. По умолчанию будет использоваться текущий авторизованный пользователь. $time (integer, необязательный) - unix-время для установки как 'последнее прочтение'. По умолчанию, или если передан NULL, будет использовано текущее время. $extraContainerWhere (mixed, необязательный) - массив или строка, содержащая дополнительные операторы WHERE, которые должны быть переданы в базовый запрос. \IPS\DateTime timeLastRead( [ \IPS\Member $member ] ) Возвращает объект DateTime, указывающий на последнее прочтение элемента пользователем (или NULL, если элемент ещё не прочитан) $member (\IPS\Member, необязательный) - Пользователь, чьё время последнего прочтения должно быть возвращено. По умолчанию будет использоваться текущий авторизованный пользователь.
  17. Поддерживая механизм жалоб в вашем приложении, пользователи смогут жаловаться на ваши элементы контента модераторам, которые смогут рассматривать их в центре жалоб. Как реализовать жалобы Во-первых, вам необходимо реализовать интерфейс жалоб в вашей модели элементов контента, например: implements \IPS\Content\ReportCenter Затем добавьте статическое свойство в модель вашего элемента контента. Это свойство является названием иконки FontAwesome, которая будет представлять ваши элементы контента при просмотре в центре жалоб: public static $icon = 'string'; Наконец, включите ссылку жалоб в свой HTML код. В этом случае вы не должны вызывать метод canReport(), поскольку он является ресурсоемким. Вместо этого проверьте наличие возможности у группы создавать жалобы, а так же, чтобы пользователь не являлся автором этого элемента контента. Например: {{if !\IPS\Member::loggedIn()->group['gbw_no_report'] and $item->author()->member_id != \IPS\Member::loggedIn()->member_id }} <a href='{$item->url('report')}' data-ipsDialog data-ipsDialog-size='narrow' data-ipsDialog-title="{lang="report_post"}" data-ipsDialog- flashMessage="{lang="node_error"}" title='{lang="report_post"}'><i class='icon-exclamation-sign'></i>&nbsp; {lang="report_post"}</a> {{endif}} Дополнительные доступные методы модели boolean canReport( [ \IPS\Member $member ] ) Указывает, сможет ли пользователь жаловаться на элемент. Рассматривает наличие у группы пользователя разрешения на подачу жалоб, может ли пользователь просматривать контент и имеет ли уже отправленную жалобу на элемент. $member (\IPS\Member, optional) - Пользователь, чьи разрешения должны быть проверены. По умолчанию используется текущий авторизованный пользователь. \IPS\core\Reports\Report report( string $reportContent ) Отправляет и возвращает жалобу на элемент. $reportContent (string, required) - Контент жалобы.
  18. Кнопки Поделиться позволяют пользователям распространять элементы контента в различные социальные сети, настроенные администратором. Как реализовать ссылки Поделиться Во-первых, ваша модель элемента контента должна реализовать интерфейс ссылок поделиться, например: implements \IPS\Content\Shareable Наконец, включите шаблон ссылок в просмотр вашего элемента контента: {template="sharelinks" app="core" group="global" params="$item"} Дополнительные доступные методы модели array sharelinks() Возвращает массив URL-адресов сервисов для элемента контента.
  19. Ваш элемент контента может автоматически отслеживать количество просмотров реализуя интерфейс просмотра страниц. Обратите внимание, что кеширование гостевой страницы может сделать счет неточным, так как кешированная страница не увеличит количество просмотров. Реализация отслеживания просмотра страниц Во-первых, вам необходимо реализовать интерфейс просмотра страниц в вашей модели элементов контента, например: implements \IPS\Content\Views Наконец, убедитесь, что метод manage() в вашем контроллере элемента контента вызывает родительский метод manage(): parent::manage(); Дополнительные доступные методы модели array stats( [ boolean $includeFirstComment ] ) Возвращает массив статистических данных о элементе, с ключом num_views, содержащим количество просмотров. $includeFirstComment (boolean, необязательный, по умолчанию TRUE) - Определяет, подсчитывается ли первый комментарий в количестве комментариев элемента.
  20. Как реализовать возможность подписываться Примечание: ваше приложение также должно реализовать поиск (\IPS\Content\Searchable) для возможности реализовать подписку. Сперва вы должны реализовать интефрейс подписки в вашей модели элемента контента, например: implements \IPS\Content\Followable Затем вам нужно вставить конструкцию в шаблон, которая покажет кнопку Подписаться, в ваши ноды и сами элементы контента. В просмотр ноды (например просмотр форума), вставьте данный тег: {template="follow" app="core" group="global" params=“'yourApp','yourNodeClass', $node->_id, \IPS\yourApp\YourContentClass::containerFollowers( $node )->count( TRUE )"} Параметры в этом теге: yourApp - ключ вашего приложения. yourNodeClass - имя класса вашей ноды контейнера. $node->_id - ID вашего контейнера (например форум, в приложении "Форумы"). Последний параметр должен статически вызывать containerFollowers (смотрите ниже) в вашем классе элемента, чтобы передать текущее количество подписчиков. в шаблон просмотра элемента контента (например просмотр темы), вставьте следующий тег: {template="follow" app="core" group="global" params="'yourApp', 'yourContentItemClass', $item->id, $item->followersCount()"} Параметры: yourApp - ключ вашего приложения. yourContentItemClass - название класса вашего элемента контента. $item->id - ID соответствующего элемента контента. Последний параметр просто вызывает $item->followersCount() для передачи текущего количества подписчиков. Изменения после реализации После публикации нового элемента контента, пользователи, подписанные на ноду, в которой размещён элемент, получат уведомление. Если контент должен быть одобрен модератором, уведомления будут отложены до тех пор, пока контент не будет одобрен. Дополнительные доступные методы модели integer static containerFollowers( \IPS\Node\Model $node [, integer $privacy [, array $frequencyTypes [, \IPS\DateTime $date [, integer|array $limit [, string $order [, integer $flags ] ] ] ] ] ] ) Возвращает подписчиков ноды. $node (\IPS\Node\Model, обязательный) - Нода, из которой будут возвращены подписчикии. $privacy (integer, необязательный, по умолчанию 3) - Поразрядное значение, представляющее типы подписки, которые должны быть возвращены (смотрите ниже для получения дополнительной информации). Значение по умолчанию 3 включает как анонимных, так и публичных подписчиков. $frequencyTypes (array, необязательный, по умолчанию array( 'none', 'immediate', 'daily', 'weekly' ) ) - Позволяет вам сузить возвращаемых подписчиков до определённых типов подписок. По умолчанию учитываются все типы. $limit (integer or NULL, необязательный, по умолчанию NULL) - Позволяет ограничить количество возвращаемых подписчиков. Значение передаётся в виде параметра LIMIT в результирующий запрос. $order (string, необязательный, по умолчанию NULL) - Позволяет вам определить столбец, по которому будут упорядочены результаты. $flags (integer or NULL, необязательный, по умолчанию NULL) - SQL флаги, которые будут переданы в \IPS\Db при выполнении базового запроса. Побитовые значения приватности подписок Конфигурация конфиденциальности подписок позволяет пользователю указать, какой должна быть подписка - 'публичной' или 'анонимной', то есть его подписка будет учтена при подсчёте общего количества подписчиков, но не будет показано имя подписчика. Значения: const FOLLOW_PUBLIC = 1; const FOLLOW_ANONYMOUS = 2;
  21. Как реализовать репутацию Сначала вам нужно реализовать интерфейс репутации в своей модели, например: implements \IPS\Content\Reputation Затем вам нужно добавить статическое свойство в свою вашу модель элемента контента, которое отличает этот тип репутации от другого вида контента. Это может быть всё, что вам нравится, но принято использовать имя столбца, в котором хранится идентификатор элемента (например, topic_id или entry_id). public static $reputationType = 'string'; Наконец, добавьте кнопки репутации, вызвав шаблон кнопок репутации в представлении (шаблоне) вашего элемента контента: {template="reputation" app="core" group="global" params=“$item"} Дополнительные доступные методы модели boolean canGiveReputation( integer $type [, \IPS\Member $member ] ) Указывает, может ли пользователь выдать репутацию автору элемента контента. $type (integer, обязательный) - Тип репутации. Либо 1, либо -1, где 1 - положительная репутация, а -1 - отрицательная репутация. $member (\IPS\Member, необязательный) - Пользователь, чьи разрешения должны быть использованы при проверке. По умолчанию используется текущий авторизованный пользователь. void giveReputation( integer $type [, \IPS\Member $member ] ) Выдаёт репутацию автору элемента контента. Выбрасывает исключение DomainException, если пользователь не имеет права выдавать репутацию этому элементу. $type (integer, обязательный) - Тип выдаваемой репутации. Либо 1, либо -1, где 1 - положительная репутация, а -1 - отрицательная репутация. $member (\IPS\Member, необязательный) - Пользователь, чьи разрешения должны быть использованы при проверке. По умолчанию используется текущий авторизованный пользователь. integer repGiven( [ \IPS\Member $member ] ) Возвращает значение, указывающее была ли выдана репутация (и какого типа) пользователю за элемент контента. Возвращаемые значения: 1 - была выдана положительная репутация. -1 - была выдана отрицательная репутация. 0 - репутация не выдана. $member (\IPS\Member, необязательный) - Пользователь, чьи разрешения должны быть использованы при проверке. По умолчанию используется текущий авторизованный пользователь.
  22. Как реализовать поиск Функциональность поиска (и связанные с ним функции, такие как ленты активности) автоматически обрабатывается для вас ядром Invision Community. Вам просто нужно указать, что ваши элементы контента должны быть доступны для поиска, реализуя интерфейс: implements \IPS\Content\Searchable Обратите внимание, что вы также должны реализовать расширение ContentRouter. Изменения после реализации Контент будет проиндексирован и включён в результаты поиска и ленты активности. Индекс будет автоматически обновляться при создании, редактировании, перемещении, скрытии и т.д. контента.
  23. К элементам контента пользователи могут добавлять теги. Теги могут быть использованы для поиска других различных типов контента с такими же тегами. Префикс является одним из тегов элемента, который показывается выделенным и в начале заголовка элемента. Как реализовать тегирование Тегирование требует, чтобы ваши элементы контента находились внутри ноды контейнера. Во-первых, вам необходимо реализовать интерфейс тегирования: implements \IPS\Content\Tags Затем вы можете отображать префикс и теги в отображении для своего элемента, например: {{if $item->prefix()}} <a href="{url="app=core&module=system&controller=tags&tag={$item->prefix()}" seoTemplate="tags"}">{$item->prefix()}</a> {{endif}} {{if count( $file->tags() )}} <ul> {{foreach $file->tags() as $tag}} <li> <a href="{url="app=core&module=system&controller=tags&tag={$tag}" seoTemplate="tags"}">{$tag}</a> </li> {{endforeach}} </ul> {{endif}} Изменения после реализации Поле для ввода тегов будет добавлено в форму создания/редактирования. Префиксы и теги будут отображаться в списках контента. Дополнительные доступные методы модели boolean static canTag( [ \IPS\Member $member [, \IPS\Node\Model $container ] ] ) Указывает, имеет ли пользователь разрешение на тегирование элементов. $member (\IPS\Member, optional) - Если предоставлено, при проверке будут использоваться разрешения текущего пользователя. По умолчанию, будет использован текущий авторизованный пользователь. $container (\IPS\Node\Model, optional) - Если предоставлено, проверяет, может ли пользователь тегировать в этой конкретной ноде. boolean static canPrefix( [ \IPS\Member $member [, \IPS\Node\Model $container ] ] ) Указывает, имеет ли пользователь разрешение на выбор тега в качестве префикса для элементов. $member (\IPS\Member, optional) - Если предоставлено, при проверке будут использоваться разрешения текущего пользователя. По умолчанию, будет использован текущий авторизованный пользователь. $container (\IPS\Node\Model, optional) - Если предоставлено, проверяет, может ли пользователь выбирать префикс к элементам в этой конкретной ноде. array tags() Возвращает массив тегов элемента. string prefix( [ boolean $encode ] ) Возвращает префикс для элемента (NULL если элемент не имеет префикса). $encode (boolean, optional, default FALSE) - Если true, url-encode вернёт префикс.
  24. Как реализовать закрепление Чтобы поддерживать закрепление элементов контента в вашей модели, вам необходимо реализовать следующий интерфейс: implements \IPS\Content\Pinnable Затем вы должны добавить ключ закрепления в свойство $databaseColumnMap, со значением, которое является именем столбца базы данных, хранящего статус закрепления вашего элемента. Ну и наконец, вам нужно добавить поддержку в ваши шаблоны. Например: {{if $item->canPin()}} <a href='{$item->url()->setQueryString( array( 'do' => 'moderate', 'action' => 'pin' ) )}'>{lang="pin"}</a> {{endif}} {{if $item->canUnpin()}} <a href='{$item->url()->setQueryString( array( 'do' => 'moderate', 'action' => 'unpin' ) )}'>{lang="unpin"}</a> {{endif}} Изменения после реализации Закреплённые элементы будут отображаться вверху списка элементов контента. Модераторы с соответствующим разрешением смогут видеть и использовать инструменты для закрепления контента при выборе элементов в списке элементов контента. Дополнительные доступные методы модели boolean canPin( \IPS\Member $member ) Указывает, имеет ли пользователь разрешение на закрепление элементов. Этот метод учитывает, был ли элемент уже закреплен. $member (\IPS\Member, optional) - Если предоставлено, будут проверять разрешения данного пользователя. По умолчанию, будет использован текущий авторизованный пользователь. boolean canUnpin( \IPS\Member $member ) Указывает, имеет ли пользователь разрешение откреплять элементы. Этот метод учитывает, является ли элемент уже незакрепленным. $member (\IPS\Member, optional) - Если предоставлено, будут проверять разрешения данного пользователя. По умолчанию, будет использован текущий авторизованный пользователь.
  25. Как реализовать популярность Чтобы поддерживать возможность делать контент популярным в вашем приложении, вы сперва должны реализовать интерфейс в вашей модели элемента контента: implements \IPS\Content\Featurable Затем вам нужно добавить ключ в ваше свойство $databaseColumnMap, со значением, являющимся именем столбца в вашей таблице базы данных, в которой хранится статус популярности элемента. Ну и наконец, вам нужно добавить поддержку в ваши шаблоны. Например: {{if $item->canFeature()}} <a href='{$item->url()->setQueryString( array( 'do' => 'moderate', 'action' => 'feature' ) )}'>{lang="feature"}</a> {{endif}} {{if $item->canUnfeature()}} <a href='{$item->url()->setQueryString( array( 'do' => 'moderate', 'action' => 'unfeature' ) )}'>{lang="unfeature"}</a> {{endif}} Изменения после реализации После реализации интерфейса \IPS\Content\Featurable, модераторы с соответствующим разрешением смогут видеть и использовать инструменты для популяризации контента при выборе элементов в списке элементов контента. Дополнительные доступные методы модели \IPS\Patterns\AciveRecordIterator static featured( [ integer $limit [, string $order [, \IPS\Node\Model $container ] ] ] ) Возвращает популярные элементы. Если разрешения поддерживаются в вашей модели, возвращаются только те элементы, на просмотр которых у пользователя есть разрешение. $limit (integer, необязательный, по умолчанию 10) - Количество элементов для возврата. $order (string, необязательный, по умолчанию 'RAND()') - Порядок сортировки для использования в запросе. $container (\IPS\Node\Model, необязательный, по умолчанию NULL) - Если указано, будут возвращены только популярные элементы из данного контейнера. boolean canFeature( \IPS\Member $member ) Указывает, имеет ли пользователь разрешение на установку элемента популярным. Этот метод учитывает, включен ли элемент. Этот метод учитывает, является ли уже элемент популярным. $member (\IPS\Member, необязательный) - Если предоставлено, будут проверять разрешения данного пользователя. По умолчанию, будет использован текущий авторизованный пользователь. boolean canUnfeature( \IPS\Member $member ) Указывает, имеет ли пользователь разрешение на установку элемента НЕ популярным. Этот метод учитывает, является ли уже элемент не популярным. $member (\IPS\Member, необязательный) - Если предоставлено, будут проверять разрешения данного пользователя. По умолчанию, будет использован текущий авторизованный пользователь.
×
×
  • Создать...

Важная информация

Используя наш сайт вы соглашаетесь с нашей Политикой конфиденциальности