<commit_before><?php
/*
 * @author Anakeen
 * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License
 * @package FDL
*/
/**
 * Functions used for edition help
 *
 * @author Anakeen
 * @version $Id: FDL_external.php,v 1.71 2009/01/13 09:37:25 eric Exp $
 * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License
 * @package FDL
 * @subpackage
 */
/**
 */

include_once ("FDL/Class.Dir.php");
include_once ("FDL/Lib.Dir.php");

function vault_filename($th, $fileid)
{
    
    if (preg_match(PREGEXPFILE, $fileid, $reg)) {
        // reg[1] is mime type
        $vf = newFreeVaultFile($th->dbaccess);
        if ($vf->Show($reg[2], $info) == "") $fname = $info->name;
        else $fname = sprintf(_("file %d") , $th->initid);
    } else {
        $fname = sprintf(_("file %d") , $th->initid);
    }
    
    return array(
        $fname
    );
}
/**
 * Functions used for edition help
 *
 * @param string $dbaccess database specification
 * @param int $docid identifier document
 * @return array first item : the title
 */
function gettitle($dbaccess, $docid)
{
    
    $doc = new_Doc($dbaccess, $docid);
    if ($doc->isAffected()) return array(
        $doc->title
    );
    return array(
        "?",
        " "
    ); // suppress
    
}
/**
 * link enum definition from other def
 */
function linkenum($famid, $attrid)
{
    
    $dbaccess = getParam("FREEDOM_DB");
    if (!is_numeric($famid)) $famid = getFamIdFromName($dbaccess, $famid);
    $soc = new_Doc($dbaccess, $famid);
    if ($soc->isAffected()) {
        /**
         * @var NormalAttribute $a
         */
        $a = $soc->getAttribute($attrid);
        if ($a->phpfunc == "-") {
            return EnumAttributeTools::getFlatEnumNotation($soc->id, $a->id);
        }
        return $a->phpfunc;
    }
    return "";
}
/**
 * get mail address from MAILRECIPENT families
 * @param $dbaccess
 * @param $name
 * @return array|string
 */
function lmail($dbaccess, $name)
{
    
    $tr = array();
    $sf = new SearchDoc($dbaccess, -1);
    $sf->setObjectReturn();
    $sf->overrideViewControl();
    $sf->addFilter("atags ~* 'MAILRECIPIENT'");
    $dlf = $sf->search()->getDocumentList();
    
    if ($dlf->count() == 0) return sprintf(_("none families are described to be used as recipient"));
    foreach ($dlf as $fam) {
        $cfam = createTmpDoc($dbaccess, $fam->id);
        /**
         * @var IMailRecipient $cfam
         */
        if (!method_exists($cfam, "getMail")) return sprintf(_("family %s does not implement IMailRecipent - missing getMail method") , $fam->name);
        if (!method_exists($cfam, "getMailAttribute")) return sprintf(_("family %s does not implement IMailRecipent - missing getMailAttribute method") , $fam->name);
        if (!method_exists($cfam, "getMailTitle")) return sprintf(_("family %s does not implement IMailRecipient - missing getMailTitle method") , $fam->name);
        
        $mailAttr = $cfam->getMailAttribute();
        $s = new SearchDoc($dbaccess, $fam->id);
        $s->setObjectReturn();
        $s->setSlice(100);
        if ($mailAttr) $s->addFilter("%s is not null", $mailAttr);
        if ($name != "") {
            if ($mailAttr) $s->addFilter("(title ~* '%s') or (%s ~* '%s')", $name, $mailAttr, $name);
            else $s->addFilter("(title ~* '%s')", $name, $name);
        }
        $dl = $s->search()->getDocumentList();
        foreach ($dl as $dest) {
            /**
             * @var _IUSER $dest
             */
            $mailTitle = $dest->getMailTitle();
            $mail = $dest->getMail();
            if ($mailTitle == '') {
                $mailTitle = $mail;
            }
            $usw = $dest->getRawValue("us_whatid");
            $uid = "";
            if ($usw > 0) {
                $uid = $dest->id;
                $type = "link"; //$type="link";  // cause it is a bool
                
            } else {
                $type = "plain"; //$type="plain";
                $uid = " ";
            }
            $tr[] = array(
                xml_entity_encode($mailTitle) ,
                $mail,
                $uid,
                $type
            );
        }
    }
    usort($tr, function ($a, $b)
    {
        return strcasecmp($a[0], $b[0]);
    });
    return $tr;
}

function tplmail($dbaccess, $type, $famid, $wfamid, $name)
{
    switch ($type) {
        case 'F': // address fix
            return lmail($dbaccess, $name);
            break;

        case 'A': // value of attribute
            if (!$famid) {
                return _("family must be defined");
            }
            $ta = getFamAttribute($dbaccess, $famid, 'text', false, $name);
            return $ta;
            break;

        case 'D': // value of attribute
            if (!$famid) {
                return _("family must be defined");
            }
            $ta = getFamAttribute($dbaccess, $famid, 'docid', false, $name);
            $ta = array_merge($ta, getFamAttribute($dbaccess, $famid, 'account', false, $name));
            return $ta;
            break;

        case 'DE':
            if (!$famid) {
                return _("family must be defined");
            }
            $ta = getFamAttribute($dbaccess, $famid, 'docid', true, $name);
            $ta = array_merge($ta, getFamAttribute($dbaccess, $famid, 'account', true, $name));
            return $ta;
            break;

        case 'G': // value of attribute
            if (!$famid) {
                return _("family must be defined");
            }
            $ta = getFamAttribute($dbaccess, $famid, 'file', false, $name);
            $ta = array_merge($ta, getFamAttribute($dbaccess, $famid, 'image', false, $name));
            return $ta;
            break;

        case 'E': // value of attribute
            if (!$famid) {
                return _("family must be defined");
            }
            $ta = getFamAttribute($dbaccess, $famid, '', true, $name);
            return $ta;
        case 'WA': // value of attribute
            if (!$wfamid) {
                return _("cycle family must be defined");
            }
            $ta = getFamAttribute($dbaccess, $wfamid, 'text', false, $name);
            return $ta;
            break;

        case 'WE': // value of attribute
            if (!$wfamid) {
                return _("cycle family must be defined");
            }
            $ta = getFamAttribute($dbaccess, $wfamid, '', true, $name);
            return $ta;
            break;

        case 'WD': // value of attribute
            if (!$wfamid) {
                return _("cycle family must be defined");
            }
            $ta = getFamAttribute($dbaccess, $wfamid, 'docid', false, $name);
            return $ta;
            break;

        case 'PR':
            if (!$famid) {
                return _("family must be defined");
            }
            $ta = getFamAttribute($dbaccess, $famid, 'docid', true, $name);
            return $ta;
            break;

        case 'WPR':
            if (!$wfamid) {
                return _("cycle family must be defined");
            }
            $ta = getFamAttribute($dbaccess, $wfamid, 'docid', true, $name);
            return $ta;
            break;

        case 'P':
            return getGlobalsParameters($name);
            break;
    }
    return "error tplmail($dbaccess,$type,$famid, $name)";
}

function tpluser($dbaccess, $type, $famid, $wfamid, $name)
{
    switch ($type) {
        case 'F': // address fix
            $users = lfamily($dbaccess, "IUSER", $name);
            if (is_array($users)) {
                foreach ($users as $k => $v) {
                    $users[$k][1] = $v[1] . ' (' . $v[2] . ')';
                }
            }
            return $users;
        default:
            return tplmail($dbaccess, $type, $famid, $wfamid, $name);
    }
}

function getGlobalsParameters($name)
{
    include_once ("Class.QueryDb.php");
    $q = new QueryDb("", "ParamDef");
    
    $tr = array();
    $q->AddQuery("isglob = 'Y'");
    if ($name) $q->AddQuery("name ~* '" . pg_escape_string($name) . "'");
    $q->order_by = "name";
    $la = $q->Query(0, 20, "TABLE");
    foreach ($la as $k => $v) {
        $p = $v["name"] . ' (' . $v["descr"] . ')';
        $tr[] = array(
            $p,
            $p
        );
    }
    return $tr;
}
/**
 * attribut list to be use in mail template
 */
function getFamAttribute($dbaccess, $famid, $type = "text", $param = false, $name = "")
{
    $doc = createDoc($dbaccess, $famid, false);
    $tr = array();
    if ($param) {
        $tinter = $doc->getParamAttributes();
    } else {
        $tinter = $doc->GetNormalAttributes();
    }
    $name = strtolower($name);
    // HERE HERE HERE
    $pattern_name = preg_quote($name, "/");
    $pattern_type = ($type);
    foreach ($tinter as $k => $v) {
        if (($name == "") || (preg_match("/$pattern_name/i", $v->getLabel() , $reg)) || (preg_match("/$pattern_name/", $v->id, $reg))) {
            preg_match("/$pattern_type/", $v->type, $reg);
            if (($type == "") || ($v->type == $type) || ((strpos($type, '|') > 0) && (preg_match("/$pattern_type/", $v->type, $reg)))) {
                $r = $v->id . ' (' . $v->getLabel() . ')';
                $tr[] = array(
                    $r,
                    $r
                );
            }
        }
    }
    return $tr;
}
// liste des familles
function lfamilies($dbaccess, $name = '', $subfam = "")
{
    //'lsociety(D,US_SOCIETY):US_IDSOCIETY,US_SOCIETY,
    global $action;
    
    if ($subfam == "") {
        $tinter = GetClassesDoc($dbaccess, $action->user->id, 0, "TABLE");
    } else {
        if (!is_numeric($subfam)) {
            $subfam = getFamIdFromName($dbaccess, $subfam);
        }
        $cdoc = new_Doc($dbaccess, $subfam);
        $tinter = $cdoc->GetChildFam();
        $tinter[] = get_object_vars($cdoc);
    }
    
    $tr = array();
    
    $name = strtolower($name);
    // HERE HERE HERE
    $pattern_name = preg_quote($name, "/");
    while (list($k, $v) = each($tinter)) {
        $ftitle = DocFam::getLangTitle($v);
        if (($name == "") || (preg_match("/$pattern_name/i", $ftitle, $reg))) {
            $tr[] = array(
                $ftitle,
                $v["id"],
                $ftitle
            );
        }
    }
    return $tr;
}
// liste des documents par familles

/**
 * list of documents of a same family
 *
 * @param string $dbaccess database specification
 * @param string $famid family identifier (if 0 any family). It can be internal name
 * @param string $name string filter on the title
 * @param int $dirid identifier of folder for restriction to a folder tree (deprecated)
 * @param array $filter additionnals SQL filters
 * @param string $idid the document id to use (default: id)
 * @param bool $withDiacritic to search with accent
 * @return array/string*3 array of (title, identifier, title)
 */
function lfamily($dbaccess, $famid, $name = "", $dirid = 0, $filter = array() , $idid = "id", $withDiacritic = false)
{
    $only = false;
    if ($famid[0] == '-') {
        $only = true;
        $famid = substr($famid, 1);
    }
    
    if (!is_numeric($famid)) {
        $famName = $famid;
        $famid = getFamIdFromName($dbaccess, $famName);
        if ($famid <= 0) {
            return sprintf(_("family %s not found") , $famName);
        }
    }
    $s = new SearchDoc($dbaccess, $famid); //$famid=-(abs($famid));
    if ($only) {
        $s->only = true;
    }
    if (!is_array($filter)) {
        if (trim($filter) != "") $filter = array(
            $filter
        );
        else $filter = array();
    }
    if (count($filter) > 0) {
        foreach ($filter as $f) {
            $s->addFilter($f);
        }
    }
    
    if ($name != "" && is_string($name)) {
        if (!$withDiacritic) {
            $name = setDiacriticRules(mb_strtolower($name));
        }
        $s->addFilter("title ~* '%s'", $name);
    }
    $s->setSlice(100);
    
    if ($dirid) $s->useCollection($dirid);
    $s->returnsOnly(array(
        "title",
        $idid
    ));
    $tinter = $s->search();
    if ($s->getError()) {
        return $s->getError();
    }
    
    $tr = array();
    
    foreach ($tinter as $k => $v) {
        $tr[] = array(
            htmlspecialchars($v["title"]) ,
            $v[$idid],
            $v["title"]
        );
    }
    return $tr;
}
/**
 * create preg rule to search without diacritic
 * @see lfamily
 * @param string $text
 * @return string rule for preg
 */
function setDiacriticRules($text)
{
    $dias = array(
        "a|à|á|â|ã|ä|å",
        "o|ò|ó|ô|õ|ö|ø",
        "e|è|é|ê|ë",
        "c|ç",
        "i|ì|í|î|ï",
        "u|ù|ú|û|ü",
        "y|ÿ",
        "n|ñ"
    );
    foreach ($dias as $dia) {
        $text = preg_replace("/[" . str_replace("|", "", $dia) . "]/u", "[$dia]", $text);
    }
    return $text;
}
// alias name

/**
 * @deprecated use lfamily instead
 * @param $dbaccess
 * @param $famid
 * @param string $name
 * @param int $dirid
 * @param array $filter
 * @param string $idid
 * @return mixed
 */
function lfamilly($dbaccess, $famid, $name = "", $dirid = 0, $filter = array() , $idid = "id")
{
    return lfamily($dbaccess, $famid, $name, $dirid, $filter, $idid);
}
/**
 * list of documents of a same family and their specific attributes
 *
 * @param string $dbaccess database specification
 * @param string $famid family identifier (if 0 any family). It can be internal name
 * @param string $name string filter on the title
 * @param string $attrids argument variable of name of attribute to be returned
 * @return array/string*3 array of (title, identifier, attr1, attr2, ...)
 */
function lfamilyvalues($dbaccess, $famid, $name = "")
{
    //'lsociety(D,US_SOCIETY):US_IDSOCIETY,US_SOCIETY,
    global $action;
    
    $only = false;
    if ($famid[0] == '-') {
        $only = true;
        $famid = substr($famid, 1);
    }
    
    if (!is_numeric($famid)) {
        $famid = getFamIdFromName($dbaccess, $famid);
    }
    $filter = array();
    if ($name != "") {
        $name = pg_escape_string($name);
        $filter[] = "title ~* '$name'";
    }
    $attr = array();
    $args = func_get_args();
    foreach ($args as $k => $v) {
        if ($k > 2) $attr[] = strtolower($v);
    }
    //$famid=-(abs($famid));
    if ($only) $famid = - ($famid);
    $tinter = internalGetDocCollection($dbaccess, $dirid = 0, 0, 100, $filter, $action->user->id, "TABLE", $famid, false, "title");
    
    $tr = array();
    
    foreach ($tinter as $k => $v) {
        $tr[$k] = array(
            $v["title"]
        );
        foreach ($attr as $a) {
            $tr[$k][] = $v[$a];
        }
    }
    return $tr;
}
/**
 * list of documents of a same family and which are in the $kid category
 *
 * @param string $dbaccess database specification
 * @param string $famname family internal name
 * @param string $aid enum attribute identifier
 * @param string $kid enum key to search
 * @param string $name string filter on the title
 * @param array $filter additionnals SQL filters
 * @return array/string*3 array of (title, identifier, title)
 */
function lkfamily($dbaccess, $famname, $aid, $kid, $name, $filter = array())
{
    //'lsociety(D,US_SOCIETY):US_IDSOCIETY,US_SOCIETY,
    global $action;
    
    if ($name != "") {
        $name = pg_escape_string($name);
        $filter[] = "title ~* '.*$name.*'";
    }
    
    $tinter = getKindDoc($dbaccess, $famname, $aid, $kid, $name, $filter);
    
    $tr = array();
    
    while (list($k, $v) = each($tinter)) {
        
        $tr[] = array(
            $v["title"],
            $v["id"],
            $v["title"]
        );
    }
    return $tr;
}
/**
 * return account documents
 * @param string $filterName title filter key
 * @param int $limit max account returned
 * @return array
 */
function fdlGetDocuments($families, $filterName = '', $limit = 15, $extraFilter = '')
{
    $tout = array();
    $famname = explode('|', $families);
    
    foreach ($famname as $famid) {
        if (count($tout) < $limit) {
            $s = new SearchDoc(getDbAccess() , $famid);
            if ($filterName) $s->addFilter("title ~* '%s'", $filterName);
            if ($extraFilter) $s->addFilter($extraFilter);
            $s->setSlice($limit);
            $s->setObjectReturn();
            $s->search();
            if ($s->getError()) return $s->getError();
            
            while ($doc = $s->getNextDoc()) {
                $title = $doc->getHTMLTitle();
                $tout[] = array(
                    sprintf('<img width="10px" src="%s">%s', $doc->getIcon('', 10) , $title) ,
                    $doc->initid,
                    $title
                );
            }
        }
    }
    if ((count($tout) == 0) && ($filterName != '')) return sprintf(_("no document match '%s'") , $filterName);
    return $tout;
}
/**
 * return account list
 * @param string $filterName filter key
 * @param int $limit max result limit
 * @param string $options option for role or group
 * @return array|string
 */
function fdlGetAccounts($filterName = '', $limit = 15, $options = '')
{
    $sort = 'lastname';
    $searchinmail = false;
    $s = new SearchAccount();
    $s->setSlice($limit);
    if (preg_match('/usemailfilter\s*=([^|]*)/', $options, $regMatch)) {
        $searchinmail = trim($regMatch[1]);
        $searchinmail = ($searchinmail == "yes");
    }
    if (preg_match('/role\s*=([^|]*)/', $options, $regRole)) {
        $roles = explode(',', $regRole[1]);
        
        foreach ($roles as $role) {
            try {
                $s->addRoleFilter($role);
            }
            catch(Exception $e) {
                return $e->getMessage();
            }
        }
    }
    if (preg_match('/group\s*=([^|]*)/', $options, $regGroup)) {
        $groups = explode(',', $regGroup[1]);
        
        foreach ($groups as $group) {
            try {
                $s->addGroupFilter($group);
            }
            catch(Exception $e) {
                return $e->getMessage();
            }
        }
    }
    
    if (preg_match('/match\s*=([^|]*)/', $options, $regMatch)) {
        $match = trim($regMatch[1]);
        switch ($match) {
            case 'all':
                break;

            case 'group':
                $s->setTypeFilter($s::groupType);
                break;

            case 'role':
                $s->setTypeFilter($s::roleType);
                break;

            default:
                $s->setTypeFilter($s::userType);
        }
    } else {
        $s->setTypeFilter($s::userType);
    }
    
    if (preg_match('/family\s*=([^|]*)/', $options, $regMatch)) {
        $match = trim($regMatch[1]);
        $s->filterFamily($match);
    }
    $tr = array();
    
    $condName = "";
    if ($filterName) {
        $tname = explode(' ', $filterName);
        $filterName = pg_escape_string($filterName);
        $condmail = '';
        if ($searchinmail) $condmail = sprintf("or (mail ~* '%s')", $filterName);
        if (count($tname) > 1) {
            $condName = sprintf(" (coalesce(firstname,'') || ' ' || coalesce(lastname,'') ~* '%s' $condmail)", $filterName);
        } else {
            $condName = sprintf(" (firstname ~* '%s' or lastname ~* '%s' $condmail)", $filterName, $filterName);
        }
    }
    
    if ($condName) $s->addFilter($condName);
    if (!$sort) $sort = 'lastname';
    $s->setOrder($sort);
    $s->overrideViewControl(false);
    $al = $s->search();
    foreach ($al as $account) {
        
        $mail = $account->mail ? (' (' . mb_substr($account->mail, 0, 40) . ')') : '';
        $tr[] = array(
            htmlspecialchars($account->lastname . " " . $account->firstname . $mail) ,
            $account->fid,
            $account->lastname . " " . $account->firstname
        );
    }
    
    return $tr;
}
/**
 * return list of string for multiple static choice
 *
 * @param string $val filter value - can be empty => see all choices
 * @param string $enum possible choices like 'the first|the second|the last'
 * @return array/string*2 array of (enum, enum)
 */
function lenum($val, $enum)<commit_msg>Better search for account (refs #3912)<commit_after><?php
/*
 * @author Anakeen
 * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License
 * @package FDL
*/
/**
 * Functions used for edition help
 *
 * @author Anakeen
 * @version $Id: FDL_external.php,v 1.71 2009/01/13 09:37:25 eric Exp $
 * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License
 * @package FDL
 * @subpackage
 */
/**
 */

include_once ("FDL/Class.Dir.php");
include_once ("FDL/Lib.Dir.php");

function vault_filename($th, $fileid)
{
    
    if (preg_match(PREGEXPFILE, $fileid, $reg)) {
        // reg[1] is mime type
        $vf = newFreeVaultFile($th->dbaccess);
        if ($vf->Show($reg[2], $info) == "") $fname = $info->name;
        else $fname = sprintf(_("file %d") , $th->initid);
    } else {
        $fname = sprintf(_("file %d") , $th->initid);
    }
    
    return array(
        $fname
    );
}
/**
 * Functions used for edition help
 *
 * @param string $dbaccess database specification
 * @param int $docid identifier document
 * @return array first item : the title
 */
function gettitle($dbaccess, $docid)
{
    
    $doc = new_Doc($dbaccess, $docid);
    if ($doc->isAffected()) return array(
        $doc->title
    );
    return array(
        "?",
        " "
    ); // suppress
    
}
/**
 * link enum definition from other def
 */
function linkenum($famid, $attrid)
{
    
    $dbaccess = getParam("FREEDOM_DB");
    if (!is_numeric($famid)) $famid = getFamIdFromName($dbaccess, $famid);
    $soc = new_Doc($dbaccess, $famid);
    if ($soc->isAffected()) {
        /**
         * @var NormalAttribute $a
         */
        $a = $soc->getAttribute($attrid);
        if ($a->phpfunc == "-") {
            return EnumAttributeTools::getFlatEnumNotation($soc->id, $a->id);
        }
        return $a->phpfunc;
    }
    return "";
}
/**
 * get mail address from MAILRECIPENT families
 * @param $dbaccess
 * @param $name
 * @return array|string
 */
function lmail($dbaccess, $name)
{
    
    $tr = array();
    $sf = new SearchDoc($dbaccess, -1);
    $sf->setObjectReturn();
    $sf->overrideViewControl();
    $sf->addFilter("atags ~* 'MAILRECIPIENT'");
    $dlf = $sf->search()->getDocumentList();
    
    if ($dlf->count() == 0) return sprintf(_("none families are described to be used as recipient"));
    foreach ($dlf as $fam) {
        $cfam = createTmpDoc($dbaccess, $fam->id);
        /**
         * @var IMailRecipient $cfam
         */
        if (!method_exists($cfam, "getMail")) return sprintf(_("family %s does not implement IMailRecipent - missing getMail method") , $fam->name);
        if (!method_exists($cfam, "getMailAttribute")) return sprintf(_("family %s does not implement IMailRecipent - missing getMailAttribute method") , $fam->name);
        if (!method_exists($cfam, "getMailTitle")) return sprintf(_("family %s does not implement IMailRecipient - missing getMailTitle method") , $fam->name);
        
        $mailAttr = $cfam->getMailAttribute();
        $s = new SearchDoc($dbaccess, $fam->id);
        $s->setObjectReturn();
        $s->setSlice(100);
        if ($mailAttr) $s->addFilter("%s is not null", $mailAttr);
        if ($name != "") {
            if ($mailAttr) $s->addFilter("(title ~* '%s') or (%s ~* '%s')", $name, $mailAttr, $name);
            else $s->addFilter("(title ~* '%s')", $name, $name);
        }
        $dl = $s->search()->getDocumentList();
        foreach ($dl as $dest) {
            /**
             * @var _IUSER $dest
             */
            $mailTitle = $dest->getMailTitle();
            $mail = $dest->getMail();
            if ($mailTitle == '') {
                $mailTitle = $mail;
            }
            $usw = $dest->getRawValue("us_whatid");
            $uid = "";
            if ($usw > 0) {
                $uid = $dest->id;
                $type = "link"; //$type="link";  // cause it is a bool
                
            } else {
                $type = "plain"; //$type="plain";
                $uid = " ";
            }
            $tr[] = array(
                xml_entity_encode($mailTitle) ,
                $mail,
                $uid,
                $type
            );
        }
    }
    usort($tr, function ($a, $b)
    {
        return strcasecmp($a[0], $b[0]);
    });
    return $tr;
}

function tplmail($dbaccess, $type, $famid, $wfamid, $name)
{
    switch ($type) {
        case 'F': // address fix
            return lmail($dbaccess, $name);
            break;

        case 'A': // value of attribute
            if (!$famid) {
                return _("family must be defined");
            }
            $ta = getFamAttribute($dbaccess, $famid, 'text', false, $name);
            return $ta;
            break;

        case 'D': // value of attribute
            if (!$famid) {
                return _("family must be defined");
            }
            $ta = getFamAttribute($dbaccess, $famid, 'docid', false, $name);
            $ta = array_merge($ta, getFamAttribute($dbaccess, $famid, 'account', false, $name));
            return $ta;
            break;

        case 'DE':
            if (!$famid) {
                return _("family must be defined");
            }
            $ta = getFamAttribute($dbaccess, $famid, 'docid', true, $name);
            $ta = array_merge($ta, getFamAttribute($dbaccess, $famid, 'account', true, $name));
            return $ta;
            break;

        case 'G': // value of attribute
            if (!$famid) {
                return _("family must be defined");
            }
            $ta = getFamAttribute($dbaccess, $famid, 'file', false, $name);
            $ta = array_merge($ta, getFamAttribute($dbaccess, $famid, 'image', false, $name));
            return $ta;
            break;

        case 'E': // value of attribute
            if (!$famid) {
                return _("family must be defined");
            }
            $ta = getFamAttribute($dbaccess, $famid, '', true, $name);
            return $ta;
        case 'WA': // value of attribute
            if (!$wfamid) {
                return _("cycle family must be defined");
            }
            $ta = getFamAttribute($dbaccess, $wfamid, 'text', false, $name);
            return $ta;
            break;

        case 'WE': // value of attribute
            if (!$wfamid) {
                return _("cycle family must be defined");
            }
            $ta = getFamAttribute($dbaccess, $wfamid, '', true, $name);
            return $ta;
            break;

        case 'WD': // value of attribute
            if (!$wfamid) {
                return _("cycle family must be defined");
            }
            $ta = getFamAttribute($dbaccess, $wfamid, 'docid', false, $name);
            return $ta;
            break;

        case 'PR':
            if (!$famid) {
                return _("family must be defined");
            }
            $ta = getFamAttribute($dbaccess, $famid, 'docid', true, $name);
            return $ta;
            break;

        case 'WPR':
            if (!$wfamid) {
                return _("cycle family must be defined");
            }
            $ta = getFamAttribute($dbaccess, $wfamid, 'docid', true, $name);
            return $ta;
            break;

        case 'P':
            return getGlobalsParameters($name);
            break;
    }
    return "error tplmail($dbaccess,$type,$famid, $name)";
}

function tpluser($dbaccess, $type, $famid, $wfamid, $name)
{
    switch ($type) {
        case 'F': // address fix
            $users = lfamily($dbaccess, "IUSER", $name);
            if (is_array($users)) {
                foreach ($users as $k => $v) {
                    $users[$k][1] = $v[1] . ' (' . $v[2] . ')';
                }
            }
            return $users;
        default:
            return tplmail($dbaccess, $type, $famid, $wfamid, $name);
    }
}

function getGlobalsParameters($name)
{
    include_once ("Class.QueryDb.php");
    $q = new QueryDb("", "ParamDef");
    
    $tr = array();
    $q->AddQuery("isglob = 'Y'");
    if ($name) $q->AddQuery("name ~* '" . pg_escape_string($name) . "'");
    $q->order_by = "name";
    $la = $q->Query(0, 20, "TABLE");
    foreach ($la as $k => $v) {
        $p = $v["name"] . ' (' . $v["descr"] . ')';
        $tr[] = array(
            $p,
            $p
        );
    }
    return $tr;
}
/**
 * attribut list to be use in mail template
 */
function getFamAttribute($dbaccess, $famid, $type = "text", $param = false, $name = "")
{
    $doc = createDoc($dbaccess, $famid, false);
    $tr = array();
    if ($param) {
        $tinter = $doc->getParamAttributes();
    } else {
        $tinter = $doc->GetNormalAttributes();
    }
    $name = strtolower($name);
    // HERE HERE HERE
    $pattern_name = preg_quote($name, "/");
    $pattern_type = ($type);
    foreach ($tinter as $k => $v) {
        if (($name == "") || (preg_match("/$pattern_name/i", $v->getLabel() , $reg)) || (preg_match("/$pattern_name/", $v->id, $reg))) {
            preg_match("/$pattern_type/", $v->type, $reg);
            if (($type == "") || ($v->type == $type) || ((strpos($type, '|') > 0) && (preg_match("/$pattern_type/", $v->type, $reg)))) {
                $r = $v->id . ' (' . $v->getLabel() . ')';
                $tr[] = array(
                    $r,
                    $r
                );
            }
        }
    }
    return $tr;
}
// liste des familles
function lfamilies($dbaccess, $name = '', $subfam = "")
{
    //'lsociety(D,US_SOCIETY):US_IDSOCIETY,US_SOCIETY,
    global $action;
    
    if ($subfam == "") {
        $tinter = GetClassesDoc($dbaccess, $action->user->id, 0, "TABLE");
    } else {
        if (!is_numeric($subfam)) {
            $subfam = getFamIdFromName($dbaccess, $subfam);
        }
        $cdoc = new_Doc($dbaccess, $subfam);
        $tinter = $cdoc->GetChildFam();
        $tinter[] = get_object_vars($cdoc);
    }
    
    $tr = array();
    
    $name = strtolower($name);
    // HERE HERE HERE
    $pattern_name = preg_quote($name, "/");
    while (list($k, $v) = each($tinter)) {
        $ftitle = DocFam::getLangTitle($v);
        if (($name == "") || (preg_match("/$pattern_name/i", $ftitle, $reg))) {
            $tr[] = array(
                $ftitle,
                $v["id"],
                $ftitle
            );
        }
    }
    return $tr;
}
// liste des documents par familles

/**
 * list of documents of a same family
 *
 * @param string $dbaccess database specification
 * @param string $famid family identifier (if 0 any family). It can be internal name
 * @param string $name string filter on the title
 * @param int $dirid identifier of folder for restriction to a folder tree (deprecated)
 * @param array $filter additionnals SQL filters
 * @param string $idid the document id to use (default: id)
 * @param bool $withDiacritic to search with accent
 * @return array/string*3 array of (title, identifier, title)
 */
function lfamily($dbaccess, $famid, $name = "", $dirid = 0, $filter = array() , $idid = "id", $withDiacritic = false)
{
    $only = false;
    if ($famid[0] == '-') {
        $only = true;
        $famid = substr($famid, 1);
    }
    
    if (!is_numeric($famid)) {
        $famName = $famid;
        $famid = getFamIdFromName($dbaccess, $famName);
        if ($famid <= 0) {
            return sprintf(_("family %s not found") , $famName);
        }
    }
    $s = new SearchDoc($dbaccess, $famid); //$famid=-(abs($famid));
    if ($only) {
        $s->only = true;
    }
    if (!is_array($filter)) {
        if (trim($filter) != "") $filter = array(
            $filter
        );
        else $filter = array();
    }
    if (count($filter) > 0) {
        foreach ($filter as $f) {
            $s->addFilter($f);
        }
    }
    
    if ($name != "" && is_string($name)) {
        if (!$withDiacritic) {
            $name = setDiacriticRules(mb_strtolower($name));
        }
        $s->addFilter("title ~* '%s'", $name);
    }
    $s->setSlice(100);
    
    if ($dirid) $s->useCollection($dirid);
    $s->returnsOnly(array(
        "title",
        $idid
    ));
    $tinter = $s->search();
    if ($s->getError()) {
        return $s->getError();
    }
    
    $tr = array();
    
    foreach ($tinter as $k => $v) {
        $tr[] = array(
            htmlspecialchars($v["title"]) ,
            $v[$idid],
            $v["title"]
        );
    }
    return $tr;
}
/**
 * create preg rule to search without diacritic
 * @see lfamily
 * @param string $text
 * @return string rule for preg
 */
function setDiacriticRules($text)
{
    $dias = array(
        "a|à|á|â|ã|ä|å",
        "o|ò|ó|ô|õ|ö|ø",
        "e|è|é|ê|ë",
        "c|ç",
        "i|ì|í|î|ï",
        "u|ù|ú|û|ü",
        "y|ÿ",
        "n|ñ"
    );
    foreach ($dias as $dia) {
        $text = preg_replace("/[" . str_replace("|", "", $dia) . "]/u", "[$dia]", $text);
    }
    return $text;
}
// alias name

/**
 * @deprecated use lfamily instead
 * @param $dbaccess
 * @param $famid
 * @param string $name
 * @param int $dirid
 * @param array $filter
 * @param string $idid
 * @return mixed
 */
function lfamilly($dbaccess, $famid, $name = "", $dirid = 0, $filter = array() , $idid = "id")
{
    return lfamily($dbaccess, $famid, $name, $dirid, $filter, $idid);
}
/**
 * list of documents of a same family and their specific attributes
 *
 * @param string $dbaccess database specification
 * @param string $famid family identifier (if 0 any family). It can be internal name
 * @param string $name string filter on the title
 * @param string $attrids argument variable of name of attribute to be returned
 * @return array/string*3 array of (title, identifier, attr1, attr2, ...)
 */
function lfamilyvalues($dbaccess, $famid, $name = "")
{
    //'lsociety(D,US_SOCIETY):US_IDSOCIETY,US_SOCIETY,
    global $action;
    
    $only = false;
    if ($famid[0] == '-') {
        $only = true;
        $famid = substr($famid, 1);
    }
    
    if (!is_numeric($famid)) {
        $famid = getFamIdFromName($dbaccess, $famid);
    }
    $filter = array();
    if ($name != "") {
        $name = pg_escape_string($name);
        $filter[] = "title ~* '$name'";
    }
    $attr = array();
    $args = func_get_args();
    foreach ($args as $k => $v) {
        if ($k > 2) $attr[] = strtolower($v);
    }
    //$famid=-(abs($famid));
    if ($only) $famid = - ($famid);
    $tinter = internalGetDocCollection($dbaccess, $dirid = 0, 0, 100, $filter, $action->user->id, "TABLE", $famid, false, "title");
    
    $tr = array();
    
    foreach ($tinter as $k => $v) {
        $tr[$k] = array(
            $v["title"]
        );
        foreach ($attr as $a) {
            $tr[$k][] = $v[$a];
        }
    }
    return $tr;
}
/**
 * list of documents of a same family and which are in the $kid category
 *
 * @param string $dbaccess database specification
 * @param string $famname family internal name
 * @param string $aid enum attribute identifier
 * @param string $kid enum key to search
 * @param string $name string filter on the title
 * @param array $filter additionnals SQL filters
 * @return array/string*3 array of (title, identifier, title)
 */
function lkfamily($dbaccess, $famname, $aid, $kid, $name, $filter = array())
{
    //'lsociety(D,US_SOCIETY):US_IDSOCIETY,US_SOCIETY,
    global $action;
    
    if ($name != "") {
        $name = pg_escape_string($name);
        $filter[] = "title ~* '.*$name.*'";
    }
    
    $tinter = getKindDoc($dbaccess, $famname, $aid, $kid, $name, $filter);
    
    $tr = array();
    
    while (list($k, $v) = each($tinter)) {
        
        $tr[] = array(
            $v["title"],
            $v["id"],
            $v["title"]
        );
    }
    return $tr;
}
/**
 * return account documents
 * @param string $filterName title filter key
 * @param int $limit max account returned
 * @return array
 */
function fdlGetDocuments($families, $filterName = '', $limit = 15, $extraFilter = '')
{
    $tout = array();
    $famname = explode('|', $families);
    
    foreach ($famname as $famid) {
        if (count($tout) < $limit) {
            $s = new SearchDoc(getDbAccess() , $famid);
            if ($filterName) $s->addFilter("title ~* '%s'", $filterName);
            if ($extraFilter) $s->addFilter($extraFilter);
            $s->setSlice($limit);
            $s->setObjectReturn();
            $s->search();
            if ($s->getError()) return $s->getError();
            
            while ($doc = $s->getNextDoc()) {
                $title = $doc->getHTMLTitle();
                $tout[] = array(
                    sprintf('<img width="10px" src="%s">%s', $doc->getIcon('', 10) , $title) ,
                    $doc->initid,
                    $title
                );
            }
        }
    }
    if ((count($tout) == 0) && ($filterName != '')) return sprintf(_("no document match '%s'") , $filterName);
    return $tout;
}
/**
 * return account list
 * @param string $filterName filter key
 * @param int $limit max result limit
 * @param string $options option for role or group
 * @return array|string
 */
function fdlGetAccounts($filterName = '', $limit = 15, $options = '')
{
    $sort = 'lastname';
    $searchinmail = false;
    $s = new SearchAccount();
    $s->setSlice($limit);
    if (preg_match('/usemailfilter\s*=([^|]*)/', $options, $regMatch)) {
        $searchinmail = trim($regMatch[1]);
        $searchinmail = ($searchinmail == "yes");
    }
    if (preg_match('/role\s*=([^|]*)/', $options, $regRole)) {
        $roles = explode(',', $regRole[1]);
        
        foreach ($roles as $role) {
            try {
                $s->addRoleFilter($role);
            }
            catch(Exception $e) {
                return $e->getMessage();
            }
        }
    }
    if (preg_match('/group\s*=([^|]*)/', $options, $regGroup)) {
        $groups = explode(',', $regGroup[1]);
        
        foreach ($groups as $group) {
            try {
                $s->addGroupFilter($group);
            }
            catch(Exception $e) {
                return $e->getMessage();
            }
        }
    }
    
    if (preg_match('/match\s*=([^|]*)/', $options, $regMatch)) {
        $match = trim($regMatch[1]);
        switch ($match) {
            case 'all':
                break;

            case 'group':
                $s->setTypeFilter($s::groupType);
                break;

            case 'role':
                $s->setTypeFilter($s::roleType);
                break;

            default:
                $s->setTypeFilter($s::userType);
        }
    } else {
        $s->setTypeFilter($s::userType);
    }
    
    if (preg_match('/family\s*=([^|]*)/', $options, $regMatch)) {
        $match = trim($regMatch[1]);
        $s->filterFamily($match);
    }
    $tr = array();
    
    $condName = "";
    if ($filterName) {
        $tname = explode(' ', $filterName);
        $condmail = '';
        if ($searchinmail) $condmail = sprintf("|| ' ' || coalesce(mail,'')");
        foreach ($tname as $name) {
            if ($condName) $condName.= " AND ";
            $condName.= sprintf("(coalesce(firstname,'') || ' ' || coalesce(lastname,'') %s ~* '%s')", $condmail, pg_escape_string(setDiacriticRules($name)));
        }
    }
    
    if ($condName) $s->addFilter($condName);
    if (!$sort) $sort = 'lastname';
    $s->setOrder($sort);
    $s->overrideViewControl(false);
    $al = $s->search();
    foreach ($al as $account) {
        
        $mail = $account->mail ? (' (' . mb_substr($account->mail, 0, 40) . ')') : '';
        $tr[] = array(
            htmlspecialchars($account->lastname . " " . $account->firstname . $mail) ,
            $account->fid,
            $account->lastname . " " . $account->firstname
        );
    }
    
    return $tr;
}
/**
 * return list of string for multiple static choice
 *
 * @param string $val filter value - can be empty => see all choices
 * @param string $enum possible choices like 'the first|the second|the last'
 * @return array/string*2 array of (enum, enum)
 */
function lenum($val, $enum)
{'fraction_non_alphanumeric': 0.17790392147141937, 'fraction_numerical': 0.0041396063655743396, 'mean_word_length': 1.975586369671043, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 218, 'https://': 0, 'lorem ipsum': 0, 'www.': 4, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6476832', 'n_tokens_mistral': 13412, 'n_tokens_neox': 12968, 'n_words': 3122}