Хранить объекты будем в базе данных MODX. Для этого создадим в ней табличку с таким же префиксом, как и у других таблиц:
CREATE TABLE `modx_things_names` ( `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, `name` VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, `description` TEXT CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, `active` TINYINT(1) UNSIGNED NOT NULL DEFAULT 1, PRIMARY KEY (`id`), INDEX (`active`) ) ENGINE=MyISAM CHARSET=utf8 COLLATE utf8_general_ci;
Ну и можно через PhpMyAdmin заполнить тестовыми данными
Чтобы MODX мог получать данные из нашей таблицы, ему надо о ней «рассказать». Для этого нужно создать xPDO-модель. Создаём папку /core/components/things/model/things/ и в ней файл metadata.mysql.php
<?php $xpdo_meta_map = array( 'xPDOSimpleObject' => // Наши объекты будут расширять xPDOSimpleObject array( 0 => 'ThingsName', // Придумываем название класса для наших объектов ), );
Если мы создаём несколько таблиц в рамках одного дополнения, прописываем все эти таблицы в нашем файле. Теперь для каждой таблицы нужно создать 3 файла:
/core/components/things/model/things/thingsname.class.php
<?php class ThingsName extends xPDOSimpleObject {}
/core/components/things/model/things/mysql/thingsname.class.php
<?php require_once (dirname(dirname(__FILE__)) . '/thingsname.class.php'); class ThingsName_mysql extends ThingsName {}
/core/components/things/model/things/mysql/thingsname.map.inc.php
В этом файле нужно описать все поля объекта и его связи.
<?php // Указываем, к какому объекту относится описание $xpdo_meta_map['ThingsName'] = array( 'package' => 'things', 'version' => '1.1', 'table' => 'things_names', // Имя соответствующей таблицы 'extends' => 'xPDOSimpleObject', 'fields' => // Список полей объекта array( 'name' => '', 'description' => '', 'active' => 1, ), 'fieldMeta' => array( // Описываем свойства каждого поля 'name' => array( 'dbtype' => 'varchar', // Тип поля в БД 'precision' => '255', // Длина поля 'phptype' => 'string', // Тип поля в PHP 'null' => false, // Допустимо ли значение NULL 'default' => '', // Значение по умолчанию ), 'description' => array( 'dbtype' => 'text', 'phptype' => 'string', 'null' => true, 'default' => '', ), 'active' => array( 'dbtype' => 'tinyint', 'precision' => '1', 'phptype' => 'boolean', 'null' => true, 'default' => 1, ), ), );
Этого достаточно, чтобы следующий код успешно отработал в любом сниппете:
<?php $modx->addPackage('things', MODX_CORE_PATH . 'components/things/model/'); $things = $modx->getCollection('ThingsName'); $output = array(); foreach ($things as $thing) { $output[] = $thing->name; } return implode(PHP_EOL, $output);
Но нам нужно, чтобы список объектов был получен в процессоре getlist, чтобы вывести потом в табличке.
Можно вызывать метод addPackage в процессоре, но процессоров у нас потом будет несколько, поэтому вызовем этот метод в коннекторе /assets/components/things/connector.php:
<?php $base_path = dirname(__FILE__); while (!file_exists($base_path . '/config.core.php')) { $base_path = dirname($base_path); } require_once $base_path . '/config.core.php'; require_once MODX_CORE_PATH . 'config/' . MODX_CONFIG_KEY . '.inc.php'; require_once MODX_CONNECTORS_PATH . 'index.php'; // Подключаем модель наших объектов $modx->addPackage('things', MODX_CORE_PATH . 'components/things/model/'); $modx->request->handleRequest(array( 'processors_path' => MODX_CORE_PATH . 'components/things/processors/', 'location' => '', ));
Теперь в процессоре мы можем получить список всех объектов, подставив свойства limit и start:
<?php class ThingsGetListProcessor extends modProcessor { public function process() { $array = array(); // Создаём запрос $q = $this->modx->newQuery('ThingsName'); // Узнаём общее количество объектов $total = $this->modx->getCount('ThingsName', $q); // Передаём в запрос start и limit $limit = $this->getProperty('limit'); $start = $this->getProperty('start'); $q->limit($limit, $start); // Получаем объекты и добавляем их в массив $objects = $this->modx->getCollection('ThingsName', $q); foreach ($objects as $object) { $array[] = $object->toArray(); } // Отдаём данные в виде массива табличке ExtJS return json_encode(array( 'success' => true, 'total' => $total, 'results' => $array )); } } return "ThingsGetListProcessor";
Как ни удивительно, для таких процессоров в MODX тоже есть заготовки. Всё, что мы прописали здесь (и даже немного больше) уже прописано в классе modObjectGetListProcessor. Мы можем унаследоваться от него, указав только нужный нам класс объекта:
<?php // Меняем название процессора — просто для удобства class ThingsNameGetListProcessor extends modObjectGetListProcessor { public $classKey = 'ThingsName'; // Класс объекта public $defaultSortField = 'id'; // По какому полю сортировать } return "ThingsNameGetListProcessor";
В табличке выведем новые поля, которые есть у наших объектов:
Things.grid.Names = function (config) { config = config || {}; Ext.apply(config, { columns: [ {dataIndex: 'id', width: 150, header: 'ID'}, {dataIndex: 'name', width: 250, header: 'Name'}, // Добавляем новые колонки {dataIndex: 'description', width: 500, header: 'Description'}, {dataIndex: 'active', width: 100, header: 'Active'} ], autoHeight: true, viewConfig: { forceFit: true, scrollOffset: 0 }, url: Things.config.connector_url, action: 'mgr/thing/getlist', // Добавляем новые поля fields: ['id','name', 'description', 'active'], paging: true, pageSize: 1 }); Things.grid.Names.superclass.constructor.call(this, config); } Ext.extend(Things.grid.Names, MODx.grid.Grid); Ext.reg('things-grid-names', Things.grid.Names);
У колонок можно указать renderer — это функция, которая определяет, как оформить поле в зависимости от его значения:
// ... {dataIndex: 'active', width: 100, header: 'Active', renderer: function(value) { if (value) { // Если значение поля == true return '<span class="green">Yes</span>'; } else { // Иначе return '<span class="red">No</span>'; } }} // ...
Так же renderer можно использовать, чтобы отобразить картинку, если в базе хранится её адрес:
// ... {dataIndex: 'image', width: 100, header: 'Image', renderer: function(value) { return '<img src="' + value + '">'; }} // ...
На этом работу с табличкой, думаю, закончим. В следующих уроках попробуем разобраться с окнами, чтобы создавать или редактировать наши объекты.
При вызове сниппета ничего не происходит, в логах ошибка:
P.S. ThingsName заменил на FormconstructorName
Если интересно, то могу дать доступ в админку.
Вот этот файл thingsname.map.inc.php должен лежать в
а у тебя в статье
/core/components/things/model/things/things/thingsname.map.inc.php
на:
/core/components/things/model/things/mysql/thingsname.map.inc.php
Я часа два сидел и не мог понять, почему у меня не работает))
phptype' => 'text' не существует, есть phptype' => 'string'
Пишет что процессор не найдет. Если вместо params поставить baseParams то выводятся все ресурсы со всех родителей, как будто выставлен родитель = 0. Подскажите как можно в процессор передать значения?