J'ai ce module personnalisé qui montre tous les contacts en fonction de certaines balises. Je peux ajouter une ou plusieurs balises dans un champ du module
Ce que je veux, c'est ajouter l'option dans le module pour montrer:
ou
Le code que j'ai vient de faire ce dernier. Comment puis-je ajouter la possibilité pour l'option 1?
Le code que j'ai est:
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
module utilise la clause HAVING
pour y parvenir.
$query->having('COUNT(' . $db->quoteName('tags.tag_id') . ') = ' . count($tags));
Mais je ne suis pas sûr que ce soit la meilleure solution possible. Cela pourrait être plutôt lent parce que WHERE IN
sélectionne toutes les lignes correspondant à n’importe quelle balise et HAVING
filtre uniquement après que les lignes ont été sélectionnées.
J'ai pris le temps de configurer mes propres données de test et Sharky a raison (+1 à Sharky) concernant la mise en œuvre d'une clause HAVING
.
$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());
Sortie:
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()
dans la clause SELECT
.HAVING
peut utiliser COUNT(*)
pour obtenir le même résultat que le chargement de la colonne tag_id
.Changer le numéro qui suit COUNT()
dictera le nombre de balises qualifiantes requises pour qu'un contact/utilisateur soit inclus dans le jeu de résultats. Par exemple, si vous recherchez 3 balises différentes, mais n'en exigez que 2, vous obtiendrez toutes les lignes dans lesquelles les contacts/utilisateurs ont 2 balises qualifiantes sur 3.