기본 조건 운영자가 태그 가능 확장자에서 또는 과정에서 변경할 수 있습니까?
-
12-12-2019 - |
문제
$tagged = Os :: model()-> withTags("windows, windows7, windowsXp")-> find();
.
다음 중 하나라도 태그가 지정된 레코드를 검색하고 싶습니다. 창 , Windows7 , WindowsXP .
기본적으로 태그는 and-ed 인 조건을 생성합니다.나는 태그에 대한 또는 연산자를 사용하고 싶습니다.따라서 레코드에 Windows, Windows7이지만 WindowsXP가 아닌 경우 검색되지 않습니다.
etaggablebehavior.php 에서 etaggablebehavior.php 에서 getfindbytagscriteritia () 을 편집하여 해결 방법을 찾았습니다.
.
/**
* Get criteria to limit query by tags.
* @access private
* @param array $tags
* @return CDbCriteria
*/
protected function getFindByTagsCriteria($tags) {
$criteria = new CDbCriteria();
$pk = $this->getOwner()->tableSchema->primaryKey;
if(!empty($tags)){
$conn = $this->getConnection();
$criteria->select = 't.*';
if(count($tags) >0){
$criteria -> join .= "
JOIN {$this->getTagBindingTableName()} bt
ON t.{$pk} = bt.{$this->getModelTableFkName()}
JOIN {$this->tagTable} tag0
ON tag0.{$this->tagTablePk} = bt.{$this->tagBindingTableTagId} AND (";
for($i = 0, $count = count($tags); $i < $count; $i++){
$tag = $conn->quoteValue($tags[$i]);
$criteria->join .= " tag0.`{$this->tagTableName}` = $tag OR";
}
$criteria -> join = rtrim($criteria -> join, "OR");
$criteria -> join .= ")";
}
}
if($this->getScopeCriteria()){
$criteria->mergeWith($this->getScopeCriteria());
}
return $criteria;
}
플러그인 자체를 수정하지 않고도 다른 방법을 정말로 감사드립니다.
해결책 2
샘 Yii 개발 팀에서 etaggablebehavior.php 에 두 가지 기능을 추가하여 이것을 해결할 수있게 도와 줬습니다.
./**
* Get criteria to limit query to match any of tags specified
* @access private
* @param array $tags
* @return CDbCriteria
*/
protected function getFindByAnyTagsCriteria($tags) {
$criteria = new CDbCriteria();
$pk = $this->getOwner()->tableSchema->primaryKey;
if(!empty($tags)){
$conn = $this->getConnection();
foreach($tags as &$tag) {
$tag = $conn->quoteValue($tag);
}
unset($tag);
$tags = implode(', ', $tags);
$criteria->select = 't.*';
$criteria->join .=
"JOIN {$this->getTagBindingTableName()} bt ON t.{$pk} = bt.{$this->getModelTableFkName()}
JOIN {$this->tagTable} tag ON tag.{$this->tagTablePk} = bt.{$this->tagBindingTableTagId} AND tag.`{$this->tagTableName}` IN ($tags)";
}
}
if($this->getScopeCriteria()){
$criteria->mergeWith($this->getScopeCriteria());
}
return $criteria;
}
/**
* Limit current AR query to have any of tags specified.
* @param string|array $tags
* @return CActiveRecord
*/
public function taggedWithAnyOf($tags) {
$tags = $this->toTagsArray($tags);
if(!empty($tags)){
$criteria = $this->getFindByAnyTagsCriteria($tags);
$this->getOwner()->getDbCriteria()->mergeWith($criteria);
}
return $this->getOwner();
}
다른 팁
여기에서 할 일은 모델의 withTags () 메소드를 설정하여 배열 값을 가져옵니다 (예 : ).
/**
* @param array $tags List of tags to search for
* @return named scope
*/
public function withTags($tags)
{
$condition = '1';
$params = array();
foreach($tags as $key=>$value)
{
$condition.=' OR tag = :tag'.$key;
$params[':tag'.$key] = $value;
}
$this->getDbCriteria()->mergeWith(array(
'condition'=>$condition,
'params'=>$params,
));
return $this;
}
.
이렇게하면 이름이 지정된 범위를 다음과 같이 호출 할 수 있어야합니다.
$tags = array('windows', 'windows7', 'windowsXp'),
$tagged = Os::model()->withTags($tags)->findAll();
.