Эксперт по MODX
2,4
рейтинг
30 июня 2011 в 01:41

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

MODX*
imageВ данной статье мы разберем следующие вопросы:
  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()
<br>
$obj = 'program';    


/*
Префикс таблиц. Если префикс не отличается от системного, то можно вообще не указывать.
К сожалению, xPDO при генерации не позволяет перечислять имена конкретных таблиц,
которые нам нужны, а позволяет отсеять только по префиксу.
*/
<br>
$tablePrefix='modx_program_';


// Папка, где будет записана XML-схема и все файлы создаваемого объекта

// Путь к файлам класса вы будете потом прописывать в вызове метода $modx->addPackage();
<br>
$Path = dirname(__FILE__).'/model/';


// Файл-схема
<br>
$Schema = $Path.'/'.$obj.'.mysql.schema.xml';


/*******************************************************/


<br>
// Подгружаем основной файл-конфиг сайта или самим придется прописывать все основные настройки
<br>
require_once dirname(dirname(dirname(__FILE__))).'/core/config/config.inc.php';


// Подружаем основной класс MODx
<br>
include_once MODX_CORE_PATH . 'model/modx/modx.class.php';


// Инициализируем класс MODx
<br>
$modx= new modX();


// Инициализируем контекст, если принципиально
<br>
// $modx->initialize('mgr');


// Устанавливаем настройки логирования

// Не обязательно
<br>
$modx->setLogLevel(modX::LOG_LEVEL_INFO);
<br>
$modx->setLogTarget(XPDO_CLI_MODE ? 'ECHO' : 'HTML');


// !!! Обязательно!
<br>
// Подгружаем основной класс-пакер
<br>
$modx->addPackage('transport.modPackageBuilder', '', false, true);


// Указатель типа базы данных (MySQL / MsSQL и т.п.)
<br>
$manager = $modx->getManager();


// Класс-генератор схем
<br>
$generator = $manager->getGenerator();



// Генерируем файл-XML
<br>
// /xpdo/om/mysql/xpdogenerator.class.php

<br>
// public function writeSchema($schemaFile, $package= '', $baseClass= '', $tablePrefix= '', $restrictPrefix= false)
<br>
// $tablePrefix - указываем, если хотим только те таблицы, которые начинаются с этого префикса.

<br>
// $restrictPrefix - указывает true, если хотим получить таблицы только по префиксу

<br>
$xml= $generator->writeSchema($Schema, $obj, 'xPDOObject', $tablePrefix ,$restrictPrefix=true );


// Создает классы и мапы (php) по схеме xml
<br>
$generator->parseSchema($Schema, $Path); 

<br>
<br>
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">



Самое основное, что нам тут понадобится, это:
1.
<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
  ));
  $row->save();

  return ;
}



Вроде бы всё. Если что не ясно, спрашивайте.
Ланец Николай @Fi1osof
карма
13,0
рейтинг 2,4
Эксперт по MODX
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (17)

  • +1
    Было бы неплохо сразу же осветить вопрос о создании своей странички в админке для работы с таблицей (включая интерфейс редактора) используя extjs и последующей работой с этими данными в самой CMF, а то просто от таблицы, даже и доступной через xpdo толку не много.
    • +1
      ну как же толку не много? далеко не все таблицы создаются только для того, чтобы в админке с ними работать через админские интерфейсы.
      Но тему взял на заметку. В дальнейшем вполне возможно и напишу соответствующую тему.
      А пока могу дать для изучения свою систему сбора статистики. Установочный пакет можно скачать тут.
      Между прочим это абсолютно рабочая система сбора статистики, которую я активно использую. Правда она еще не доведена до ума, по этому я не выкладываю на modx.com
      Закидываете этот пакет в папку core/packages/, заходите в управление пакетами -> установить новый -> искать локально. Устанавливаете пакет, обновляете окно и в главном меню появляется Компоненты->SEO: Сбор статистики.
      В общем в этом пакете реализовано все, о чем вы спрашиваете (и пользовательская таблица, и страница в админке на ExtJS и т.п. ).
      Разобраться вам придется со следующими моментами:
      1. Система->Действия. Именно там прописаны пункты главного меню. Для того, чтобы что-то туда можно было добавить, нужно создавать Пространство имен (правда в нашем случае уже все создано, вам только разобраться надо будет)
      2. Пользовательская страница в админке. Основные файлы будут в папке core/components/seo/ Путь к ним прописывается в Действиях
      3. Коннекторы. Отслеживайте Ajax-запросы через FireBug или типа того.
      • 0
        Спасибо, добавил в избранное, изучу.

        Написали бы пост про это — цены бы вам не было, т.к. данный процесс даже на английском толком не освещён, а разобраться всё времени нет. Хотя наверное будет задача разберусь )
        • 0
          Сейчас просто реально некогда. Сижу вот систему документооборота на MODx+MySQL+ExtJS пишу для политического института Путина))), а эта тема очень большая, плюс скриншотов понаделать придется. Хотя тему данную знаю полностью.
          Но постараюсь в ближайшие дни осветить этот вопрос.
    • 0
      Этот вопрос немного освещен здесь.
    • –1
      Вот тут bezumkin все подробно расписал.
  • 0
    Fi1osof, Вы это всё изучили методом тыка?

    Для того, чтобы лучше понимать механизм взаимодействия xPDO с XML-схемой

    XML-схема нужна только на стадии генерации (или обновления) модели с PHP-картами (maps). Когда вы обращаетесь к объекту
    $my_object = $modx->newObject('myObject');

    xPDO взаимодействует именно с этими картами (PHP файлами), а не XML.

    В этой статье всё поставлено с ног на голову. Читайте документацию.
    • 0
      Это не статья с ног на голову, а задачи другие и реализация. В приведенной вами документации описывается как создать XML-файл, описывающий будущие таблицы. Используя этот файл, впоследствии создаются пользовательские таблицы. Но этот XML-файл нужно прописывать вручную. Попробуйте таким образом описать 10 пользовательских таблиц с кучей индексов, первичных и вторичных ключей и т.п. Если опишите и создадите из этого все таблицы без ошибок менее чем за 2 часа, вы герой.
      Мне ЛЕНЬ так много писать!
      Я через phpMyAdmin в легкую создаю нужные мне таблицы со всеми ключами, запускаю скрипт и получаю 100% рабочий XML, который могу впоследствии использовать, и все необходимые php-файлы. И это за считаные минуты. А если мне надо изменить какие-то таблицы, я легко это делаю без риска потери данных, потом делит всех старых файлов и генерация новых. И это минимум времени.
      Так что, могу поспорить, что это два разных подхода при реализации одних и тех же задач. Какой вам использовать — это вам выбирать. А я буду так делать.
      • 0
        Да, такой подход тоже имеет право на жизнь. Я лично не вижу ничего сложного создать руками XML. Для меня это ни чуть не сложнее создания таблицы через phpMyAdmin. Только речь не об этом. Если пишите статью, то надо доскональна изучить тему и не давать ложную информацию (выше я процитировал один кусок).
        • 0
          Так вы цитируйте полнее.
          Для того, чтобы лучше понимать механизм взаимодействия xPDO с XML-схемой, а так же понимать, что прописывается в файле-генераторе, и какие объекты получаете на выходе

          Извините, если я не достаточно понятно выразился. Понятно дело, что используется для генерации.
          И речь шла не о том, что с XML xPDO будет взаимодействовать каждый раз, а о том, чтобы в принципе всегда можно было посмотреть какие имена объектов у нас и какие у них свойства. Хотя бы потому, что имена объектов могут отличаться от имен конечных таблиц.
          Итак,
          1. Попробуйте обвинить меня в том, что все это не работает, о чем я написал. Я вам сразу скажу, что это все работает.
          2. Знаете материал лучше — напишите. На хабре эта тема вообще не была освещена, в том числе и вами, хотя вы, как говорите, вопрос этот знаете досканально.
          • 0
            Хотя бы потому, что имена объектов могут отличаться от имен конечных таблиц.
            Вот именно. У вас получается, что как будто нам заранее не известно название пакета и т.п., хотя мы же сами создаем этот пакет и можем сами назвать его как угодно. XML в данном случае вообще можно не упоминать. Все поля (свойства объекта) вы создали сами в таблице.
            значение атрибута package нам нужно, чтобы знать какой пакет нам вообще нужно подгружать.
            ___
            хотя вы, как говорите, вопрос этот знаете досканально.
            Где я это сказал? Я знаю только то, что написал в комменте.
            • 0
              Сорри, коммент нижу разместился
  • 0
    Все равно не убедили. Вы будете своим методом пользоваться, а я своим. И уверен, кому-нибудь материал тоже будет полезен.
    Дальше не вижу смысла это обсуждать. Как я и говорил, лучше тогда действительно статью напишите про ваш метод. А просто спорить не конструктивно
  • 0
    Если я создаю свою таблицу, то возможно ли забирать с неё данные (строки) такими сниппетами как гетпэйдж? Кешыруются ли запросы?
    • 0
      Пока для новой таблицы на будут сгенерированы map-файлы, с вашими новыми таблицами нельзя будет работать в принципе, в том числе и сниппетом getPage.
      Про то, кэшируется ли результаты выполнения getPage, не подскажу, потому что им не пользуюсь в принципе, но учитывая то, что он работает в связке с тем же getResource, результаты нужно кэшировать и для одного, и для другого. ИМХО лучше самому управлять кэшем с помощью modCacheManager.
      • 0
        map файлы это и есть xml схема и пхп файлы о которых говорили?
        • 0
          Map-файлы, это PHP-файлы, используемые для работы с БД, в которых описана структура таблиц. Они имеют расширение map.inc.php Их вы можете увидеть в папке /core/model/modx/mysql
          XML используется для генерации всех этих php-файлов.
          Вы можете или самостоятельно описать вашу будущую таблицу в XML, и уже используя его создать пользовательскую таблицу и сгенерировать эти файлы, или создать таблицу вручную и запустить скрипт на генерацию всех файлов, как это описано тут.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.