Давно не было новых уроков. Начнем новую серию экспериментов связанных теперь уже с дополнительными объектами в MODX. Это довольно часто используется, особенно, если вы хотите хранить в базе данных какую-то дополнительную информацию. Например, компонент Redirector хранит все редиректы в отдельной таблице. И мы научимся делать так же)
Если вы хотите хранить дополнительные данные в дополнительной таблице, вам нужно создать свое дополнение. В MODX дополнения называются компонентами или пакетами.
Начнем мы с простенького:
На сайте есть страница с картой России. На этой карте надо вывести метки в тех городах, где есть филиалы нашей организации. Карта сделана картинкой, метки имеют абсолютное позиционирование. Все бы ничего, но организация бурными темпами развивается, постоянно появляются новые филиалы, и хорошо бы упростить добавление меток на карте.
Будем считать, что MODX вы уже установили))) Ставим дополнение Console, чтобы удобнее было экспериментировать, и CMPGenerator, который поможет нам рассказать MODX'у о нашей дополнительной таблице.
Координаты меток будем хранить в отдельной таблице, так что, заходим в phpMyAdmin и создаем новую таблицу modx_map_item со следующими полями:
- id — INT(10), AUTO_INCREMENT
- title — VARCHAR(250), utf8_general_ci, NULL - да, По умолчанию - NULL
- coord_x — INT(10), NULL - да, По умолчанию - NULL
- coord_y — INT(10), NULL - да, По умолчанию - NULL
После этого заходим в админку, Компоненты->CMPGenerator. Нажимаем Create package. Заполняем поля: Package Name - Map Database Name - оставляем пустым (или пишем имя вашей базы данных) Tables - modx_map_item Prefix - modx_ Build Schema - Да Build Package - Да
и сохраняем. Все, модель сгенерирована, все данные о нашей таблице у MODX'а есть. Можете посмотреть в папке /core/components/Map/
Открываем Компонеты->Console и пробуем создать объект:
<?php $item = $modx->newObject('MapItem'); $item->save();Упс:
Could not load class: MapItem from mysql.mapitem.
Fatal error: Call to a member function save() on a non-object in /home/.../public_html/core/components/console/processors/exec.class.php(19) : eval()'d code on line 3
Данные у MODX'a-то есть, но он не знает, что они у него есть))
Переходим в настройки системы и создаем новый параметр (если его еще нет) extension_packages. Заполняем только "Ключ" (extension_packages) и "Значение":
[{"Map":{"path":"[[++core_path]]components/Map/model/"}}]
Если у вас в этом параметре уже что-то записано, вам надо дописать этот код в конец через запятую, вот так:
[{...здесь уже что-то есть...},{"Map":{"path":"[[++core_path]]components/Map/model/"}}]
иначе сломаются другие компоненты)))
Можно делать это не руками, а предоставить право MODX'у самому. Для этого надо в Console выполнить следующий код:
$modx->addExtensionPackage('Map', '[[++core_path]]components/Map/model/');и системный параметр будет прописан правильно.
Теперь пробуем опять создать объект. Ошибки нет. Идем в phpMyAdmin и видим, что появилась новая строка. Поздравляю, теперь вы можете работать с этим новым объектом с помощью xPDO, как с любым другим объектом MODX.
Оригинал статьи: http://community.modx-cms.ru/blog/modx-xpdo/11035.html
В таком случае данные о компоненте будут погружаться только там, где они действительно нужны, а не на всех страницах сайта/админки. И да, для меток есть форк StoreLocator — MarkerGoogleMaps.
Однако у Василия есть особенность изложения материала — он не всегда указывает с каким файлом и в какой директории работает в данный момент, а это очень важно.
К тому же я не увидел, возможно ли сделать общую таблицу для создания связей между объектами.
Скажем у вас есть таблица ms2_products и есть сторонняя таблица в которой хранится ProductID и информация для сторонней системы, где ProductID — ключ указатель на запись в таблице.
Как с Вами можно связаться для коммерческого сотрудничества? (консультации/заказы)
есть вопрос: можно ли теперь этот объект добавить в дерево ресурсов и как?
(в схеме почему-то нет поля с ключем id, все правильно?)
настроил путь: extension_packages
[{«Datearr»:{«path»:"[[++core_path]]components/Datearr/model/"]}}
Но упорно выдает ошибку
Could not load class: Datearr from mysql.datearr.
Fatal error: Call to a member function save() on a non-object in /Applications/MAMP/htdocs/test/core/components/console/processors/exec.class.php(19): eval()'d code on line 3
Уже голову сломал подключая таблицы различными методами, итог — не работает.
Может подскажите куда смотреть хотя бы?
В моем случает класс имел название DaDatearr по названию таблицы modx_da_datearr
хотя в префиксы я указывал modx_da_, не понимаю этого момента
У меня такой вопрос — а можно после того как модель сгенерирована удалить CMPGenerator?
Есть у меня стойкая нелюбовь к «лишним» компонентам.
Для потомков отмечу: если на сайте установлен AjaxManager, то после проведения всех операций, почему-то не создаются новые объекты. Причём ни в консоли, ни на сайте. Почти час бился с выскакивающей ошибкой, пока не деинсталировал AjaxManager и не повторил процесс.
После создания модели, вернул AjaxManager. Всё работает. Так что его нужно «выключать» только на время создания модели, почему-то.
Странно очень, при создании пакета через CMPGenerator появляется сообщение: время действия сессии истекло, запрашивается логин и пароль, после ввода которых сообщение появляется снова. После обновления страницы в админку больше никак не зайти, после ввода логина и пароля ничего не происходит. Также появляются проблемы в работе сайта: перестают работать практически все сниппеты. Версия MODX 2.2.14
Если, после того, как пакет уже сгенерирован в CMPGenerator, в созданную таблицу были добавлены столбцы, пакет нужно перегенерировать. Это делается по щелчку правой кнопкой на названии пакета в CMPGenerator, в выпадающем меню выбирается «Build» и — «Сохранить».
modx_mandoki_lessons
modx_mandoki_groups
modx_mandoki_users
надо чтобы в каждую из них создавался объект средствами модх, подскажите пожалуйста, как лучше сделать это?
Отказывается удалять. Может что-то предварительно нужно прописать?..
Ещё бред какой-то творится… Вот такой код ничего совершенно не выводит, хотя должен выводить id-шки строк таблицы:
Хотя в этой таблице есть ещё поле id — уникальное (auto_increment)…
Вылезает ошибка:
«Could not load class: ProductItem from mysql.productitem.»
версия модекса «MODX Revolution 2.2.12-pl»
Как же мне убедить modx принять свои таблицы?
Выяснилось, что при генерации пакетов компонентом CMPGenerator префиксы таблиц, отличных от 'modx_', не работают: не получаются данные из базы и не сохраняются.
xPDO в любом случае использует префикс 'modx_'.
То есть, например, есть у меня таблица mecha_robot_makers, я в мастере создания (в CMPGenerator) ввожу имя таблицы mecha_robot_makers и префикс mecha_. В сниппете проверяю имя используемой в классе таблицы:
$myRow = $modx->newObject('RobotMakers');
echo $myRow->_table;
и на странице выводится 'modx_robot_makers'.
Возможно, я неправильно понял смысл префиксов или того, что именно нужно вводить в поля при генерации пакета.
Переименовал таблицу (сделал префикс modx_), и все заработало.
joxi.ru/4DmBEG1uK0ejrP
[2015-07-05 22:01:46] (ERROR @ /manager/components/console/connectors/console.php)
Error 42S02 executing statement:
INSERT INTO `fgrx_map_item` () VALUES ()
Array
(
[0] => 42S02
[1] => 1146
[2] => Table 'XXXXXXXXXX.fgrx_map_item' doesn't exist
)
А таблицу я создал по вашей инструкции modx_map_item, она появилась в базе, в генераторе тоже указал modx_map_item, а при запросе <?php
$item = $modx->newObject('MapItem');
$item->save();
почему то требует fgrx_map_item… Пришлось его удовлетворить и создать новую таблицу fgrx_map_item.
Предыдущий автор тоже на похожую проблему жалуется. Скорее всего генератор некорректно работает при префиксах отличных от modx_ и берет префикс по умолчанию из системы, а не из «Prefix»
[2015-07-05 22:27:42] (ERROR @ /manager/components/console/connectors/console.php)
Error 42S02 executing statement:
INSERT INTO `fgrx__exam_sheet` () VALUES ()
Array
(
[0] => 42S02
[1] => 1146
[2] => Table 'XXXX.fgrx__exam_sheet' doesn't exist
)
В первом случае просто поменял название таблицы на fgrx_map_item, но это же не правильно. Нужно где то в настройках менять. В настройках генератора поменял обратно на fgrx, никаких изменений, та же ошибка с двойным подчеркиванием.
joxi.ru/j1A59nQu8991AE
Название таблицы нормальное, откуда берет «нижнее подчеркивание» лишнее.
Сделал все как написано
Пытаюсь повторить вашу инструкцию, создаю таблицу, делаю пакет в CMPGenerator. Схема делается, папка появляется. Потом в консоли делаю $modx->addPackage('Map', $modx->getOption('core_path').'components/Map/model/','modx_map_');
Но когда пытаюсь вызвать $item = $modx->newObject('MapItem');
$item->save(); в консоли, то получаю
Could not load class: MapItem from mysql.mapitem.
Это я делаю что-то не так, или с времён написания статьи что-то поменялось?
===
(ERROR @ /papka/assets/components/cmpgenerator/connector.php) Schema /home/u111/site.ru/www/papka/core/components/Map/model/Map/Map.mysql.schema.xml contains no valid object elements.
===
Куда копать, в чем причины? Помогите, пожалуйста. Хочу отметить, что site.ru/www/papka именно так. Modx установлен в поддиректорию papka. А файлы самого сайта (другого) лежат в папке site.ru/www.
Спасибо.
У нас есть:
таблица modx_hoststat
package: HostStat
Выполняем:
В итоге:
Fatal error: Call to a member function toArray() on array in…
Что с этим делать — непонятно…
Писать вначале $modx->addPackage('HostStat', $modx->getOption('core_path').'components/HostStat/model/','modx_'); пробовал, не помогает.
Вам нужно в getObject указывать именно такую формулировку, как в кавычках.
Но если вы уже сделали два каталога, придётся писать плагин, который при сохранении товаров будет отправлять запрос на другой сайт, а другой сайт должен на этот запрос среагировать — изменить соответствующие поля. Это сложнее, так как придётся думать ещё и над безопасностью, чтобы нельзя было с другого сайта или вручную отправить такой запрос и всё на сайтах поломать.
Готового решения ни по первому варианту, ни по второму я, к сожалению, не видел. Если есть бюджет, можно попробовать составить ТЗ и дать объявление о работе на modx.pro/work/ Если оценить примерно, такой функционал может стоить от 3 800 до 7 000…
У меня появился вопросик по синхронизации, товары по свойствам у меня синхронизировать вышло а вот теперь задача стоит еще и 2 ТВшки синхронизировать.
Пишу такой код:
в лог получаю значение то что надо с другой базы, но вот записать в нее таким кодом:
не выходит.
в сети ничего не могу найти(доку xPDO уже пересмотрел несколько раз) что бы помогло решить проблемму, вы не подскажете в чем косяк или куда хоть рыть?
P.S linux mint 17, Chromium 53
Вот статейка для изучения: Запросы на UPDATE, DELETE и т.п., а так же отладка чистых SQL-запросов, выполняемых через PDO
[2017-04-23 21:26:50] (WARN @ C:\home\htdocs.modx\core\xpdo\xpdo.class.php: 667)
Could not load metadata map geodata/mysql/geodata.map.inc.php for class GeoData from geodata.mysql.geodata
Подскажите, пожалуйста, в чем здесь проблема?
Спасибо
нужно было в файле: C:\home\htdocs.modx\core\components\geodata\model\geodata\mysql\geodata.map.inc.php сменить регистр, т.е.:
Было так
Стало так:
а в extension_packages нужно прописать
Тема довольно старая, но есть вопрос, который упорно не хочет решаться.
В phpMyAdmin создал малюсеньку тестовую табличку:
Установил CMPGenerator. По вашему мануалу выше создал новый компонент. Структура со схемой создались замечательно. В консоле код:
тоже отрабатывает и данные в таблицу вносятся.
Далее по этому мануалу установил MIGX, чтобы сохраненные данные можно было отображать в админке. Создал пункт в верхнем меню, создал конфигурацию:
по пункту меню начала отображаться болванка, но сами данные из базы никак не хотят отображаться, что только ни делал! По мануалу выше всё должно сработать с первого раза, но… Самое интересное, что при клике на кнопке «Добавить элемент», ввожу данные в поля «имя» и «сообщение» и данные успешно заносятся в базу! Т.е. связь с базой через контроллер настроена правильно. Не понию, в чем ошибка..? Кэши многократно чистил и CMS`ки и браузера — ничего. Можете подсказать?
например map_item, map_user,map_control
Error HY000 executing statement:
INSERT INTO `modx_okved_h_first` () VALUES ()
Array
(
[0] => HY000
[1] => 1364
[2] => Field 'name' doesn't have a default value
)
Делал все как в статье, модель в components появилась