Ich habe dieses benutzerdefinierte Modul, das alle Kontakte basierend auf einigen Tags anzeigt. Ich kann ein oder mehrere Tags in ein Feld im Modul einfügen
Was ich möchte, ist die Option im Modul hinzuzufügen, um Folgendes anzuzeigen:
oder
Der Code, den ich gerade habe, tut das letztere. Wie kann ich die Möglichkeit für Option 1 hinzufügen?
Der Code, den ich habe, ist:
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
Das Modul Tags - Similar
Verwendet die HAVING
-Klausel, um dies zu erreichen.
$query->having('COUNT(' . $db->quoteName('tags.tag_id') . ') = ' . count($tags));
Ich bin mir aber nicht sicher, ob dies die bestmögliche Lösung ist. Dies kann sehr langsam sein, da WHERE IN
Erst nach Auswahl der Zeilen alle Zeilen auswählt, die mit einem beliebigen Tag und HAVING
-Filtern übereinstimmen.
Ich habe mir die Zeit genommen, meine eigenen Testdaten einzurichten, und Sharky hat Recht (+1 für Sharky), eine HAVING
-Klausel zu implementieren.
$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());
Ausgabe:
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',
)),
)
GROUP_CONCAT()
in der SELECT
-Klausel, um alle tag_ids in der Ergebnismenge anzuzeigen.HAVING
-Klausel kann COUNT(*)
verwenden, um dasselbe Ergebnis zu erzielen wie die Eingabe der Spalte tag_id
.Durch Ändern der Zahl nach COUNT()
wird festgelegt, wie viele qualifizierende Tags erforderlich sind, damit ein Kontakt/Benutzer in die Ergebnismenge aufgenommen wird. Wenn Sie beispielsweise nach 3 verschiedenen Tags suchen, aber nur 2 benötigen, erhalten Sie alle Zeilen, in denen Kontakte/Benutzer über 2 von 3 qualifizierenden Tags verfügen.