# Mécanismes de recherche
La recherche de Smart Elements est une fonctionnalité essentielle à la gestion des Smart Elements. Cette recherche permet de trouver des Smart Elements sur divers critères tels que:
- critère d'appartenance à une Smart Structure,
- critère sur les propriétés de Smart Elements,
- critère sur les Smart Fields des Smart Elements,
- critère sur les droits du Smart Element,
- critère sur l'appartenance à un dossier,
- critère sur les relations entre Smart Elements,
- critère sur les activités ou état lié à un cycle de vie.
Les chapitres suivants détaillent les techniques permettant d'effetuer des recherches de Smart Elements.
# Recherche de Smart Elements
# Recherche de Smart Elements issus d'une même Smart Structure
La recherche de Smart Elements en fonction d'une Smart Structure est réalisée avec la classe
SearchElements
.
# Récupération du résultat de la recherche
Par défaut les résultats suivants sont exclus:
- Les Smart Elements supprimés (
doctype = 'Z'
), - Les Smart Elements figés (
locked = -1
), - Les Smart Elements temporaires (
doctype = 'T'
), - Les Smart Elements archivés (
archiveid is null
), - Les Smart Elements non visibles par l'utilisateur courant (
droit view
).
# Retour de Smart Elements
La méthode SearchElements::getResults()
retourne un objet itérable Anakeen\Search\ElementList
.
- Avec une boucle
foreach
use Anakeen\Search\SearchElements;
$searchElement = new SearchElements("IUSER");
$res = $searchElement->search()->getResults();
foreach ($res as $key => $data) {
printf("%d) %-10s : %s\n", $key, $data->getTitle(), $data->getRawValue(\SmartStructure\Fields\Iuser::us_mail));
}
- Avec une boucle
while
en utilisant la méthodeSearchElements::getNextElement()
use Anakeen\Search\SearchElements;
$searchElement = new SearchElements("IUSER");
$res = $searchElement->search();
$i = 0;
while (($r = $res->getNextElement())) {
printf("$i) %-10s : %s\n", $r->getTitle(), $r->getRawValue(\SmartStructure\Fields\Iuser::us_mail));
$i++;
}
# Retour d'objets Smart Element
Il est possible d'appliquer les méthodes des objets sur les retours de Smart Elements (exemple:
SmartElement::getRawValue
).
use Anakeen\Search\SearchElements;
$searchElement = new SearchElements("IUSER");
$searchElement->addFilter("us_extmail is not null");
$searchElement->search();
$c = $searchElement->count();
print "count $c\n";
$i = 0;
while (($r = $searchElement->getNextElement())) {
printf("$i)" . $r->getTitle() . "(" . $r->getRawValue(\SmartStructure\Fields\Iuser::us_mail) . ")\n");
$i++;
}
Sécurité
Les objets Smart Element sont retournés non contrôlés. Le store
ne vérifiera pas les droits d'accès.
Il faut utiliser la méthode disableAccessControl
pour activer les droits.
# Utilisation des itérateurs
Pour récupérer la liste des Smart Elements, il est aussi possible d'utiliser un itérateur PHP afin de parcourir la liste des Smart Elements.
use Anakeen\Search\SearchElements;
$searchElement = new SearchElements("IUSER");
$searchElement->addFilter("us_extmail is not null");
$searchElement->setSlice(15);
$searchElement->search();
$res = $searchElement->getResults();
foreach ($res as $key => $el) {
print "$key)" . $el->getTitle() . "(" . $el->getRawValue("us_mail", "nomail") . ")\n";
}
La méthode getResults()
retourne une objet ElementList
qui implémente l'interface
Iterator. Il est ainsi possible d'utiliser le résultat dans une
boucle classique foreach
.
# Recherche avec des critères sur des Smart Fields du Smart Element
Dans le cas où une Smart Structure d'appartenance est précisée, il est possible d'utiliser les Smart Fields de cette Smart Structure comme critères.
use Anakeen\Search\SearchElements;
$s = new SearchElements("IUSER"); // recherche sur les Smart Elements de la Smart Structure IUSER
$s->addFilter("us_fname ~* 'jean'"); // prénom contient Jean
$res = $s->search()->getResults();
foreach ($res as $key => $el) {
print "$key)" . $el->getTitle() . "(" . $el->getRawValue("us_mail", "nomail") . ")\n";
}
L'exemple ci-dessus montre la recherche de toutes les personnes dont le prénom contient jean
. Les filtres ajoutés au
moyen de la méthode addFilter()
établissent une conjonction de conditions (opérateur and
). Pour établir une
disjonction, il faut l'écrire manuellement en SQL en utilisateur l'opérateur or
.
Les opérateurs SQL utilisés doivent être compatibles avec les
types des Smart Fields stockés en base de données.
use Anakeen\Search\SearchElements;
$s = new SearchElements("IUSER"); // recherche sur les Smart Elements de la Smart Structure IUSER
$s->addFilter("us_fname ~* 'jean|patrick'"); // prénom contient jean ou patrick
// mail fini par .org ou nom commençant par CO
$s->addFilter("(us_mail ~ '\.org$') or (us_lname ~ '^CO')");
$res = $s->search()->getResults();
foreach ($res as $key => $el) {
print "$key)" .
$el->getTitle() .
"(" .
$el->getRawValue("us_mail", "nomail") .
":" .
$el->getRawValue("us_lname") .
")\n";
}
Note
Les types docid
sont enregistrées au format text
dans la base de données.
# Recherche dans un array
Pour une Smart Structure avec un tableau contenant une liste de valeur, le filtre PostgreSQL suivant permet de filtrer les Smart Elements dont une des valeurs est égale à une valeur précise:
use Anakeen\Search\SearchElements;
$s = new SearchElements("IUSER"); // recherche sur les Smart Elements de la Smart Structure IUSER
$s->addFilter("'Main Group' ~ ANY(us_group)");
$res = $s->search()->getResults();
$c = $s->count();
print $c . " results\n";
foreach ($res as $item) {
print $item->getTitle();
}
# Recherche avec jointure
Il est possible d'ajouter des critères portant sur une autre table en utilisant un mécanisme de jointure. Ce mécanisme
ne permet pas de récupérer des données provenant de cette autre table mais permet de les utiliser comme critère de
recherche.
Exemple: recherche des Smart Elements qui ont dans l'historique un ordre de suppression émis par l'utilisateur courant.
use Anakeen\Search\SearchElements;
$s = new SearchElements();
$s->useTrash("only");
$s->join("id = dochisto(id)");
$s->addFilter("dochisto.uid = %d", "Administrators");
$s->addFilter("dochisto.code = 'DELETE'");
$s->setDistinct(true);
$result = $s->search()->getResults();
foreach ($result as $item) {
print $item->getTitle();
}
Il est notamment possible d'utiliser, entre autres, les tables dochisto
,docutag
ou docrel
pour établir un critère
de jointure.
Attention
On ne peut utiliser qu'un seul ordre join
par requête.
Il est aussi possible de créer un critère sur une Smart Structure liée :
use Anakeen\Search\SearchElements;
$s = new SearchElements("DEVBILL");
$s->join("bill_author::int = devperson(id)");
$s->addFilter("devperson.dev_firstname = 'Jack'");
$result = $s->search()->getResults();
$c = $s->count();
print $c . " results";
foreach ($result as $item) {
print $item->getTitle();
}
Dans l'exemple décrit on recherche les factures DEVBILL
dont l'auteur est une personne DEVPERSON
nommé Jack.
Attention
Bien lier les deux Smart Structures à travers l'identificateur initial (initid
) dans le cas des relations créées avec
les options par défaut.
# Recherche de Smart Structure
Pour rechercher des Smart Structures, il faut utiliser la valeur -1
lors de la construction de l'objet recherche.
use Anakeen\Search\SearchElements;
$s = new SearchElements(-1);
$result = $s->search()->getResults();
foreach ($result as $r) {
print $r->getTitle();
}
# Recherche de Smart Element depuis leur identifiant
Dans le cas ou vous disposez d'une liste d'identifiant de Smart Element, il faut utiliser l'itérateur de Smart Element.
use Anakeen\Search\ElementList;
$dl = new ElementList();
$dl->addElementIdentifiers(array(97519, 97514, 97515, 97513));
foreach ($dl as $item) {
print $item;
}
La méthode ElementList::addElementIdentifiers()
permet de renseigner la liste des identifiants de Smart Element.
Si dans la liste un ou plusieurs identifiant sn'ciste pas alors l'itérateur ne les retourne pas. Dans ce cas le nombre
de Smart Elements retourné est inférieur au nombre d'identifiants données.
Par défaut seuls les Smart Elements que l'utilisateur a le droit de voir sont retournés.
Si vous voulez affiner les critères de recherche vous pouvez le faire en utilisant la recherche stockée dans
l'itérateur.
use Anakeen\Search\ElementList;
$el = new ElementList();
$el->addElementIdentifiers(array(97519, 97514, 97515, 97513));
$el->getSearchElement()->addFilter("title ~ 'HANOUZET'");
$el->getSearchElement()->overrideAccessControl();
foreach ($el as $r) {
print $r->getTitle();
}
Cela ne retournera que les Smart Elements dont le titre contient HANOUZET parmi les quatre Smart Elements donnés sans
tenir compte des droits de visibilités. Il est aussi possible d'utiliser la fonction de callback pour l'appliquer à
l'ensemble de la liste (voir ElementList::listMap()
).
# Recherche de Smart Element contenu dans une collection
La classe SearchElements
permet de faire des recherches dans une collection spécifique (dossier ou recherche) au moyen
de la méthode SearchElements::useCollection()
.
Cette recherche n'est pas récursive par défaut, c'est à dire qu'elle ne recherche que dans la collection indiquée.
Lorsque la collection est un dossier, il est possible de faire des recherches récursives à l'aide de la méthode
SearchSmartData::setRecursiveSearch()
. Le niveau de profondeur de la recherche est ensuite défini au moyen de la
propriété SearchSmartData::folderRecursiveLevel
, positionné à 2 par défaut.
Note
Le setRecursiveSearch
fait référence au niveau de récursivité. Par exemple, folderRecursiveLevel=0
veut dire que
l'on recherche dans le dossier, alors que folderRecursiveLevel=1
indique de rechercher dans le dossier et ses
sous-dossiers.
Lorsque la collection est une recherche, il n'est pas possible de faire la recherche récursivement.
use Anakeen\Search\SearchElements;
$s = new SearchElements();
$s->useCollection("MASK");
$r = $s->search();
# Recherche en fonction des droits
# Recherche sans tenir compte des droits
Par défaut, seuls les Smart Elements que l'utilisateur a le droit de voir sont retournés. Pour retourner tous les Smart
Elements sans vérifier les droits, il faut utiliser la méthode overrideAccessControl()
.
use Anakeen\Search\SearchElements;
$s = new SearchElements("DEVBILL");
$s->overrideAccessControl();
Note
Si la recherche est faite sour l'identité admin
, aucun droit n'est vérifié.
# Recherche et Smart Elements confidentiels
Les Smart Elements confidentiels sont les Smart Elements dont la propriété confidential
est égale à 1. L'accès à ces
Smart Elements doit être contrôlé par l'application qui décide quelles parties elle veut montrer. À la différence du
droit voir (view
) des Smart Elements, la recherche retourne les Smart Elements confidentiels par défaut. Le filtrage
est à faire du côté de l'application avec un post-traitement. Cependant, il est possible de rajouter un filtre
permettant de ne pas retourner les Smart Elements confidentiels que l'utilisateur n'a pas le droit de voir. Pour cela,
il faut appeler la méthode excludeConfidential()
.
use Anakeen\Search\SearchElements;
$s = new SearchElements("DEVBILL");
$s->excludeConfidential();
$s->search();
# Recherche sur les propriétés du Smart Element
# Recherche et révision
Par défaut, seule la dernière révision du Smart Element est retournée. Pour chercher sur l'ensemble des révisions, il
faut mettre la propriété latest
à false
.
use Anakeen\Search\SearchElements;
$s = new SearchElements("DEVBILL");
$s->setLatest(false); // toutes les révisions
Si la propriété locked = -1
, cela indique que le Smart Element est figé.
# Recherche sur les propriétés
Cet exemple, montre la recherche de Smart Element par le titre. Ici, tout type de Smart Element est retourné si son titre contient 'jean' en majuscule ou minuscule. Les opérateurs utilisables sont les opérateurs SQL de PostgreSQL.
use Anakeen\Search\SearchElements;
$s = new SearchElements();
$s->addFilter("title ~* 'jean'");
$res = $s->search()->getResults();
foreach ($res as $r) {
print $r->getTitle();
}
# Rechercher sur les états d'un Smart Element lié à un cycle de vie
La recherche des Smart Elements en fonction de leur activité ou de leur état est faite en filtrant sur la propriété
state
. La clef correspondante est l'identifiant indiqué dans les propriétés e1
et e2
du cycle. La recherche
suivant l'activité est forcément effectuée sur les dernière révisions.
use Anakeen\Search\SearchElements;
use Anakeen\SmartElementManager;
$doc = SmartElementManager::getDocument("WDOC_BILL"); // Cycle DEVBILL
$s = new SearchElements("DEVBILL");
$s->addFilter("state = '%s'", $doc->getFirstState()); // recherche des Smart Elements étant dans la première activité
$s->search();
La recherche sur l'état est effectuée sur les révisions passées.
use Anakeen\Search\SearchElements;
use Anakeen\SmartElementManager;
use SmartStructure\Fields\Devbill as bill;
$doc = SmartElementManager::getDocument("WDOC_BILL");
$s = new SearchElements("DEVBILL");
$s->addFilter("state = '%s'", bill::bill_author);
$s->setLatest(false);
$s->addFilter("locked = -1"); // révisions passées uniquement
$s->search();
# Recherche des relations d'un Smart Element
Pour trouver les Smart Elements qui ont lié à un autre,, il faut utiliser la classe DocRel
. La méthode
DocRel::getIRelations()
donne la liste des Smart Elements liés vers un Smart Element.
use Anakeen\SmartElementManager;
$doc = SmartElementManager::getDocument(98452);
$docrel = new \DocRel($doc->initid);
$toMeRelation = $docrel->getIRelations();
$fromMeRelation = $docrel->getRelations();
print "\n#------------------ Relation vers moi\n";
print_r($toMeRelation);
print "\n#------------------ Relation depuis moi\n";
print_r($fromMeRelation);
La méthode DocRel::getIRelations()
retourne les caractéristiques des Smart Elements liés.
- sinitid : Identifiant initial source (celui qui pointe vers la cible),
- cinitid : Identifiant initial cible (la cible pointé par la source),
- stitle : Titre de la source,
- ctile : Titre de la cible,
- sicon : Icône de la source,
- cicon : Icône de la cible,
- type : Type de lien (nom du Smart field ayant établi le lien),
- doctype : doctype du Smart Element source.
Résultats:
#------------------Relation vers moi Array()
#------------------Relation depuis moi Array(
Array(
[0] => Array(
[sinitid] => 98111
[cinitid] => 97755
[ctitle] => EVERS Léana SOUFFLET NEGOCE
[cicon] => devclient.png
[stitle] => Bill0003
[sicon] => devbill.png
[type] => bill_clients
[doctype] => F
)
[1] => Array(
[sinitid] => 98111
[cinitid] => 97745
[ctitle] => RELAIX Alexandre SYSTEME U CENTRALE NATIONALE
[cicon] => devclient.png
[stitle] => Bill0003
[sicon] => devbill.png
[type] => bill_clients
[doctype] => F
)
[2] => Array(
[sinitid] => 98111
[cinitid] => 97626
[ctitle] => ADAMZIK Jack
[cicon] => devperson.png
[stitle] => Bill0003
[sicon] => devbill.png
[type] => bill_author
[doctype] => F
)
)
Pour exploiter les résultats, il est aussi possible d'utiliser un objet ElementList
.
use Anakeen\Search\ElementList;
use Anakeen\SmartElementManager;
$doc = SmartElementManager::getDocument(98111);
$docrel = new \DocRel();
$docrel->sinitid = $doc->initid;
$fromMeRelation = $docrel->getRelations();
$ids = array_map(function ($r) {
return $r["sinitid"];
}, $fromMeRelation);
$dl = new ElementList();
$dl->addElementIdentifiers($ids);
foreach ($dl as $r) {
printf("%s %s '%d'\n", $doc->getFamilyDocument()->getTitle(), $doc->getTitle(), $doc->id);
}
Résultat
Bill Bill0003 ADAMZIK Jack '98111'
L'objet $dl
contient alors les Smart Elements pointant vers la cible.
# Callback et itérateur
# Callback sur un itérateur
Il est possible d'appliquer une fonction sur chacun des Smart Elements d'une liste de Smart Elements provenant d'un itérateur.
use Anakeen\Search\SearchElements;
$s = new SearchElements("IUSER");
$s->addFilter("us_extmail is not null");
$s->search();
$dl = $s->getResults();
$test = 1;
$callback = function (&$doc) use ($test) {
if ($test) {
$doc->lock();
}
};
$dl->listMap($callback);
foreach ($dl as $docid => $doc) {
print "$docid)" . $doc->getTitle() . "(" . $doc->getPropertyValue("locked") . ")\n";
}
Dans cet exemple, l'ensemble des Smart Elements est verrouillé.
Attention
La fonction de mapping est appelée sur chacun des Smart Elements lors de l'itération. S'il n'y a pas d'itération, la fonction de mapping n'est pas appelée.
# Callback sur un itérateur avec filtrage
La fonction de callback permet aussi d'exclure des Smart Elements de l'itérateur. Si la méthode retourne le booléen false, alors le Smart Element est exclu de la liste. Tout autre retour que le booléen false retournera le Smart Element, même s'il n'y a pas de retour explicite.
use Anakeen\Search\SearchElements;
$s = new SearchElements("IUSER");
$s->search();
$dl = $s->getResults();
$callback = function (&$doc) {
if (!$doc->isLocked()) {
$doc->lock();
return true;
}
};
$dl->listMap($callback);
foreach ($dl as $docid => $doc) {
print "$docid)" . $doc->getTitle() . "(" . $doc->getPropertyValue("locked") . ")\n";
}
Cet exemple ne verrouillera que les Smart Elements non verrouillés et ne retournera que les Smart Element venant d'être verrouillés.
# Compter le nombre de résultats
Le nombre de résultats peut être obtenu avec la méthode SearchSmartData::count()
après avoir effectué la recherche
(appel SearchSmartData::search()
).
use Anakeen\Search\SearchElements;
$s = new SearchElements("IUSER");
$s->search();
$c = $s->count();
print $c . " results";
Si seul le nombre vous intéresse, la méthode SearchSmartData::count()
n'est pas la plus performante, car la requête
est lancée et l'ensemble des résultats st récupéré. Pour des performances accrues, il faut utiliser la méthode
SearchElements::onlyCount()
. Ceci effectue la recherche en ne retournant que le nombre de Smart Elements
correspondants.
use Anakeen\Search\SearchElements;
$s = new SearchElements("IUSER");
$s->search();
$c = $s->onlyCount();
print $c . " results";
Attention
Le premier appel à une des méthodes de SearchSmartData::search()
ou SearchElements::onlyCount()
lance une requête au
serveur de base de données. Le résultat est mis en cache pour être exploité par les itérateurs.
use Anakeen\Search\SearchElements;
$s = new SearchElements("IUSER");
// Pas d'appel à SearchSmartData::search()
$c = $s->onlyCount(); // retourne le nombre de résultats
print $c . " results";
$s->addFilter("cdate > '%s'", date("Y-m-d"));
$s->search(); // relance la recherche
# Traitements des erreurs
Si la requête échoue suite à des erreurs SQL (souvent liées à un filtre mal formé), une exception de type
Anakeen\Database\Exception
ou Anakeen\Search\Exception
est retournée. Ces deux type d'erreur hérite de
Anakeen\Exception
.
use Anakeen\Search\SearchElements;
try {
$s = new SearchElements("IUSER");
$s->addFilter("us_extmail is not null");
$s->addFilter("pas bon"); // Ici une erreur de filtre
$r = $s->search();
} catch (\Anakeen\Exception $e) {
print $e->getMessage();
}
Résultat :
{"success":true,"data":"","messages":[]}{DB0005} query prepare error : ERROR: syntax error at or near "bon"
LINE 1: ...cked != -1) and (us_extmail is not null) and (pas bon) ORDER...
^
select doc128.* from doc128 where (doc128.doctype != 'Z') and (doc128.doctype != 'T') and (doc128.locked != -1) and (us_extmail is not null) and (pas bon) ORDER BY title LIMIT ALL OFFSET 0;
La classe SearchElements
permet de récupérer les informations sur la requête afin de débugguer votre recherche. Ces
informations sont consultables avec la méthode SearchSmartData::getSearchInfo()
après avoir exécuté la recherche.
use Anakeen\Search\SearchElements;
$s = new SearchElements("IUSER");
$s->addFilter("us_extmail is not null");
$s->search();
print $s->getSearchInfo();
Résultat :
[ debuginfo: Anakeen\Search\Internal\SearchSmartData: private ] => Array
(
[ count ] => 862
[ query ] => selectdoc128.\*fromdoc128where(doc128.doctype!='Z')and(doc128.doctype!='T')and(doc128.locked!=-1)and(us_extmailisnotnull)ORDERBYtitleLIMITALLOFFSET0;
[ error ] =>
[ delay ] => 0.013s
)
# Recherche détaillé
# Enregistrement d'une recherche détaillée
# Création d'une recherche par Smart Structure
La recherche détaillée (Smart Structure DSEARCH
) a pour but de rechercher des Smart Elements d'une Smart Structure
donnée. Elle permet aussi d'être utilisée depuis l'interface graphique ou depuis la classe SearchElements
pour avoir
une liste de Smart Elements suivant des critères préétablis.
$rd = SEManager::createDocument("DSEARCH");
$rd->setValue(dsearch::se_famid, "IUSER");
$rd->store();
$s = new SearchElements();
$s->useCollection($rd->initid);
$dl = $s->getResults();
foreach ($dl as $d) {
print $d->getTitle();
}
L'affectation des critères est effectuée, en valorisant les Smart Fields du tableau se_t_detail
de la Smart Structure
DSEARCH
.
use Anakeen\Core\SEManager;
use Anakeen\Search\SearchElements;
use SmartStructure\Fields\Dsearch as dsearch;
$rd = SEManager::createDocument("DSEARCH");
$rd->setAttributeValue(dsearch::se_famid, "IUSER");
$rd->setAttributeValue(dsearch::ba_title, "Search Active Users with email");
$criteria = array(
array(
dsearch::se_attrids => \SmartStructure\Fields\Iuser::us_status,
dsearch::se_funcs => "=",
dsearch::se_keys => "A"
),
array(
dsearch::se_attrids => \SmartStructure\Fields\Iuser::us_status,
dsearch::se_funcs => "=",
dsearch::se_keys => ""
)
);
$rd->setAttributeValue(dsearch::se_t_detail, $criteria);
$rd->store();
$s = new SearchElements();
$s->useCollection($rd->initid);
$dl = $s->getResults();
foreach ($dl as $d) {
print $d->getTitle();
}
# Enregistrement d'une recherche détaillée avec SearchElements
La recherche détaillée peut aussi être enregistrée avec une requête arbitraire. La méthode
SearchHooks::addStaticQuery()
permet de modifier la requête issue des critères du Smart Element recherche.
use Anakeen\Core\SEManager;
use SmartStructure\Fields\Dsearch as dsearch;
$s = new \Anakeen\Search\Internal\SearchSmartData("IUSER");
$s->addFilter("us_extmail is not null");
$sql = $s->getOriginalQuery();
$rd = SEManager::createDocument("DSEARCH");
$rd->setValue(dsearch::ba_title, "my Search");
$rd->store();
/**
* @var \Anakeen\SmartStructures\Search\SearchHooks $mySearch
*/
$mySearch = SEManager::getDocument($rd->initid);
$mySearch->addStaticQuery($sql);
Dans ce cas, le Smart Element produit s'il est modifié par l'interface, perd ses caractéristiques spécifiques au dépend
des nouveaux critères présents sur l'interface graphique.
La méthode SearchHooks::addStaticQuery()
ne peut être utilisée que si le Smart Element est déjà enregistré en base de
données.
La requête SQL enregistrée ne doit pas tenir compte des droits. Ces critères de droits sont ajoutés par l'utilisation
de la recherche détaillé.
# Utilisation de méthodes dans l'interface de recherche détaillée
Lors de la création d'une recherche détaillé, il est possible de choisir pour un critère une méthode comme valeur.
Exemple: ma_date > ::getDate(-7)
Cet exemple indique que le critère est la date courante -7 jours. La méthode SmartElement::getDate()
est une méthode
statique de la classe SmartElement
.
Les méthodes utilisables dans les recherches détaillées sont les méthodes de la classe de la Smart Structure sur
laquelle porte la recherche qui ont un commentaire ( au format DocBlock
et qui contiennent les tags @searchLabel
et @searchType
). Vous pouvez ainsi déclarer votre propre méthode,
utilisable comme critère de recherche dans le fichier méthode de votre Smart Structure et ajouter les commentaires
DocBlock adéquats. Cette méthode est généralement statique car elle ne doit pas faire appel à des valeurs de Smart
Element. Par contre vous pouvez utiliser des paramètres de la Smart Strucure. La valeur de retour de cette méthode est
utilisé comme valeur du critère. Cela ne peut être appliqué que sur des opérateurs nécessitant une seule valeur. Cette
méthode spécifique est utilisable pour des recherches détaillées portant sur la Smart Structure en question.
Exemple de déclaration de méthode :
/**
* Get a random integer between 1 and 10
*
* @searchLabel Random integer between 1 and 10
* @searchType int
* @searchType double
* @searchType money
*/
public function getRandomNumber() {
return mt_rand(1, 10);
}
Le tag @searchLabel
permet de spécifier le libellé qui est présenté lors de l'affichage de la liste des méthodes
compatibles (traduit en fonction de la locale de l'utilisateur).
Le tag @searchType
permet de spécifier les types de Smart Fields sur lesquels cette méthode est utilisable.
L'interface de composition des critères de lla recherche détaillée ne présentera alors que les méthodes compatibles avec
le Smart Field du critère.
Pour des besoins plus complexes de sélection des méthodes compatibles, vous pouvez surcharger la méthode
SmartElement::getSearchMethods()
pour enlever ou ajouter des méthodes à la liste générée par défaut. Les méthodes que
vous ajoutez devront aussi avoir les tags @searchLabel
et @searchType
positionné.
Exemple de surcharge de SmartElement::getSearchMethods()
:
public function getSearchMethods($attrId, $attrType) {
$methods = parent::getSearchMethods($attrId, $attrType);
if ($attrType == 'date' || $attrType == 'timestamp') {
/*
* Ajouter avant-hier et après-demain
* pour les attributs de type 'date' et 'timestamp'
*/
$methods = array_merge(
$methods,
array(
array(
'label' => _("Day before yesterday"),
'method' => '::getDate(-2)'
),
array(
'label' => _("Day after tomorrow"),
'method' => '::getDate(2)'
)
)
);
}
return $methods
}
# Rapports
Les rapports (Smart Structure REPORT
) héritent de la Smart Structure recherche détaillée (Smart StructureDSEARCH
).
# Création d'un rapport
# Critères de recherche
L'enregistrement de la requête est identique à celle de la recherche détaillée.
use Anakeen\Core\SEManager;
use Anakeen\Search\SearchElements;
use SmartStructure\Fields\Dsearch as dsearch;
$rd = SEManager::createDocument("REPORT");
$rd->setAttributeValue(dsearch::ba_title, "Report with toview Tag");
$rd->setAttributeValue(dsearch::se_famid, "IUSER");
$rd->setAttributeValue(dsearch::ba_title, "Report Active Users with email");
$criteria = array(
array(
dsearch::se_attrids => \SmartStructure\Fields\Iuser::us_status,
dsearch::se_funcs => "=",
dsearch::se_keys => "A"
),
array(
dsearch::se_attrids => \SmartStructure\Fields\Iuser::us_extmail,
dsearch::se_funcs => "is not null",
dsearch::se_keys => ""
)
);
$rd->setAttributeValue(dsearch::se_t_detail, $criteria);
$rd->store();
$s = new SearchElements();
$s->useCollection($rd->initid);
$dl = $s->getResults();
foreach ($dl as $d) {
print $d->getTitle();
}
# Présentation du rapport
Les colonnes à afficher sont indiquées par le Smart Field rep_idcols
. Ce Smart Field doit contenir un identnifiant de
Smart Field ou de propriété.
$columns = array(
array(
Attribute\Report::rep_lcols => "Utilisateurs",
Attribute\Report::rep_idcols => "title",
Attribute\Report::rep_foots => "CARD"
),
array(
Attribute\Report::rep_lcols => "Utilisateurs",
Attribute\Report::rep_idcols => Attribute\Iuser::us_whatid
),
array(
Attribute\Report::rep_lcols => "Courriel",
Attribute\Report::rep_idcols => Attribute\Iuser::us_mail
),
array(
Attribute\Report::rep_lcols => "Groupes",
Attribute\Report::rep_idcols => Attribute\Iuser::us_idgroup
),
array(
Attribute\Report::rep_lcols => "Identifiant groupes",
Attribute\Report::rep_displayoption => "docid",
Attribute\Report::rep_idcols => Attribute\Iuser::us_idgroup
)
);
$report->setAttributeValue(Attribute\Report::rep_tcols, $columns);
$report->setAttributeValue(Attribute\Report::rep_style, "standard1");
$report->store();
Le Smart Field rep_lcols
(libellé) n'est pas utilisé lors de la génération. Le libellé affiché correspond au libellé
du Smart Field ou de la propriété.
Pour le cas particulier des Smart fields de type docid
et de type account
si le Smart field req_displayoption
, si
le Smart Fields rep_displayoption
vaut docid
, alors ce sont les identifiants des Smart Fields qui sont affichés au
lieu des titres des Smart Fields.
Pour la propriété title
, des précautions doivent être prise en cas de surcharge du titre.
# Recherche spécialisée
Pour toute recherche non prévue en standard par l'interface, il est possible de programmer des recherches spécifiques. Elles pourront ensuite être utilisées comme une recherche "normale" depuis l'interface grâce à la Smart Structure recherche spécialisée. Lorsque vous éditez une recherche spécialisée, vous devez renseigner :
- Le fichier PHP où se trouve la fonction de recherche,
Ce fichier doit être dans le répertoire
EXTERNALS
du contexte. - Le nom de cette fonction.
Cette fonction prend les 3 arguments suivants:
- start: index de de départ pour la recherche.
- slice : nombre max d'élément à retourner.
- userid : utilisateur courant.
Des arguments supplémentaires peuvent êgalement être fournis:
Exemple: Fichier ÈXTERNALS/my.test.phpp$
namespace My;
use Anakeen\Search\SearchElementData;
/**
* function use for specialised search
* return all Smart Element tagged TOVIEWDOC by current usr=er
*
* @param int $start start cursor
* @param int $slice offset ("ALL" means no limit)
* @param int $userid user system identifier (NOT USED in this function)
*
*/
function myToViewTags($start = "0", $slice = "ALL", $userid = 0)
{
$tag = "TOVIEWDOC";
$s = new SearchElementData();
$s->join("id = docutag(id)");
$s->setSlice($slice);
$s->setStart($start);
$s->addFilter("docutag.uid = %d", $userid);
$s->addFilter("docutag.tag = '%s'", $tag);
return $s->search()->getResults();
}
# Enregistrement d'une recherche spécialisée
L'enregistrement se fait en créant un Smart Element de la Smart Structure SSEARCH
. Les Smart Fields se_phpfile
et
se_phpfunc
permettent d'indiquer la fonction à utiliser.
use Anakeen\Core\SEManager;
use SmartStructure\Fields\Ssearch as ssearch;
$sd = SEManager::createDocument("SSEARCH");
$sd->setValue(ssearch::ba_title, "Search TOVIEWDOC Tag");
$sd->setValue(ssearch::se_phpfile, "myTest.php"); //EXTERNALS/myTest.php
$sd->setValue(ssearch::se_phpfunc, "My\\myToViewTags");
$sd->store();
# Arguments supplémentaires de la fonction
Des arguments supplémentaires peuvent être ajoutés dans le Smart Field ArgumentPHP' (
se_phparg`). Ils sont ajoutés
dans l'appel à partir de la quatrième position. Pour ajouter plusieurs arguments, il faut les séparer par une virgule
(exemple: 2134,ceci est un test, dernier argument).
Dans ces arguments, il est possible de référencer:
- N'importe quel Smart Field ou propriété du Smart Element recherche, au moyen de la notation
%ATTRID%
ou%PROPID%
,Par exemple,
%TITLE%
pour avoir le titre de la recherche - L'objet recherche lui-même au moyen du mot clé
%THIS%
.
# Retour de la fonction
La fonction de recherche doit retourner un tableau de Smart Elements bruts (type array
et non object
). Ce type est
celui retourné par la classe SearchElements
.