一部のタグに基づいてすべての連絡先を表示するこのカスタムモジュールがあります。モジュールのフィールドに1つ以上のタグを追加できます
私が欲しいのは、モジュールに表示するオプションを追加することです:
または
私が持っているコードは後者を実行するだけです。オプション1の可能性を追加するにはどうすればよいですか?
私が持っているコードは:
public static function getPeopleByTags($params)
{
//echo "<pre>";
$tags = $params->get("tags");
$model = JModelLegacy::getInstance('Field', 'FieldsModel', array('ignore_request' => true)); //load fields model
//get people info from database
$db = JFactory::getDbo();
$query = $db->getQuery(true);
$query->select('id,catid,name,alias,image,email_to,published,user_id,tags.tag_id');
//$query->select('*');
$query->from($db->quoteName('#__contact_details').'AS contacts');
$query->join('right','#__contentitem_tag_map AS tags ON `tags`.`content_item_id` = `contacts`.`id`');
$query->where($db->quoteName("published") ." = 1 AND `tags`.`type_id` = 2 AND `tags`.`tag_id` IN (".implode(',',$tags).") ");
$query->group('`contacts`.`id`');
$db->setQuery($query);
$people = $db->loadObjectList();
return $people;
}
Joomla 3.9.0
Tags - Similar
モジュールはHAVING
句を使用してこれを実現します。
$query->having('COUNT(' . $db->quoteName('tags.tag_id') . ') = ' . count($tags));
しかし、これが最善の解決策かどうかはわかりません。 WHERE IN
は、任意のタグに一致するすべての行を選択し、HAVING
は、行が選択された後にのみフィルタリングします。
時間をかけて自分のテストデータをセットアップしたところ、HAVING
句の実装に関してSharkyは正しい(+1〜Sharky)でした。
_$tag_ids = $params->get("tags");
$db = JFactory::getDbo();
$query = $db->getQuery(true)
->select("id, catid, name, alias, image, email_to, published, user_id")
->select(" GROUP_CONCAT(tags.tag_id) AS tag_ids")
->from("#__contact_details AS contacts")
->innerJoin("#__contentitem_tag_map AS tags ON tags.content_item_id = contacts.id")
->where("published = 1")
->where("type_id = 2")
->where("tag_id IN (" . implode(',', $tag_ids) . ")")
->group("contacts.id")
->having("COUNT(*) = " . sizeof($tag_ids));
echo $query->dump();
$db->setQuery($query);
echo "<pre>";
var_export($db->loadObjectList());
_
出力:
_SELECT id, catid, name, alias, image, email_to, published, user_id, GROUP_CONCAT(tags.tag_id) AS tag_ids FROM zyxwv_contact_details AS contacts INNER JOIN zyxwv_contentitem_tag_map AS tags ON tags.content_item_id = contacts.id WHERE published = 1 AND type_id = 2 AND tag_id IN (9,10) GROUP BY contacts.id HAVING COUNT(*) = 2
_
_array (
0 =>
stdClass::__set_state(array(
'id' => '12',
'catid' => '21',
'name' => 'Sharky',
'alias' => 'sharky',
'image' => 'images/sharky.jpg',
'email_to' => '',
'published' => '1',
'user_id' => '0',
'tag_ids' => '9,10',
)),
1 =>
stdClass::__set_state(array(
'id' => '82',
'catid' => '21',
'name' => 'mickmackusa',
'alias' => 'mickmackusa',
'image' => '',
'email_to' => '',
'published' => '1',
'user_id' => '0',
'tag_ids' => '9,10',
)),
)
_
SELECT
句でGROUP_CONCAT()
を使用します。HAVING
句はCOUNT(*)
を使用して、_tag_id
_列をフィードするのと同じ結果を得ることができます。COUNT()
に続く番号を変更すると、連絡先/ユーザーが結果セットに含まれるために必要な修飾タグの数が決まります。たとえば、3つの異なるタグを検索したが2つしか必要ない場合、連絡先/ユーザーが3つの修飾タグのうち2つを持っているすべての行を取得します。