Отсутствует связь между кастомными таблицами.
Всем доброго времени суток! Давеча столкнулся с такой проблемой.
Не работает метод getMany(). Уже не знаю что и думать. Буду очень признателен за любую помощь. Спасибо!
xml базы:
Вызов метода getMany() осуществляется в preHook'е сниппета Formit. Сниппет создает плэйсхолдер со списком «Город -> Район города».
Код сниппета:
Не работает метод getMany(). Уже не знаю что и думать. Буду очень признателен за любую помощь. Спасибо!
xml базы:
<?xml version="1.0" encoding="UTF-8"?>
<model package="geolocation" baseClass="xPDOObject" platform="mysql" defaultEngine="MyISAM" version="1.1">
<object class="Areas" table="areas" extends="xPDOSimpleObject">
<field key="town_fk" dbtype="int" precision="10" attributes="unsigned" phptype="integer" null="false" />
<field key="title" dbtype="varchar" precision="255" phptype="string" null="false" />
<field key="is_default" dbtype="enum" precision="'1','0'" phptype="string" null="false" default="0" />
<aggregate alias="Towns" class="Towns" local="town_fk" foreign="id" cardinality="many" owner="foreign" />
<composite alias="Streets" class="Streets" local="id" foreign="area_fk" cardinality="one" owner="owner" />
</object>
<object class="Regions" table="regions" extends="xPDOSimpleObject">
<field key="title" dbtype="varchar" precision="255" phptype="string" null="false" />
<composite alias="Towns" class="Towns" local="id" foreign="region_fk" cardinality="one" owner="owner" />
</object>
<object class="Streets" table="streets" extends="xPDOSimpleObject">
<field key="area_fk" dbtype="int" precision="11" phptype="integer" null="false" />
<field key="title" dbtype="varchar" precision="255" phptype="string" null="false" />
<field key="adress" dbtype="varchar" precision="255" phptype="string" null="false" />
<field key="phonenumber" dbtype="char" precision="12" phptype="string" null="false" />
<field key="is_default" dbtype="enum" precision="'1','0'" phptype="string" null="false" default="0" />
<field key="in_map" dbtype="text" phptype="string" null="false" />
<aggregate alias="Areas" class="Areas" local="area_fk" foreign="id" cardinality="many" owner="foreign" />
</object>
<object class="Towns" table="towns" extends="xPDOSimpleObject">
<field key="title" dbtype="char" precision="20" phptype="string" null="false" />
<field key="region_fk" dbtype="int" precision="10" attributes="unsigned" phptype="integer" null="false" />
<composite alias="Areas" class="Areas" local="id" foreign="town_fk" cardinality="one" owner="owner" />
<aggregate alias="Regions" class="Regions" local="region_fk" foreign="id" cardinality="many" owner="foreign" />
</object>
</model>
Вызов метода getMany() осуществляется в preHook'е сниппета Formit. Сниппет создает плэйсхолдер со списком «Город -> Район города».
Код сниппета:
$out = '';
$towns = $modx->getCollection('Towns',1);
if (!$towns) {
$hook->addError('areas','Не удалось получить список городов');
return false;
}
foreach($towns as $town){
$areas = $town->getMany('Areas');
if (!$areas) {
$hook->addError('areas','Не удалось получить список районов');
return false;
}
foreach($areas as $area){
$out .= '<li>'.$town->get('title').' -> '.$area->get('title').'</li>' ;
}
}
$hook->setValue('areas',$out);
В журнале MODx такая запись:[2015-09-20 08:38:10] (ERROR @ /home/p26419/public_html/aversboden.ru/core/xpdo/om/xpdoobject.class.php: 2266) PHP warning: array_diff_key(): Argument #1 is not an array
Комментарии: 20
Как минимум в схеме вижу одну повторяющуюся ошибку: owner может быть или local или foreign.
В качестве примера и образца брал видео от Ильи Уткина youtu.be/Qkspw8kXwK4?t=164. В нем owner=«owner».
Поменял в своей таблице owner=«owner» на owner=«local»- результат аналогичный…
Поменял в своей таблице owner=«owner» на owner=«local»- результат аналогичный…
А map файлы пересоздали/изменили? MODX не работает со схемой, он работает с готовыми map файлами.
Нет. Дело в том, что я работал с дополнением UICMPGenerator. Он к сожалению сейчас отказывается нормально работать. Не могли бы вы мне подсказать как их пересоздать или где почитать литературу.
Вариант 1.
Ставьте CMPGenerator. Открываете и создаете новый пакет «geolocation». Указываете таблицы, префикс, генерируете и схему и пакет, предварительно сохранив свою старую схему. Далее, в новой схеме прописываете связи aggregate и composite из своей схемы.
Опять открываете пакет в CMPGenerator, только теперь схему генерировать не надо (ставите Нет), только пакет. Сохраняйте. Все.
Вариант 2.
Или вручную — найти все map-файлы и у них поправить все что нужно. Как правило, они лежать в папочке mysql.
Первый вариант самый простой.
Ставьте CMPGenerator. Открываете и создаете новый пакет «geolocation». Указываете таблицы, префикс, генерируете и схему и пакет, предварительно сохранив свою старую схему. Далее, в новой схеме прописываете связи aggregate и composite из своей схемы.
Опять открываете пакет в CMPGenerator, только теперь схему генерировать не надо (ставите Нет), только пакет. Сохраняйте. Все.
Вариант 2.
Или вручную — найти все map-файлы и у них поправить все что нужно. Как правило, они лежать в папочке mysql.
Первый вариант самый простой.
Спасибо за инструкцию! Решил пойти сначала 2 способом. Результата нет. Попробовал 1 способ. Повторил в точности как написано. Результата так и нет =(
Я надеюсь, вы пакет загружаете перед запросами. Если нет, то нужно вставить следующий код перед вызовом ваших объектов.
$path = $modx->getOption('core_path') . 'components/geolocation/model/';
if (!$modx->addPackage('geolocation', $path)) return '[geolocation] Пакет не найден.';
Вставил ваш код. Изменений нет.
Использую вот такие настройки CMPgeneratora:
Код XML-схемы:
Использую вот такие настройки CMPgeneratora:
Код XML-схемы:
<?xml version="1.0" encoding="UTF-8"?>
<model package="geolocation" baseClass="xPDOObject" platform="mysql" defaultEngine="MyISAM" version="1.1">
<object class="Areas" table="areas" extends="xPDOSimpleObject">
<field key="town_fk" dbtype="int" precision="10" attributes="unsigned" phptype="integer" null="false" />
<field key="title" dbtype="varchar" precision="255" phptype="string" null="false" />
<field key="is_default" dbtype="enum" precision="'1','0'" phptype="string" null="false" default="0" />
<aggregate alias="Towns" class="Towns" local="town_fk" foreign="id" cardinality="many" owner="foreign" />
<composite alias="Streets" class="Streets" local="id" foreign="area_fk" cardinality="one" owner="local" />
</object>
<object class="Regions" table="regions" extends="xPDOSimpleObject">
<field key="title" dbtype="varchar" precision="255" phptype="string" null="false" />
<composite alias="Towns" class="Towns" local="id" foreign="region_fk" cardinality="one" owner="local" />
</object>
<object class="Streets" table="streets" extends="xPDOSimpleObject">
<field key="area_fk" dbtype="int" precision="11" phptype="integer" null="false" />
<field key="title" dbtype="varchar" precision="255" phptype="string" null="false" />
<field key="adress" dbtype="varchar" precision="255" phptype="string" null="false" />
<field key="phonenumber" dbtype="char" precision="12" phptype="string" null="false" />
<field key="is_default" dbtype="enum" precision="'1','0'" phptype="string" null="false" default="0" />
<field key="in_map" dbtype="text" phptype="string" null="false" />
<aggregate alias="Areas" class="Areas" local="area_fk" foreign="id" cardinality="many" owner="foreign" />
</object>
<object class="Towns" table="towns" extends="xPDOSimpleObject">
<field key="title" dbtype="char" precision="20" phptype="string" null="false" />
<field key="region_fk" dbtype="int" precision="10" attributes="unsigned" phptype="integer" null="false" />
<composite alias="Areas" class="Areas" local="id" foreign="town_fk" cardinality="one" owner="local" />
<aggregate alias="Regions" class="Regions" local="region_fk" foreign="id" cardinality="many" owner="foreign" />
</object>
</model>
Уже лучше. А теперь осталось разобраться вот с этим
П.С.
$towns = $modx->getCollection('Towns',1);
Судя по названию переменной $towns и методу getCollection запрашивается список городов. Т.е. городов, определенных условием, указанным во втором параметре метода getCollection. И что мы так видим? Единичку. Т.е. вы получаете всего один объект. Теперь читаем что должно быть type: object|array|string
Desc: An xPDOCriteria object or an array.
Т.е. или объект xPDOCriteria или массив или строка (для where).П.С.
Также неплохо было бы проверить, существует ли запись с id = 1
Прошу меня извинить. Данная ошибка возникла в результате пустой xml-таблицы. сейчас подправил все (можете перечитать мой предыдущий комент). И все равно та же ошибка.
Ну я больше не знаю чем помочь.
Попробуйте поэтапно.
1. Проверьте, если ли записи в таблице городов.
2. Если есть, вызов $modx->getCollection('Towns') что-нибудь возвращает?
3. Если да, есть ли запись с id=1
и т.д.
Попробуйте поэтапно.
1. Проверьте, если ли записи в таблице городов.
2. Если есть, вызов $modx->getCollection('Towns') что-нибудь возвращает?
3. Если да, есть ли запись с id=1
и т.д.
1) Записи есть
2) $modx->getCollection('Towns') возвращает массив обьектов Towns
3) Запись с id=1 есть
Спасибо за помощь. Буду пытаться дальше искать багу.
2) $modx->getCollection('Towns') возвращает массив обьектов Towns
3) Запись с id=1 есть
Спасибо за помощь. Буду пытаться дальше искать багу.
Так у вас в схеме для объекта Towns указано cardinality=«one»
<composite alias="Areas" class="Areas" local="id" foreign="town_fk" cardinality="one" owner="local" />
А вы запрашиваете getMany()$areas = $town->getMany('Areas');
Это же отношение записи таблицы Towns к записям из таблицы Areas. Несколько записей Areas ссылаются на одну запись из Towns. Вроде все верно или нет?
Спасибо за мануал. Исправил. Получаю теперь сообщение:
Не удалось получить список районовКод снипета:
$out = '';
$towns = $modx->getCollection('Towns');
if (!$towns) {
$hook->addError('areas','Не удалось получить список городов');
return false;
}
foreach($towns as $town){
$areas = $town->getMany('Areas');
if (!$areas) {
$hook->addError('areas','Не удалось получить список районов');
return false;
}
foreach($areas as $area){
$out .= '<option value="">'.$town->get('title').' - </option>' ;
}
}
$hook->setValue('areas',$out);
Код схемы:<?xml version="1.0" encoding="UTF-8"?>
<model package="geolocation" baseClass="xPDOObject" platform="mysql" defaultEngine="MyISAM" version="1.1">
<object class="Areas" table="areas" extends="xPDOSimpleObject">
<field key="town_fk" dbtype="int" precision="10" attributes="unsigned" phptype="integer" null="false" />
<field key="title" dbtype="varchar" precision="255" phptype="string" null="false" />
<field key="is_default" dbtype="enum" precision="'1','0'" phptype="string" null="false" default="0" />
<aggregate alias="Towns" class="Towns" local="town_fk" foreign="id" cardinality="one" owner="foreign" />
<composite alias="Streets" class="Streets" local="id" foreign="area_fk" cardinality="many" owner="local" />
</object>
<object class="Regions" table="regions" extends="xPDOSimpleObject">
<field key="title" dbtype="varchar" precision="255" phptype="string" null="false" />
<composite alias="Towns" class="Towns" local="id" foreign="region_fk" cardinality="many" owner="local" />
</object>
<object class="Streets" table="streets" extends="xPDOSimpleObject">
<field key="area_fk" dbtype="int" precision="11" phptype="integer" null="false" />
<field key="title" dbtype="varchar" precision="255" phptype="string" null="false" />
<field key="adress" dbtype="varchar" precision="255" phptype="string" null="false" />
<field key="phonenumber" dbtype="char" precision="12" phptype="string" null="false" />
<field key="is_default" dbtype="enum" precision="'1','0'" phptype="string" null="false" default="0" />
<field key="in_map" dbtype="text" phptype="string" null="false" />
<aggregate alias="Areas" class="Areas" local="area_fk" foreign="id" cardinality="one" owner="foreign" />
</object>
<object class="Towns" table="towns" extends="xPDOSimpleObject">
<field key="title" dbtype="char" precision="20" phptype="string" null="false" />
<field key="region_fk" dbtype="int" precision="10" attributes="unsigned" phptype="integer" null="false" />
<composite alias="Areas" class="Areas" local="id" foreign="town_fk" cardinality="many" owner="local" />
<aggregate alias="Regions" class="Regions" local="region_fk" foreign="id" cardinality="one" owner="foreign" />
</object>
</model>
Записи в таблицах есть. Метод почему то не может получить их. Но по крайней мере критическую ошибку не выдает.
Все заработало. Изменил код сниппета:
$towns = $modx->getCollection('Towns');
if (!$towns) {
$hook->addError('areas','Не удалось получить список городов');
return false;
}
foreach($towns as $town){
$areas = $town->getMany('Areas');
if (!$areas) {
$hook->addError('areas','Не удалось получить список районов');
}
foreach($areas as $area){
$out .= '<option value="">'.$town->get('title').' - '.$area->get('title').'</option>' ;
}
}
$hook->setValue('areas',$out);
Убрал return false;
Спасибо вам огромное. Только вот не могу понять почему return срабатывал...?
На здоровье!
Скорее всего, дело не в return, а в кэше. Думаю, если вернуть его обратно, то все будет работать и с ним.
Скорее всего, дело не в return, а в кэше. Думаю, если вернуть его обратно, то все будет работать и с ним.
Увы нет. Почистил кэш. С ретёрном не работает.
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.