3

我正在将一个站点移动到 ModX Revolution 并且没有使用 xPDO 的经验。
我要移动的站点有一个搜索功能,可以查看分配给某些资源的几台电视并返回适用的页面。
我在使用 xPDO 合并它时遇到了麻烦。

我能够返回电视设置为给定值的所有页面,但我不知道如何将其扩展为:
Find all resources where TV1 == X, TV2 == Y, TV3 == Z.
如何一次查询多台电视?

$value = "Mexico";
$c = $modx->newQuery('modResource');
$c->innerJoin('modTemplateVarResource','TemplateVarResources');
$c->where(array(
     'TemplateVarResources.tmplvarid' => 7,
     '"'.$value.'" IN (TemplateVarResources.value)',
));

$resources = $modx->getCollection('modResource',$c);
4

3 回答 3

0

我的两台电视代码中的工作示例:reserved(id:11)和cost_obj(id:12)

$c->leftJoin('modTemplateVarResource', 'cost_obj', array('modResource.id = cost_obj.contentid', 'cost_obj.tmplvarid = 12'));
$c->leftJoin('modTemplateVarResource', 'reserved', array('modResource.id = reserved.contentid', 'reserved.tmplvarid = 11'));
$c->query['where'][0][0][] = new xPDOQueryCondition(array(
   'sql' => 'CAST(`reserved`.`value` as UNSIGNED INTEGER) > ?',
   'binding' => array(
                     'value' => 0,
                     'type' => PDO::PARAM_INT,
                     'length'=>0),
   'conjunction'=>'AND')
);
$c->query['where'][0][1][] = new xPDOQueryCondition(array(
   'sql' => 'CAST(`cost_obj`.`value` as UNSIGNED INTEGER) > ?',
   'binding' => array(
                     'value' => 0,
                     'type' => PDO::PARAM_INT,
                     'length'=>0),
   'conjunction'=>'AND')
);
$c->query['where'][0][2][] = new xPDOQueryCondition(array(
   'sql' => 'CAST(`reserved`.`value` as UNSIGNED INTEGER) >= CAST(`cost_obj`.`value` as UNSIGNED INTEGER)',
   'conjunction'=>'AND')
);

这个查询等于

reserved > 0 AND cost_obj > 0 AND reserved >= cost_obj
于 2013-08-19T20:55:51.483 回答
0

嗯,我认为它是这样的:

$c->where(array(
     'TV1:=' => 'X'
     'AND:TV2:=' => 'Y'
     'AND:TV3:=' => 'Z'
));

最好在这里查看文档:http ://rtfm.modx.com/xpdo/2.x/class-reference/xpdoquery

于 2013-08-19T20:15:42.750 回答
0

只需为您要搜索的每台电视加入一个 modTemplateVar 表。请注意连接中的第三个参数,其中包含 ON 术语。确保您指定了您想要获取的正确电视 ID。

$value = "Mexico";
$c = $modx->newQuery('modResource');
$c->innerJoin('modTemplateVar', 'TV1', 'TV1.contentid = modResource.id AND TV1.tmplvarid = X');
$c->innerJoin('modTemplateVar', 'TV2', 'TV2.contentid = modResource.id AND TV2.tmplvarid = Y');
$c->innerJoin('modTemplateVar', 'TV3', 'TV3.contentid = modResource.id AND TV3.tmplvarid = Z');
$c->where(array(
   'TV1.value:LIKE' => $value,
   'TV2.value'...,
   'TV3.value'...
));

$resources = $modx->getCollection('modResource',$c);

请注意,这是未经测试的,但它应该让您大致了解应该如何设置查询。您可能需要在 ON 子句中的表名中添加一些反引号,不知道 xPDO 解析器对此有多挑剔。

另请注意,这不是对较大集合的非常有效的查询。实现这一点的最有效方法是制作一个适合您需要的自定义 xpdo 对象,但如果您只需要它用于这种特定情况,那将是一个相当大的项目。

如果可能的话,您也可以尝试调用 getResources,在该调用中添加电视连续词相当容易。它仍然很慢,因为它使用或多或少相同的连接完成,但至少您不必为解决方案进行故障排除。

[[getResources?
    &parents=`1,2,3...`
    &depth=`10` 
    &tpl=`yourTemplateForEachResource`
    &tvFilters=`nameOfTV1==%[[+value]]%,othertv==othervalue`
]]

请注意,tvFilters 字符串中的逗号是 AND,双管道是 OR。并以编程方式进行:

$value = 'Mexico';
$resources = $modx->runSnippet('getResources', array(
    'parents' => '1,2,3...',
    'depth' => 10,
    'tpl' => 'yourTemplateForEachResource',
    'tvFilters' => 'nameOfTV1==%' . $value . '%,othertv==othervalue'
));

我想构建自己的查询通常会更快,但是 getResources 内置了一些缓存和优化,从长远来看可能会获胜(如果使用正确)。

于 2013-08-20T20:09:37.003 回答