Николай Ланец
1 июля 2013 г., 13:36

Пользовательские таблицы в MODx Revolution

Так как постоянно слышу вопросы по поводу пользовательских таблиц и объектов в xPDO, делаю репост своей очень старой статьи на хабре. Пишу сразу с дополнениями, чтобы полностью описать что и для чего делается. Хотя та статья писалась давно, но метод до сих пор актуальный, и я им до сих пор часто пользуюсь. Так что всем новичкам советую сразу в избранное добавлять.
Сразу уточню: данный метод максимально подойдет именно новичкам, но тем, которые хоть как-то плавают в SQL, потому что если вы даже не умеете создавать таблички через phpMyAdmin, то сначала следует изучить именно основы MySQL и научиться создавать таблички и писать простейшие SQL-запросы, и только потом уже сюда.
Еще уточнение: многие считают, что правильно создавать вручную XML с описанием БД, а потом уже из нее генерировать конечные объекты. Я с этим спорить не буду. Но это более сложная процедура, и лично мне ни разу не понадобилась. Мы рассмотрим более простой метод: создание своих таблиц сразу в базе данных, а потом генерацию скриптом конечных объектов и XML с описанием модели, в который, кстати, можно уже дописать вручную связи таблиц и сгенерировать уже объекты со связями.
Итак, задача: Создать свои таблицы и иметь возможность формировать к ним запросы через xPDO и API MODX. То есть, к примеру, создать таблицу modx_mypackage_my_table и потом иметь возможность выполнять типа этого:
$obj = $modx->newObject('MyTable'); $obj->set('name', 'Калинка'); $obj->save(); // Или $obj = $modx->getObject('MyTable', array( 'name' => 'Калинка' )); print $obj->get('id');
Думаю, задача всем ясна.
Теперь немного обобщенной теории, что и как нам надо будет сделать. 1. Создаем нужные нам таблицы в базе данных через phpMyAdmin (или кто что использует для работы с БД). Только сразу имейте ввиду, что чтобы было без гемора, префиксы для таблиц надо задавать отличающиеся от MODX-префиксов. К примеру, если у MODX префикс modx_, то задавайте modx_myprefix_ или типа того. 2. Генерируем скриптом конечную модель с файлами-классами. 3. Перед выполнением запросов к объектам или подключаем пакет через $modx->addPackage(), или методом, описанным здесь. 4. Все, можно работать с объектами.
Сама статья с хабра
В данной статье мы разберем следующие вопросы:
  1. Создание пользовательских таблиц для MODx Revolution.
  2. Генерация XML-схемы и php-файлов-классов для xPDO.
  3. Работа с пользовательскими таблицами.
Одна из самых больших сложностей в переходе с Evolution на Revolution — это xPDO ИМХО. Ведь как раньше было просто: залез в мускул через phpMyAdmin, создал табличку, и работаешь с ней, отправляя чистые SQL-запросы через $modx->db. Теперь же любые изменения в базе данных ни сколько не беспокоят $modx, кроме как полный drop таблиц и т.п. Как связаны между собой xPDO и MODx (а точнее $modx), я написал тут. Считаю сложности в работе с пользовательскими таблицами в MODx Revolution — немалым препятствием для многих программистов. Но на самом деле, все не так уж и сложно. Весь рассматриваемый далее алгоритм в трех словах:
  1. Так же через phpMyAdmin (или другой удобный используемый инструмент) создаем нужные нам таблицы
  2. Используя прилагаемый ниже код генерируем необходимые для работы xPDO файлы
  3. Используя метод $modx->addPackage() подгружаем в нужном месте наш новый класс и уже работаем с нашими таблицами через методы $modx->getObject(), $modx->getCollection() и т.п.
Итак, необходимый нам для генерации файлов код (Исходник тут):
<?php /*******************************************************/ /* Конфиги нашей схемы */ /*******************************************************/ // Имя Класса. Так будет потом называться Класс при вызове $modx->addPackage() $obj = 'program'; /* Префикс таблиц. Если префикс не отличается от системного, то можно вообще не указывать. К сожалению, xPDO при генерации не позволяет перечислять имена конкретных таблиц, которые нам нужны, а позволяет отсеять только по префиксу. */ $tablePrefix='modx_program_'; // Папка, где будет записана XML-схема и все файлы создаваемого объекта // Путь к файлам класса вы будете потом прописывать в вызове метода $modx->addPackage(); $Path = dirname(__FILE__).'/model/'; // Файл-схема $Schema = $Path.'/'.$obj.'.mysql.schema.xml'; /*******************************************************/ // Подгружаем основной файл-конфиг сайта или самим придется прописывать все основные настройки require_once dirname(dirname(dirname(__FILE__))).'/core/config/config.inc.php'; // Подружаем основной класс MODx include_once MODX_CORE_PATH . 'model/modx/modx.class.php'; // Инициализируем класс MODx $modx= new modX(); // Инициализируем контекст, если принципиально // $modx->initialize('mgr'); // Устанавливаем настройки логирования // Не обязательно $modx->setLogLevel(modX::LOG_LEVEL_INFO); $modx->setLogTarget(XPDO_CLI_MODE ? 'ECHO' : 'HTML'); // !!! Обязательно! // Подгружаем основной класс-пакер $modx->addPackage('transport.modPackageBuilder', '', false, true); // Указатель типа базы данных (MySQL / MsSQL и т.п.) $manager = $modx->getManager(); // Класс-генератор схем $generator = $manager->getGenerator(); // Генерируем файл-XML // /xpdo/om/mysql/xpdogenerator.class.php // public function writeSchema($schemaFile, $package= '', $baseClass= '', $tablePrefix= '', $restrictPrefix= false) // $tablePrefix - указываем, если хотим только те таблицы, которые начинаются с этого префикса. // $restrictPrefix - указывает true, если хотим получить таблицы только по префиксу $xml= $generator->writeSchema($Schema, $obj, 'xPDOObject', $tablePrefix ,$restrictPrefix=true ); // Создает классы и мапы (php) по схеме xml $generator->parseSchema($Schema, $Path); print "<br /><br />Выполнено";
Заливаем этот файл на сервер, прописываем ему правильно пути к конфигу MODx-а, и директории, где будут созданы сгенерированные файлы. Обращаемся к файлу через браузер. В результате в указанной папке должны быть созданы xml-файл, в котором будут описаны наши таблицы и php-файл. Эти файлы, если очень надо, можно переместить в другую папку, где вы решите хранить свой новый Класс. В дальнейшем эти файлы всегда будут нужны для работы со своими таблицами.
Теперь вы можете работать со своими таблицами. Для того, чтобы лучше понимать механизм взаимодействия xPDO с XML-схемой, а так же понимать, что прописывается в файле-генераторе, и какие объекты получаете на выходе, привожу свою заметку по данному вопросу. Честно сказать, по началу без нее было просто никак…
1. Подключение пакетов и выполнение запросов к схеме
1.1 Выборка записей из таблицы
Первое, что нужно сделать, это разобраться что вообще нужно для того, чтобы обратиться к схеме. Для этого изучим XML-файл. Вот основной блок созданой нами схемы:
<model package="testtbl" baseClass="xPDOObject" platform="mysql" defaultEngine="MyISAM" version="1.1"> <object class="Tbl" table="tbl" extends="xPDOObject"><param name="wmode" value="opaque"></param>
Самое основное, что нам тут понадобится, это:
<model package="testtbl"
значение атрибута package нам нужно, чтобы знать какой пакет нам вообще нужно подгружать. В данном случае это testtbl. Вызывать пакет будем так:
$modx->addPackage( $package, $path, $prefix); // !!! Проверка в функции addPackage не канает, так как проверяется только присутствие названия пакета в принципе и чтобы указанный путь был директорией, и всё.
Рассмотрим внимательней параметры. $package. Название пакета. В нашем случае как раз testtbl $path. Путь к каталогу пакета (в котором есть XML-файл и папка по названию Объекта, в котором все PHP-файлы) $prefix. Если при создании схемы указывался префикс, отличный от дефолтового, то обязательно нужно его указать.
Есть еще одна маленькая хитрость, как точно определить необходимый префикс. Формула: $prefix = $fullTableName$tableName; Тут $fullTableName — это полное имя таблицы базы данных, к которой обращаемся, $tableName — значение атребута table тега <object нашего файла XML
Выполняем запрос:
$result = $modx->getCollection('Tbl'); foreach($result as $row){ print "<br />Next:". $row->get('columnName'); }
1.2 Создание новой записи в таблице
private static function testCreateRows(){ $pkg = 'testtbl'; $modx->addPackage( 'testtbl', $Path , 'modx_kl_test')) ; $row = $modx->newObject('Tbl'); $row->fromArray(array( 'id' => 5 )); return $row->save(); }

Добавить комментарий