MODX Revolution объекты

Содержание статьи:

Здесь собрана информация про объекты MODX для собственного пользования, возможно, кому-то она тоже пригодится. Например, для MODX разработчиков, которые пишут пхп код в сниппетах или плагинах и которым нужно понимать как взаимодействовать с ресурсами (документами, вебсылками, внутренними ссылками и статическими ресурсами) и элементами (чанками, сниппетами, плагинами, шаблонами, переменными шаблона и категориями) в MODX Revolution.

Этот пост содержит короткое вступление в xPDO. Оно представляет базовые методы, которые используются в различных объектах в MODX Revolution. Множество описанных здесь методов – это xPDO методы, но так как объект $modx является наследником $xpdo объекта, все методы доступны через $modx->methodName().

Текущий ресурс/ Текущий пользователь

Текущие ресурс и пользователь доступны прямо из следующих переменных MODX класса:

$currentResource = $modx->resource;
$currentUser = $modx->user;
/* Если пользователь не вошёл, то имя пользователя будет '(anonymous)'. */

Поля объектов доступны через каждый метод get() объекта (или getContent() для поля контента ресурса):

$intro = $modx->resource->get('introtext');
$UserID = $modx->user->get('id');
$content = $modx->resource->getContent();
Примите во внимание, что для ресурсов, использование get('content') или getContent(), выдаст сырое содержимое поля контент ресурса. Теги в поле контента не будут обработаны.

Нахождение других объектов

Ссылки на все объекты MODX могут быть получены используя метод $modx->getObject(). Вы можете «получить» объект MODX вот так:

$object = $modx->getObject('object-class-name',array(
       'name' => 'object-name' ));

Или получить объект по его ID номеру:

$object = $modx->getObject('object-class-name',$object-id);

Для получения ссылки на чанк, например, вам нужно использовать:

$chunk = $modx->getObject('modChunk',array(
       'name' => 'chunkName' ));

Чанк также можно получить по его ID, что даже быстрее. Этот способ также более надёжен, так как имя чанка может измениться, а вот его ID никогда:

$chunk = $modx->getObject('modChunk',$chunkId);

Использование ID сработает с любым типом объекта.

Для получения ресурса, который опубликован и имеет имя "Телефоны", вам нужно сделать это:

$document = $modx->getObject('modResource',array(
    'published' => 1,
    'pagetitle' => 'Телефоны'
));

Вот другой способ сделать это же:

$name = 'modResource';
$criteria = array(
    'published' => 1,
    'pagetitle' => 'Телефоны'
)
$document = $modx->getObject($name,$criteria)
Примечание: Общей ошибкой при получении ресурса является использование 'name' или 'title' вместо 'pagetitle'. Ресурсы не имеют поля 'name' или 'title', но всё равно описание панели Create/Edit ресурса для поля название страницы - это 'title.'

Вы можете также найти ресурс по его id, alias, menu title, и/или любому из полей с таблицы ниже. Если вы хотите, чтобы массив документов соответствовал вашему критерию, вы можете использовать getCollection() вместо getObject():

$docArray = $modx->getCollection('modResource',array(
    'published' => 1,
    'searchable' => 1
));

Помните, что getCollection() не возвращает пхп массив. Он возвращает массив объектов. Если вы хотите оперировать с полями объектов, как с пхп массивом, то вы должны использовать метод toArray():

$phpArray = $object->toArray();

Вы также можете использовать метод объекта get(), чтобы получить отдельное поле:

$resource->get('pagetitle');

С getObject() вы также можете использовать запрос как ваш критерий для getCollection() или getMany():

$tvCollection = $modx->getCollection('modTemplateVar', 
    "`name` IN ('" . implode("','", array('footer', 'header')) . "')");
Обратите внимание, что вы должны использовать поля показанные ниже в таблице с getObject(). Например, вам следует использовать 'pagetitle' для нахождения документов, но 'name' для нахождения сниппета или чанка.

Только если вы ходите получить объекты связанные с единственным объектом вы можете использовать метод getMany(). Подразумевая, что вы использовали getObject() для получения ссылки на ресурс или шаблон, вы можете получить их ТВ следующим образом:

$tvs = $template->resource->getMany('TemplateVars');

Похожим образом вы можете получить наследников:

$children = $resource->getMany('Children');

getObject() и getOne() возвращает null если запрошенный объект не найден, в то же время getMany() и getCollection() возвращают пустой массив, если нет соответствий заданному критерию.

Индивидуальные ресурсы (документы, вебссылки, внутренние ссылки и статические ресурсы) могут быть получены так:

$modx->getObject('modResource',$criteria);

Но также вы можете искать их отдельно:

$modx->getObject('modDocument',$criteria);
$modx->getObject('modWeblink',$criteria);
$modx->getObject('modSymlink',$criteria);
$modx->getObject('modStaticResource',$criteria);

Отдельные элементы (чанки, сниппеты, плагины, шаблоны, переменные шаблонов и категории) должны получаться используя ключ класса получаемого объекта:

$modx->getObject('modChunk',$criteria);
$modx->getObject('modSnippet',$criteria);
$modx->getObject('modPlugin',$criteria);
$modx->getObject('modTemplate',$criteria);
$modx->getObject('modTemplateVar',$criteria);
$modx->getObject('modCategory',$criteria);

Получение системных настроек

Системные настройки могут быть получены в сниппете методом getOption():

$setting = $modx->getOption('site_start');

Получение полей объекта с помощью $object->get()

После того, как вы получили объект используя getObject(), getCollection(), или getMany(), вы можете использовать $object->get() метод для получения любого поля по его имени:

$resource = $modx->getObject('modResource',12);
$longTitle = $resource->get('longtitle');

Текущий документ всегда доступен через:

$modx->resource

Вы можете получить любое из этих полей используя метод get():

$id = $modx->resource->get('id');
$name = $modx->resource->get('pagetitle');

Как и в MODX Evolution, любой тег сниппета заменяется возвращаемым значением работы сниппета. Поэтому если вы хотите вывести поле полученного объекта, то в конце вашего сниппета поместите строку:

return $resource->get('pagetitle');

Когда используете get('content') в ресурсе, то вы получите сырое значение содержимого поля контент ресурса. Без каких-либо обработанных тегов в контенте.

Использование $object->getOne() и $object->getMany() с объектами

Если объект имеет объекты, которые связанны с ним в схеме MODX, то они могут быть получены через методы getOne() или getMany(). Ресурсы, например, имеют связанные с ними Parent, Children, Template, CreatedBy, EditedBy и др. (см Таблицу ниже). Пока функция get() будет получать содержимое отдельного поля ресурса объекта, функция getOne() будет получать целый объект. Метод getMany() выдаст массив объектов. Ключом для знания того, какой метод вам нужен является то, что вам нужен более одного объекта. В таком случае, вам нужен getMany(). Ресурс, например, имеет только одного родителя, поэтому вы получите его с помощью getOne('Parent'). Тот же ресурс может иметь множество переменных шаблона в себе, поэтому для получения их вам нужно использовать getMany('TemplateVars').

Обратите внимание, что поля используемые с get() находятся в нижнем регистре, имя объектов используемые в вызове getOne() и getMany() в смешанном регистре. Методы getOne() и getMany() часто берут единственный аргумент (имя связанного объекта/объектов, которые вы хотите получить), но они также могут содержать как вариант второй аргумент, который полезен при сортировке результатов работы getMany().

Для получения ID ресурса-родителя:

$id = $resource->get('parent');

Для получения родителя самого по себе как MODX объекта:

$parentResource = $resource->getOne('Parent');

Схожим образом для получения объекта пользователь для пользователя, который создал ресурс:

$user = $resource->getOne('CreatedBy');

Или для текущего ресурса:

$user = $modx->resource->getOne('CreatedBy');

Объект пользователь содержит только ID, имя пользователя и хеш пароля пользователя. Для получения большего вам нужно использовать объект modUserProfile, ассоциированного с этим пользователем:

$user->getOne('Profile');

После того, как вы получили профиль, вы можете использовать его с помощью метода get() для получения любого поля ресурса:

$profile->get('fullname');

Для получения детей документа, отсортированных по полю Title:

$criteria = $modx->newQuery('modResource');
$criteria->where(array(
   'parent' => $modx->resource->get('id'),
));
$criteria->sortby('pagetitle','ASC');
$children = $modx->resource->getMany('Children',$criteria);

Переменные шаблона

Получение обработанных значений переменной шаблона из текущего документа (или любого документа, на который вы ссылаетесь) просто сделать с помощью этого метода (обратите внимание, что в обеих вызовах буквы 'V' в getTVValue() являются заглавными):

$val = $modx->resource->getTVValue('name_of_tv');
$val = $modx->resource->getTVValue($id); // ID переменной шаблона (не документа!"")

или

$resource = $modx->getObject('modResource',array('pagetitle'=>'SomePage'));
$val = $resource->getTVValue('name_of_tv');
$val = $resource->getTVValue($id); // ID переменной шаблона (не документа)

Получение значения переменной шаблона в другом документе является немного сложным, потому что обработанное значение переменной шаблона может отличаться в разных документах. В результате вы должны получить объект ресурс используя метод выше или используя специфические методы переменных шаблона и пересылать ID документа. Допустим $id – это ID документа (не ТВ):

/* получить ТВ */
$tv = $modx->getObject('modTemplateVar',array('name'=>'MyTV'));

/* получить сырое содержимое ТВ */
$rawValue = $tv->getValue($id);

/* получить обработанное содержимое ТВ */
$processedValue = $tv->renderOutput($id);

Использование toArray() с getChunk()

MODX делает простым отделение отображение от данных. Одним из действительно подходящих способов сделать это – это поместить заполнители (плейсхолдеры) в чанк и далее послать (передать) поля объекта в вызове в getChunk(). Скажем, например, что вы хотите вывести некоторые поля ресурса используя пользовательский сниппет. Если вы создадите Tpl чанк с заполнителями для полей, которые вы хотите показать, то вы можете вывести их в MODX Revolution с помощью всего лишь нескольких строк кода.

Метод toArray() работает с любым объектом MODX, но в основном используется с ресурсами и пользователями. Он создаёт ассоциативный PHP массив из полей объекта. Этот массив далее может быть использован как второй аргумент для $modx->getChunk() для замены любых заполнителей в чанке на соответствующие значения. Этот пример показывает как очень эффективно вывести поля ресурса. Представьте, что вы хотите показать поля ресурса называемого MyDocument и это ваш ShowResource Tpl-чанк:

Если вы разместите следующий тег сниппета на странице, то он выведет поля ресурса.
[[!ShowFields]]
Вот код самого сниппета:
$resource = $modx->getObject('modResource',array('pagetitle'=>'MyDocument'));
$fields = $resource->toArray();
return $modx->getChunk('ShowResource',$fields);

Modx заменяет все заполнители в Tpl-чанке на значения массива $fields, который содержит каждое поле ресурса. Немного более быстрая, но менее читаемая версия сниппета имеет всего лишь две строки:

$resource = $modx->getObject('modResource',array('pagetitle'=>'MyDocument'));
return $modx->getChunk('ShowResource',$resource->toArray());

Если вы хотите вывести поля текущего ресурса, сниппет станет более компактным:

return $modx->getChunk('ShowResource',$modx->resource->toArray());

Набор параметров

Набор параметров – это MODX объект, который содержит ассоциативный массив ключей и значений (схожих с Системными настройками). Набор параметров может быть прикреплён к элементам на вкладке Свойства элемента (доступные при редактировании элемента в Менеджере) или из Инструментов - Набор параметров в Основном меню Менеджера. Элемент может иметь более одного Набора параметров прикреплённых к нему и Набор параметров может быть прикреплён более, чем к одному элементу. Прикрепление набора параметров делает его доступным к элементу, это делается следующим образом:

[[SnippetName@PropertySetName]]
[[$ChunkName@PropertySetName]]

Прикреплённый к сниппету Набор параметров играет роль набора параметров сниппета (бывших параметров). Для чанка или другого элемента, значения в Наборе параметров будут заменены тегами плейсхолдера в чанке, который использует ключ от Набора параметров. Например, чанк "MyChunk" с набором параметров "MyProperties" будет выглядеть так:

[[$MyChunk@MyProperties]]

Если есть параметр "make" со значением "Ford," плейсхолдер будет заменён на Ford в отображаемом чанке.

Когда вы вызываете сниппет с набором параметров в теге:

[[SnippetName@PropertySetName? &property1=`value1` &property2=`value2`]]

Значения в выбранном Наборе параметров перезапишут значения Набора параметров по-умолчанию сниппета и параметра отправятся в тег сниппета (&property1 и &property2) и перезапишут значения на значения названного набора параметров. Конечно, это справедливо для параметров с одинаковыми именами То же самое происходит с другими элементами с прикреплёнными Наборами параметров. Значения Набора параметров перезапишут любые параметры по-умолчанию с теми же именами.

Получение обработанного вывода Объекта

В некоторых случаях вам возможно понадобится сниппета для получения обработанного вывода чанка или другого сниппета. Есть две функции runSnippet() и getChunk(), которые по-прежнему доступны в Revolution. В этом примере для сниппетов $props – это массив, который содержит параметры сниппета:

$modx->runsnippet($snippetName, $props);
$modx->getChunk($chunkName);

Когда вы выполняете сниппет с помощью runSnippet('SnippetName') в коде, то будут использованы параметры по-умолчанию. Если вы посылаете Набор параметров, используя runSnippet('SnippetName',$properties), то обое – Свойства по-умолчанию и отосланные вместе со сниппет тегом будут доступны в сниппете. Отправленные со сниппет тегом параметры перезапишут параметры по-умолчанию с тем же именем.

Плейсхолдер теги в чанке будут заменены на значения прикреплённого Набора параметров, но как эти плейсхолдеры будут обработаны при использовании getChunk() в сниппете? Ответ – это второй аргумент в getChunk(), который содержит массив параметров. Так как множество наборов параметров может иметь то же имя, то вам нужно найти нужное по имени:

$setName = 'desiredPropertySetName';
$chunkName = 'desiredChunkName';

$object = $modx->getObject('modChunk',array(
        'name' =>$chunkName));

$propSet = $modx->getObject('modPropertySet',array(
        'name' =>$setName));

return($modx->GetChunk($chunkName, $propSet->getProperties() ));

Вы должны понимать разницу между Набором параметров и Набором параметров по-умолчанию, которые доступны во вкладке Свойства элементов. Эти параметры по-умолчанию технически не являются Набором параметров. На самом деле, они – это эквивалент параметров Набора параметров. Метод getProperties() получит параметры любого из них:

/* Получение параметров по-умолчанию сниппета или другого элемента */
$snippet = $modx->getObject('modSnippet',array('name'=>'SnippetName'));
$properties = $snippet->getProperties();
/* Получение параметров отдельновзятого набора параметров */
$propSet = $modx->getObject('modPropertySet',array('name'=>'PropertySetName'));
$properties = $propSet->getProperties();

Когда чанк получают с помощью метода getChunk() Свойства по-умолчанию будут доступны для тегов плейсхолдеров в чанке и будут перезаписаны любым параметровом с тем же именем, находящемся в вызове getChunk('ChunkName',$properties).

Схожий процесс необходим, если вы хотите послать набор параметров установленных в вызове для runSnippet(). Свойства в наборе параметров будут доступны в сниппете, если они введены как параметры в теге сниппета. Снова, посылаемые значения в теге сниппета перезапишут параметры по-умолчанию с тем же именем.

Для других элементов, после того, как вы получили элемент с помощью $modx->getObject(), вы можете получить обработанный вывод используя $element->process(). Это работает для чанков и сниппетов (вообще то, обое getChunk() и runSnippet() методы вызывают метод элемента process(). Как вы могли бы догадаться $element->process($properties) также доступен и параметры по-умолчанию перезаписываются заданными в вызове.

Вам никогда не нужно посылать параметры по-умолчанию в вызовах getChunk(), runSnippet() или process(). Они используются автоматически.

Так как элементы могут иметь более одного набора параметров, прикреплённым к ним, всегда необходимо определять какой набор параметров вам нужен, кроме как если вы хотите, чтобы MODX использовал параметры по-умолчанию.

Этот метод работает также и для ресурсов. После того, как вы получили объект ресурса через $modx->getObject(), поле обработанного контента ресурса станет доступно через $resource->process(). Будьте осторожны не делать этого вызова для текущего ресурса в сниппете содержащегося в данном ресурсе с целью избегания цикла.

Получение сырого содержимого Объекта

В MODX сырое содержимое называется просто «контент». Для чанка контент – это HTML код чанка, включая любые теги плейсхолдеров. Для сниппета или плагина – это действительный код. Вам редко понадобится, может быть совсем никогда, создать сниппет или плагин для изменения MODX БД или помощи в отладке, чтобы получить контент вы можете использовать следующее:

$object->getContent();

Конечно же, вы можете получить контент отдельных полей используя:

$object->get('fieldName')

Взгляните на таблицу ниже для поиска нужный имён полей, но помните, что имена полей могут измениться в следующий версиях (особенно для чанков и сниппетов), именно поэтому getContent() будет лучшим выбором для получения контента объекта, так как он автоматически выставляет правильное имя поля.

Обратите внимание, что обращение к полям объекта напрямую (и особенно их смена) это не то, что обычно делают MODX разработчики. Это не нужно для создания веб-сайта или даже в обычном чанке, сниппете или плагине. Это должно быть сделано теми, кто действительно знает, что им нужно и только тогда, когда они действительно знают, что они делают и когда встроенных функций получения и установки контентов объектов не достаточно. Примером этого может быть пользовательский поиск и процесс замены для сниппета или чанков или системы контроля версий для MODX. Но даже в тех случаях, использование XPDO для доступа к БД может быть лучшим решением.

Информация ниже даст вам лучшее понимание того, как MODX управляет объектами, а также приведён список общих используемых имён полей в каждом объекте. Обратите внимание, что список не полон и отдельные имена полей могут изменятся в дальнейшем (это другая причина почему нужно использовать стандартные функции доступа).

Модификация Объектов

После получения ссылки на объект с помощью $modx->getObject(), вы можете менять значение его полей следующим образом:

$object->set('FieldName', 'Value');
$object->save();

Для изменения или создания основного поля Контента ресурса или элемента (например, поле «контента» ресурсов, контент чанков, код сниппетов), всегда используйте setContent():

$object->setContent('Value');
$object->save();

Вы должны знать, что ссылка на текущий загруженный ресурс доступна через $modx->resource, но вы никогда не должны это использовать для изменения ресурса, потому что это вообще копия ресурса. Всегда получайте ссылку через $modx->getObject() перед попыткой изменения объекта.

Создание новых объектов

Снова, расскажу вам о том, что вы навряд ли будете делать, только если вы не разработчик аддонов создавающий билд-скрипт. Это должно быть сделано с должным вниманием и пониманием того, какие поля необходимы для каждого типа объектов. Вы можете создавать объекты с помощью:

$object = $modx->newObject('modChunk');
$object->set('name', 'ChunkName');
$object->setContent('Это будет содержимое нового чанка.');
$object->set('description', 'Я создал этот чанк через сниппет);
$object->set('category', 'MyChunks');
$object->save(); 

Каждый описанный здесь объект имеет ID и может быть найден по нему, но вы не должны никогда НИКОГДА устанавливать set() ID самостоятельно. Также при изменении или создании объектов, убедитесь, что переменные, которые вы используете для нового значения – являются правильного типа (иными словами того же типа, что и поле вами устанавливаемое). Посмотрите файл /core/model/schema/modx.mysql.schema.xml по поводу особенностей типов БВ, точности и т.д. Ниже представлен список наиболее используемых объектов с их названиями классов и названиями их некоторых полей и типов полей. Связанные объекты доступны через getOne() и getMany() – показаны в списке ниже под полями для каждого объекта:

Основные Объекты и их свойства

Хотел сделать этот список таблицей, но пока показываю в виде списка. Во всей статье на данный список идёт сноска как на таблицу...

Document/Resource (class name = 'modResource')

  • id (int – Идентификатор ресурса)
  • pagetitle (text)
  • isfolder (int 0/1)
  • longtitle (text)
  • description (text)
  • alias (text)
  • published (int 0/1)
  • introtext (text - аннотация)
  • content (text)
  • template (int – id номер шаблона)
  • menuindex (int)
  • searchable (int 0/1)
  • cacheable (int 0/1)
  • createdby (int id номер пользователя)
  • editedby (int id номер пользователя)
  • deleted (int 0/1)
  • deletedby (int id номер пользователя)
  • publishedby (int id номер пользователя)
  • createdon (date – дата первого сохранения)
  • publishedon (date – дата последней смены статуса ресурса на опубликованный)
  • editedon (date – дата последнего редактирования ресурса)
  • menutitle (text)
  • hidemenu (int 0/1)
  • Связанные объекты, доступные через getOne()
    1. Parent (class="modResource")
    2. Template (class="modTemplate")
    3. CreatedBy (class="modUser")
    4. EditedBy (class="modUser")
    5. DeletedBy (class="modUser")
    6. PublishedBy (class="modUser")
    7. ContentType (class="modContentType")
  • Связанные объекты, доступные через getMany()
    1. Children (class="modResource")
    2. TemplateVars (class="modTemplateVar")
    3. TemplateVarTemplates (class="modTemplateVarTemplate")
Чанк (class name = 'modChunk')
  • name (text)
  • description (text)
  • category (int - id номер категории)
  • snippet (text – содержимое чанка)
  • locked (int 0/1 – закрытое для редактирования)
  • Связанные объекты доступные через getOne()
  • Category (class="modCategory")
  • Связанные объекты доступные через getMany()
    1. PropertySets (class="modElementPropertySet")
Сниппет (class name = 'modSnippet')
  • name (text)
  • description (text)
  • category (int - id номер категории)
  • snippet (text – содержимое сниппета)
  • locked (int 0/1 – заблокирован для редактирования)
  • properties (text)
  • Связанные объекты доступные через getOne()
  • Category (class="modCategory")
  • Связанные объекты доступные через getMany()
    1. PropertySets (class="modElementPropertySet")
Плагин (class name = 'modPlugin')
  • name (text)
  • description (text)
  • category (int - category id number)
  • plugincode (text - plugin's contents)
  • locked (int 0/1 - AKA locked for editing)
  • properties (text)
  • disabled (int 0/1)
  • Связанные объекты доступные через getOne()
    1. Category (class="modCategory")
    2. Связанные объекты доступные через getMany()
    3. PropertySets (class="modElementPropertySet")
    4. PluginEvents (class="modPluginEvent")
Шаблон (class name = 'modTemplate')
  • templatename (text)
  • description (text)
  • category (int - id категории)
  • content (text)
  • icon (text)
  • locked (int 0/1)
  • Связанные объекты доступные через getOne()
    1. Category (class="modCategory")
    2. Связанные объекты доступные через getMany()
    3. PropertySets (class="modElementPropertySet")
    4. TemplateVarTemplates (class="modTemplateVarTemplate")
Переменная шаблона (class name = 'modTemplateVar')
  • type (text)
  • name (text)
  • caption (text)
  • description (text)
  • category (int - category id)
  • locked (int 0/1)
  • elements (text)
  • rank (int)
  • display (text)
  • display_params (text)
  • default_text (text)
  • Связанные объекты доступные через getOne()
    1. Category (class="modCategory")
  • Связанные объекты доступные через getMany()
    1. PropertySets (class="modElementPropertySet")
    2. TemplateVarTemplates (class="modTemplateVarTemplate")
    3. TemplateVarResources (class="modTemplateVarResource")
    4. TemplateVarResourceGroups (class="modTemplateVarResourceGroup")
User (class name = 'modUser')
  • username (text)
  • password (text)
  • cachepwd (text)
  • Связанные объекты доступные через getOne()
    1. Profile (class="modUserProfile")
  • Связанные объекты доступные через getMany()
    1. CreatedResources (class="modResource")
    2. EditedResources (class="modResource")
    3. DeletedResources (class="modResource")
    4. PublishedResources (class="modResource")
    5. SentMessages (class="modUserMessage")
    6. ReceivedMessages (class="modUserMessage")
    7. UserSettings (class="modUserSetting")
    8. UserGroupMembers (class="modUserGroupMember")
Профиль пользователя (class name = 'modUserProfile')
  • fullname (text)
  • role (int)
  • email (text)
  • phone (text)
  • mobilephone (text)
  • blocked (int 0/1)
  • blockeduntil (int - date)
  • blockedafter (int - date)
  • logincount (int)
  • lastlogin (int - date)
  • thislogin (int - date)
  • failedlogincount (int)
  • sessionid (text)
  • dob (int - date)
  • gender (int 0/1)
  • country (text)
  • state (text)
  • zip (text)
  • fax (text)
  • photo (text)
  • comment (text)
  • Связанные объекты доступные через getOne()
    1. User (class="modUser")
    2. UserRole (class="modUserRole")

При создании статьи использовались материалы из блога Боба Рея и официальное руководство по MODX Revolution.