Задание. Написать сниппет, который выводит на страницу заголовки, аннотации и даты публикации всех новостей, если их всего пять или меньше, а если новостей больше пяти, пусть выводит содержание ресурса «Новости» (того самого контейнера, который является родительским ресурсом всех новостей).
Допустим, id ресурса с новостями 22. Тогда получить все дочерние ресурсы с заголовками, аннотациями и пр. мы можем так:
$where = array('parent' => 22);
$resources = $modx->getCollection('modResource',$where);
foreach ($resources as $res) {
$output .= '<h2>'.$res->get('pagetitle').'</h2>';
$output .= '<p>'.$res->get('introtext').'</p>';
$output .= '<p><small>Дата: '.$res->get('publishedon').'</small></p>';
}
return $output;Теперь добавим в наш код условие с количеством ресурсов:
$where = array('parent' => 22);
$resources = $modx->getCollection('modResource',$where);
if (count($resources) > 5) {
} else {
foreach ($resources as $res) {
$output .= '<h2>'.$res->get('pagetitle').'</h2>';
$output .= '<p>'.$res->get('introtext').'</p>';
$output .= '<p><small>Дата: '.$res->get('publishedon').'</small></p>';
}
}
return $output;Ну и, наконец, выводим контент ресурса «Новости», если самих новостей получилось больше пяти:$where = array('parent' => 22);
$resources = $modx->getCollection('modResource',$where);
if (count($resources) > 5) {
$res = $modx->getObject('modResource',22);
$output = $res->get('content');
} else {
foreach ($resources as $res) {
$output .= '<h2>'.$res->get('pagetitle').'</h2>';
$output .= '<p>'.$res->get('introtext').'</p>';
$output .= '<p><small>Дата: '.$res->get('publishedon').'</small></p>';
}
}
return $output;G+
Объектная
$where = array('parent' => 22); $resources = $modx->getCollection('modResource',$where);Данный код выведет непосредственных потомков ресурса с id=22.А как сделать рекурсивный вывод всех ресурсов находящихся в папке с id=22?
520 строчка: public function getData() { $depth = !empty($this->_config['level']) ? $this->_config['level'] : 10; $ids = $this->getChildIds($this->_config['id'],$depth); $resourceArray = array(); ...О, у Wayfinder'а есть метод getChildIds, по названию можно предположить, что он возвращает id-шники дочерних ресурсов. Ищем его:485 строчка: public function getChildIds($startId = 0,$depth = 10) { $ids = array(); if (!empty($this->_config['contexts'])) { $contexts = explode(',',$this->_config['contexts']); $contexts = array_unique($contexts); $currentContext = $this->modx->context->get('key'); $activeContext = $currentContext; $switched = false; foreach ($contexts as $context) { if ($context != $currentContext) { $this->modx->switchContext($context); $switched = true; $currentContext = $context; } $contextIds = $this->modx->getChildIds($startId,$depth); if (!empty($contextIds)) { $ids = array_merge($ids,$contextIds); } } ...Стоп, $this->modx->getChildIds($startId,$depth);, значит, у MODX есть свой метод getChildIds, будем использовать его. Если поискать, можно найти, где он находится: на 726 строчке класса самого MODX.Таким образом, код, который получает все дочерние ресурсы будет выглядеть как-то так:
$ids = $modx->getChildIds(22,50); $where = array('id:IN' => $ids); $resources = $modx->getCollection('modResource',$where);Я думаю, уровень вложенности 50 вам хватит?)) Но лучше поставить тот уровень вложенности, который вам подойдет.А теперь посмотрим на задачу — зачем нам получать все эти объекты? Может, нам как раз надо получить id-шники и подставить в запрос как дополнительное условие? Тогда нам нужна лишь первая строчка.
<?php $ids = $modx->getChildIds(9,3); $where = array( 'id:IN' => $ids ); $resources = $modx->getCollection('modResource',$where); foreach ($resources as $k => $res) { $output .= ''.$k.','; } print $output;Если в случае примера «ближайших» потомков всё в порядке. то в этом случае получаю серьёзные ошибки(ERROR @ core/xpdo/om/xpdoquery.class.php : 739) Encountered empty IN condition with key id (ERROR @ /core/xpdo/om/xpdoobject.class.php : 240) Error 42000 executing statement: Array ( [0] => 42000 [1] => 1064 [2] => You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ')' at line 1 ) (WARN @ core/components/console/processors/exec.class.php(15) : eval()'d code : 10) PHP notice: Undefined variable: outputПодскажите пожалуйста, в чём проблема?$ids = $modx->getChildIds(9,3); print implode(',', $ids);При использовании кода выше ничего не выводит, но и ошибок нет.
$child = $modx->getChildIds(146, 10, array('context' => 'web')); $collection = $modx->getCollection('modResource', array( 'id:IN' => $child, 'published' => true, 'deleted' => false, ));Немного не понятна вот эта конструкция:
$where = array('parent' => 22);Я понимаю, что это условие выборки, но при чем здесь массив?Сразу извините, если вопрос показался очень глупым, но хочу разобраться до конца.
Даже человеческим языком это будет «Ресурсы, у которых родитель равен 23»
Мы объявляем отдельный массив с одним элементом 'parent'.
Просто смутило, что выборки то ещё нет, и как мы можем в не объявленном массиве что то искать по условию.
Я думал, что в этой конструкции уже работаем с полученным массивом элементов…
Не пинайте сильно, пойду учить параллельно php…
$where = array('parent' => 22); $resources = $modx->getCollection('modResource',$where); foreach ($resources as $res) { $output .= '<h2>'.$res->get('pagetitle').'</h2>'; $output .= '<p>'.$res->get('introtext').'</p>'; $output .= '<p><small>Дата: '.$res->get('publishedon').'</small></p>'; } return $output;if (!$modx->getObject('modResource', 22)) { print "Ресурс с id 22 не найден"; return; } $where = array('parent' => 22); $resources = $modx->getCollection('modResource',$where); if (!$resources) { print "У ресурса 22 нет дочерних ресурсов"; return; } foreach ($resources as $res) { $output .= '<h2>'.$res->get('pagetitle').'</h2>'; $output .= '<p>'.$res->get('introtext').'</p>'; $output .= '<p><small>Дата: '.$res->get('publishedon').'</small></p>'; } print $output; return;Если я просто добавляю новый элемент в массив, например:
$where = array( 'parent' => 7, 'id' => 9 );То условие задается как: parent = 7 И id = 9
А если мне например вместо условия И понадобится ИЛИ?
$where = array( 'parent' => 7, 'OR:id' => 9 );<?php <? $whereLog = array( 'parent'=> 3, 'description' => $login, 'publishedon' => true ); $login = $modx->getObject('modResource', $whereLog); if(isset($login)){ if($login == $id->get('publishedby')) $output = $login('$id');и второй набросок
$where = array('parent' => 22); $resources = $modx->getCollection('modResource',$where); if ($login == $id) > 5) { $res = $modx->getObject('modResource', '$id'); $output = $res->get('publishedon'); } else {Лучше воспользоваться готовым компонентом: modstore.pro/payandsee
$ids = $modx->getChildIds(11,3,array('context' => 'web')); print implode(',', $ids); $where = array( 'id:IN' => $ids, ); $resources = $modx->getCollection('modResource', $where); $output = '<p>Вложенные ресурсы</p>'; $output .= '<p>Всего ресурсов: '.count($resources).'</p>'; foreach ($resources as $res) { $output .= '<h2> '.$res->get('pagetitle').'</h2>'; } echo $output;