[REVO] Сниппет Rowboat и условие в параметре where

Приветствую! В сниппете Rowboat нужно в параметре where задать условие, чтобы выводились данные, где id входить в заданный список. У этого сниппета в параметр where нужно записывать условия в json формате, но у меня не получается правильно написать(ничего не выводится). Пишу так
&where=`{"id IN":"1,2,3,4,5"}`
ничего не выводится. Я пробовал разные варианты написания этого условия, но ничего не получилось. И не могу найти в сети примера с IN в этом сниппете. Если кто встречался с таким, напишите как будет правильно. Спасибо за помощь!

23 комментария

avatar

&where=`{"id:IN":"1,2,3,4,5"}`
            ^


Ну и посмотреть
&debug=`1`
avatar
тоже потребовалось использовать Rowboat с
&where=`{"id:IN":"1,2,3,4,5","hidemenu:=":"0"}`

но в таком виде он ничего не выводил, вот что выводит debug:
SQL Query
SELECT `id`,`pagetitle`,`menutitle`,`menuindex` FROM `modx_site_content`
WHERE `id` IN "1,2,3,4,5" AND `hidemenu` = ""
ORDER BY `menuindex` ASC
LIMIT 8

PDO Statement
SELECT `id`,`pagetitle`,`menutitle`,`menuindex` FROM `modx_site_content`
WHERE `id` IN :id AND `hidemenu` = ""
ORDER BY `menuindex` ASC
LIMIT 8


Решил пойти дальше и понять как он разбирает переданный параметр were (у кого нет желания разбираться, см. ниже решение):
<?php

//$where={"id:IN":"1,2,3,4,5","hidemenu:=":0}
//из снипета Rowboat
if (!empty($where)) {
    $where = $modx->fromJSON($where);
    //$where = array([id:IN]=>"1,2,3,4,5",[hidemenu:=]=>0)
    if (!empty($where)) {
        $c->where($where);
    }
}

 //========== с  rbquery.class.php
    
//$criteria = array([id:IN]=>"1,2,3,4,5",[hidemenu:=]=>0)
 public function where($criteria) {
        if (is_array($criteria)) {
            foreach ($criteria as $col => $v) {
                $this->condition(array($col => $v));//для первого элемента - condition( array([id:IN]=>"1,2,3,4,5") )
                //для второго элемента - condition( array([hidemenu:=]=>0) )
            }
        } else {
            $this->condition($criteria);
        }
    }

 protected function condition($criteria) {
        $this->_where[] = $criteria; //array([id:IN]=>"1,2,3,4,5")
        //array([hidemenu:=]=>0)
    }

//======== с rbquery_mysql.class.php
    protected function prepareWhere() {
        $tw = array();
        $sql = 'WHERE';
        foreach ($this->_where as $condition) { //_where = array(array([id:IN]=>"1,2,3,4,5"),array([hidemenu:=]=>0))
        //1) $condition = array([id:IN]=>"1,2,3,4,5")  
        //2) $condition = array([hidemenu:=]=>0)
            if (is_array($condition)) {//да, это массив
                foreach ($condition as $k => $v) {//1) $k = "id:IN"  $v = "1,2,3,4,5"  2) $k = "hidemenu:="  $v = "0"
                    $operand = empty($tw) ? '' : 'AND';//1) будет  $operand = "" 2) будет  $operand = "AND"
                    $operator = '=';
                    if ($k === 0) {//неа, $k = "id:IN" и $k = "hidemenu:=" 
                    //!!! если задано не ассоциативным массивом ([0]=>"id IN (122,60,93,124,123,125,126,96)"), то $k = 0
                    //и тогда $tw[] = "id IN (122,60,93,124,123,125,126,96)" 
                    //(но это только для первого элемента массива т.к. проверка на 0)
                        $tw[] = $operand.' '.$v;
                    } else if (is_string($k)) {//да, строка
                        $op = explode(':',$k);//получим 1) $op[0]="id"  $op[1]="IN"  2) $op[0]="hidemenu"  $op[1]="="
                        if (count($op) == 1) {//неа, count($op) = 2
                            $field = $op[0];

                        } else if (in_array($op[0],$this->_conditionals)) //неа, id и = нет в _conditionals
                            $operand = 'OR';
                            $field = $op[1];
                            if (!empty($op[2])) {
                                $operator = $op[2];
                            }
                        } else {
                            if (!empty($op[1])) {//1) $op[1]="IN"  2) $op[1]="="
                                $operator = $op[1]; //1) $operator="IN"  2) $operator="="
                            }
                            $field = $op[0];//1) $field = id  2) $field = hidemenu
                        }
                        //!!! если задано не ассоциативным массивом и $k != 0, то is_string($k) выше вернет false
                        // $field будет либо не задано, либо останется предыдущее состояние 
                        //(но, т.к. задано не ассоциативным массивом $field будет не задано)
                        //и $operand = AND     $operator = "=", а, к примеру, $v = "hidemenu = 0"
                        //и $tw[] будет = "AND  = "
                        $tw[] = $operand.' '.$this->escape($field).' '.$operator.' '.$this->addParam($field,$v);
                        //1) $tw[] = " id IN :id"
                        //1) $tw[] = "AND"
                    }
                }
            }
        }
        $sql .= ' '.ltrim(implode(" ",$tw),' AND ');
        $this->_preparedSql[] = $sql;
    }


//========== с  rbquery.class.php
        public function addParam($k,$v) {//$k=id $v="1,2,3,4,5"  2) $k=hidemenu $v=0
        if (!empty($v)) {//1) установлена 2) 0 - т.е. !true будет false
            $kz = explode('.',$k);
            $k = !empty($kz[1]) ? $kz[1] : $kz[0];//$k=id
            if (array_key_exists($k,$this->_params)) {//пока еще нету
                $k = $k.uniqid($k);
            }

            $this->_params[$k] = $v;//а вот щас уже будет _params["id"]="1,2,3,4,5"
            $k = ':'.$k;//$k = ":id"
        } else { $k = '""'; }//2) $k="" и как так? это все из-за empty
        return $k;//1)$k = ":id" - так должно быть???
    }
    ?>

Дак вот, если задать where как:
&where=`{"0":"id IN (1,2,3,4,5)","hidemenu:!=":"1"}`

то все будет работать и выводить то, что нужно (во всяком случае, у меня только так выводит с IN).
avatar
Так тоже не работает?
&where=`{"id:IN:"(1,2,3,4,5)"}`
avatar
неа, не работает,
сори… первый раз не там проверил и подумал что работает)
Комментарий отредактирован 2012-11-29 16:58:29 пользователем vladimir
avatar
Ошибка там есть!) Забыл кавычки поставить
&where=`{"id:IN":"(1,2,3,4,5)"}`
avatar
я так и понял, что опечатка) вот что выводит в этом случае:
SELECT `id`,`pagetitle`,`menutitle`,`menuindex` FROM `modx_site_content`
WHERE `id` IN "(122,60,93,124,123,125,126,96)" AND `hidemenu` != "1"
ORDER BY `menuindex` ASC
LIMIT 8

в кавычках, из-за этого скорее всего
avatar
Всё верно выводит!
Гоню, там же в кавычках список id'шников, пробуйте нижний вариант
Комментарий отредактирован 2012-11-29 17:06:59 пользователем vanchelo
avatar
Лучше всего попробуйте вот так, это будет валидный JSON
&where=`[{"id:IN":[1,2,3,4,5]}]`
Комментарий отредактирован 2012-11-29 17:04:19 пользователем vanchelo
avatar
так вообще он не поймет, в этом случае будет:
array([0]=>array("id:IN"=>array(1,2,3,4,5)))
avatar
будет все правильно, он сам массив преобразует в список понятный для SQL

Потому что когда пишете запросы на xPDO то в качестве параметров не передаете строку а передаете массив, вот пример

$c = $modx->newQuery('modResource');
$c->where(array('id:IN' => array(1,2,3,4,5,6)));

avatar
Если вас смущают квадратные скобки по краям, то пишите так
&where=`{«id:IN»:[1,2,3,4,5]}`
avatar
а в этом:
SELECT `id`,`pagetitle`,`menutitle`,`menuindex` FROM `modx_site_content`
WHERE `id` IN "Array"
ORDER BY `menuindex` ASC
LIMIT 8

Parameters
array (
  'id' => 
  array (
    0 => 122,
    1 => 60,
    2 => 93,
    3 => 124,
    4 => 123,
    5 => 125,
    6 => 126,
    7 => 96,
  ),
)
avatar
дебаг в этом случае:
SQL Query
SELECT `id`,`pagetitle`,`menutitle`,`menuindex` FROM `modx_site_content`
WHERE rray
ORDER BY `menuindex` ASC
LIMIT 8

Parameters
array (
)
avatar
У меня вот так отлично всё работает:
[[!getResources?
&parents=`0`
&where=`[{"id:IN":[1,2,3,4,5]},{"hidemenu":0}]`
]]
avatar
странно, может я чего не так делаю, вот мой полный вызов Rowboat

[[!Rowboat?
   &table=`modx_site_content`
   &tpl=`tpl.main.menu.row`
   &limit=`8`
 &columns=`{"id":"","pagetitle":"","menutitle":"","menuindex":""}`
   &where=`[{"id:IN":[122,60,93,124,123,125,126,96]},{"hidemenu":0}]`
   &sortBy=`menuindex`
   &cacheResults=`0`
  &debug=`1`
]]


и ничего не выводит, если изменить на:
&where=`{"0":"id IN (1,2,3,4,5)","hidemenu:!=":"1"}`

то работает
avatar
Спасибо! Так заработало у меня, я какими только способами не пытался кавычки ставить и скобки.

PS: Странно что мне не приходили уведомления на почту про вашу переписку в этом топике(
avatar
мы вроде про Rowboat, не?)
avatar
Оба сниппета работаю через xPDO.
avatar
avatar
Ага, там куча своих методов.
Зачем вы пользуетесь им?
Ведь он уже год как не обновлялся
Комментарий отредактирован 2012-11-29 18:02:49 пользователем vanchelo
avatar
увидел вопрос про Rowboat и просто решил попробовать))
хотел сравнить генерацию меню с Wayfinder)

p.s. в Wayfinder ведь нельзя задать меню из указанных через запятую id ресурсов? и чтоб все на одном уровне были, или также, через where можно?
Комментарий отредактирован 2012-11-29 18:09:07 пользователем vladimir
avatar
Я в таких случаях пишу простейший сниппет в несколько строк кода.
avatar
ребята, а как можно вывод Rowboat настроить на ресурсы?
поставил его для tag manager, в нем нужно получать не айди из ТВ заданой (списком ресурсов), а пейджтайтл-название

чанк «userOption» с содержимым: [[+pagetitle]]==[[+pagetitle]] прописан…

подскажите пл-з, кто знает…
  • LSV
  • 0
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.