Merge pull request #10950 from OPEN-DSI/new-extrafield-sellist-chkbxlst-options

New categories options in sellist and chbxlist extrafields
This commit is contained in:
Laurent Destailleur 2019-04-08 13:28:51 +02:00 committed by GitHub
commit da6c5b552f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 320 additions and 305 deletions

View File

@ -984,17 +984,40 @@ class Categorie extends CommonObject
* fullpath = chemin complet compose des id * fullpath = chemin complet compose des id
* *
* @param string $type Type of categories ('customer', 'supplier', 'contact', 'product', 'member') or (0, 1, 2, ...). * @param string $type Type of categories ('customer', 'supplier', 'contact', 'product', 'member') or (0, 1, 2, ...).
* @param int $markafterid Removed all categories including the leaf $markafterid in category tree. * @param int|string|array $markafterid Keep only or removed all categories including the leaf $markafterid in category tree (exclude) or Keep only of category is inside the leaf starting with this id.
* @param int $keeponlyifinleafid Keep only of category is inside the leaf starting with this id. * $markafterid can be an : int (id of category)
* string (categories ids seprated by comma)
* array (list of categories ids)
* @param int $include [=0] Removed or 1=Keep only
* @return array|int Array of categories. this->cats and this->motherof are set, -1 on error * @return array|int Array of categories. this->cats and this->motherof are set, -1 on error
*/ */
public function get_full_arbo($type, $markafterid = 0, $keeponlyifinleafid = 0) public function get_full_arbo($type, $markafterid = 0, $include = 0)
{ {
// phpcs:enable // phpcs:enable
global $conf, $langs; global $conf, $langs;
if (! is_numeric($type)) $type = $this->MAP_ID[$type]; if (! is_numeric($type)) $type = $this->MAP_ID[$type];
if (is_string($markafterid))
{
$markafterid = explode(',', $markafterid);
}
elseif (is_numeric($markafterid))
{
if ($markafterid > 0)
{
$markafterid = array($markafterid);
}
else
{
$markafterid = array();
}
}
elseif (!is_array($markafterid))
{
$markafterid = array();
}
$this->cats = array(); $this->cats = array();
// Init this->motherof that is array(id_son=>id_parent, ...) // Init this->motherof that is array(id_son=>id_parent, ...)
@ -1040,39 +1063,22 @@ class Categorie extends CommonObject
$this->build_path_from_id_categ($key, 0); // Process a branch from the root category key (this category has no parent) $this->build_path_from_id_categ($key, 0); // Process a branch from the root category key (this category has no parent)
} }
// Exclude leaf including $markafterid from tree // Include or exclude leaf including $markafterid from tree
if ($markafterid) if (count($markafterid) > 0)
{ {
$keyfiltercatid = implode('|', $markafterid);
//print "Look to discard category ".$markafterid."\n"; //print "Look to discard category ".$markafterid."\n";
$keyfilter1='^'.$markafterid.'$'; $keyfilter1 = '^' . $keyfiltercatid . '$';
$keyfilter2='_'.$markafterid.'$'; $keyfilter2 = '_' . $keyfiltercatid . '$';
$keyfilter3='^'.$markafterid.'_'; $keyfilter3 = '^' . $keyfiltercatid . '_';
$keyfilter4='_'.$markafterid.'_'; $keyfilter4 = '_' . $keyfiltercatid . '_';
foreach($this->cats as $key => $val) foreach($this->cats as $key => $val)
{ {
if (preg_match('/'.$keyfilter1.'/', $val['fullpath']) || preg_match('/'.$keyfilter2.'/', $val['fullpath']) $test = (preg_match('/' . $keyfilter1 . '/', $val['fullpath']) || preg_match('/' . $keyfilter2 . '/', $val['fullpath'])
|| preg_match('/'.$keyfilter3.'/', $val['fullpath']) || preg_match('/'.$keyfilter4.'/', $val['fullpath'])) || preg_match('/' . $keyfilter3 . '/', $val['fullpath']) || preg_match('/' . $keyfilter4 . '/', $val['fullpath']));
{
unset($this->cats[$key]); if (($test && !$include) || (!$test && $include))
}
}
}
// Exclude leaf including $markafterid from tree
if ($keeponlyifinleafid)
{
//print "Look to discard category ".$keeponlyifinleafid."\n";
$keyfilter1='^'.$keeponlyifinleafid.'$';
$keyfilter2='_'.$keeponlyifinleafid.'$';
$keyfilter3='^'.$keeponlyifinleafid.'_';
$keyfilter4='_'.$keeponlyifinleafid.'_';
foreach($this->cats as $key => $val)
{
if (preg_match('/'.$keyfilter1.'/', $val['fullpath']) || preg_match('/'.$keyfilter2.'/', $val['fullpath'])
|| preg_match('/'.$keyfilter3.'/', $val['fullpath']) || preg_match('/'.$keyfilter4.'/', $val['fullpath']))
{
// We keep
}
else
{ {
unset($this->cats[$key]); unset($this->cats[$key]);
} }

View File

@ -1180,6 +1180,8 @@ class ExtraFields
// 2 : key fields name (if differ of rowid) // 2 : key fields name (if differ of rowid)
// 3 : key field parent (for dependent lists) // 3 : key field parent (for dependent lists)
// 4 : where clause filter on column or table extrafield, syntax field='value' or extra.field=value // 4 : where clause filter on column or table extrafield, syntax field='value' or extra.field=value
// 5 : id category type
// 6 : ids categories list separated by comma for category root
$keyList=(empty($InfoFieldList[2])?'rowid':$InfoFieldList[2].' as rowid'); $keyList=(empty($InfoFieldList[2])?'rowid':$InfoFieldList[2].' as rowid');
@ -1198,9 +1200,16 @@ class ExtraFields
$keyList.= ', '.$parentField; $keyList.= ', '.$parentField;
} }
$filter_categorie = false;
if (count($InfoFieldList) > 5) {
if ($InfoFieldList[0] == 'categorie') {
$filter_categorie = true;
}
}
if ($filter_categorie === false) {
$fields_label = explode('|', $InfoFieldList[1]); $fields_label = explode('|', $InfoFieldList[1]);
if (is_array($fields_label)) if (is_array($fields_label)) {
{
$keyList .= ', '; $keyList .= ', ';
$keyList .= implode(', ', $fields_label); $keyList .= implode(', ', $fields_label);
} }
@ -1208,8 +1217,7 @@ class ExtraFields
$sqlwhere = ''; $sqlwhere = '';
$sql = 'SELECT ' . $keyList; $sql = 'SELECT ' . $keyList;
$sql .= ' FROM ' . MAIN_DB_PREFIX . $InfoFieldList[0]; $sql .= ' FROM ' . MAIN_DB_PREFIX . $InfoFieldList[0];
if (!empty($InfoFieldList[4])) if (!empty($InfoFieldList[4])) {
{
// can use curent entity filter // can use curent entity filter
if (strpos($InfoFieldList[4], '$ENTITY$') !== false) { if (strpos($InfoFieldList[4], '$ENTITY$') !== false) {
$InfoFieldList[4] = str_replace('$ENTITY$', $conf->entity, $InfoFieldList[4]); $InfoFieldList[4] = str_replace('$ENTITY$', $conf->entity, $InfoFieldList[4]);
@ -1226,23 +1234,17 @@ class ExtraFields
$InfoFieldList[4] = str_replace('$ID$', '0', $InfoFieldList[4]); $InfoFieldList[4] = str_replace('$ID$', '0', $InfoFieldList[4]);
} }
//We have to join on extrafield table //We have to join on extrafield table
if (strpos($InfoFieldList[4], 'extra')!==false) if (strpos($InfoFieldList[4], 'extra') !== false) {
{
$sql .= ' as main, ' . MAIN_DB_PREFIX . $InfoFieldList[0] . '_extrafields as extra'; $sql .= ' as main, ' . MAIN_DB_PREFIX . $InfoFieldList[0] . '_extrafields as extra';
$sqlwhere .= ' WHERE extra.fk_object=main.' . $InfoFieldList[2] . ' AND ' . $InfoFieldList[4]; $sqlwhere .= ' WHERE extra.fk_object=main.' . $InfoFieldList[2] . ' AND ' . $InfoFieldList[4];
} } else {
else
{
$sqlwhere .= ' WHERE ' . $InfoFieldList[4]; $sqlwhere .= ' WHERE ' . $InfoFieldList[4];
} }
} } else {
else
{
$sqlwhere .= ' WHERE 1=1'; $sqlwhere .= ' WHERE 1=1';
} }
// Some tables may have field, some other not. For the moment we disable it. // Some tables may have field, some other not. For the moment we disable it.
if (in_array($InfoFieldList[0], array('tablewithentity'))) if (in_array($InfoFieldList[0], array('tablewithentity'))) {
{
$sqlwhere .= ' AND entity = ' . $conf->entity; $sqlwhere .= ' AND entity = ' . $conf->entity;
} }
$sql .= $sqlwhere; $sql .= $sqlwhere;
@ -1252,37 +1254,29 @@ class ExtraFields
dol_syslog(get_class($this) . '::showInputField type=sellist', LOG_DEBUG); dol_syslog(get_class($this) . '::showInputField type=sellist', LOG_DEBUG);
$resql = $this->db->query($sql); $resql = $this->db->query($sql);
if ($resql) if ($resql) {
{
$out .= '<option value="0">&nbsp;</option>'; $out .= '<option value="0">&nbsp;</option>';
$num = $this->db->num_rows($resql); $num = $this->db->num_rows($resql);
$i = 0; $i = 0;
while ($i < $num) while ($i < $num) {
{
$labeltoshow = ''; $labeltoshow = '';
$obj = $this->db->fetch_object($resql); $obj = $this->db->fetch_object($resql);
// Several field into label (eq table:code|libelle:rowid) // Several field into label (eq table:code|libelle:rowid)
$notrans = false; $notrans = false;
$fields_label = explode('|', $InfoFieldList[1]); $fields_label = explode('|', $InfoFieldList[1]);
if (is_array($fields_label)) if (is_array($fields_label)) {
{
$notrans = true; $notrans = true;
foreach ($fields_label as $field_toshow) foreach ($fields_label as $field_toshow) {
{
$labeltoshow .= $obj->$field_toshow . ' '; $labeltoshow .= $obj->$field_toshow . ' ';
} }
} } else {
else
{
$labeltoshow = $obj->{$InfoFieldList[1]}; $labeltoshow = $obj->{$InfoFieldList[1]};
} }
$labeltoshow = dol_trunc($labeltoshow, 45); $labeltoshow = dol_trunc($labeltoshow, 45);
if ($value == $obj->rowid) if ($value == $obj->rowid) {
{ foreach ($fields_label as $field_toshow) {
foreach ($fields_label as $field_toshow)
{
$translabel = $langs->trans($obj->$field_toshow); $translabel = $langs->trans($obj->$field_toshow);
if ($translabel != $obj->$field_toshow) { if ($translabel != $obj->$field_toshow) {
$labeltoshow = dol_trunc($translabel, 18) . ' '; $labeltoshow = dol_trunc($translabel, 18) . ' ';
@ -1291,27 +1285,21 @@ class ExtraFields
} }
} }
$out .= '<option value="' . $obj->rowid . '" selected>' . $labeltoshow . '</option>'; $out .= '<option value="' . $obj->rowid . '" selected>' . $labeltoshow . '</option>';
} } else {
else if (!$notrans) {
{
if (! $notrans)
{
$translabel = $langs->trans($obj->{$InfoFieldList[1]}); $translabel = $langs->trans($obj->{$InfoFieldList[1]});
if ($translabel != $obj->{$InfoFieldList[1]}) { if ($translabel != $obj->{$InfoFieldList[1]}) {
$labeltoshow = dol_trunc($translabel, 18); $labeltoshow = dol_trunc($translabel, 18);
} } else {
else {
$labeltoshow = dol_trunc($obj->{$InfoFieldList[1]}, 18); $labeltoshow = dol_trunc($obj->{$InfoFieldList[1]}, 18);
} }
} }
if (empty($labeltoshow)) $labeltoshow = '(not defined)'; if (empty($labeltoshow)) $labeltoshow = '(not defined)';
if ($value==$obj->rowid) if ($value == $obj->rowid) {
{
$out .= '<option value="' . $obj->rowid . '" selected>' . $labeltoshow . '</option>'; $out .= '<option value="' . $obj->rowid . '" selected>' . $labeltoshow . '</option>';
} }
if (!empty($InfoFieldList[3]) && $parentField) if (!empty($InfoFieldList[3]) && $parentField) {
{
$parent = $parentName . ':' . $obj->{$parentField}; $parent = $parentName . ':' . $obj->{$parentField};
} }
@ -1324,9 +1312,17 @@ class ExtraFields
$i++; $i++;
} }
$this->db->free($resql); $this->db->free($resql);
} } else {
else {
print 'Error in request ' . $sql . ' ' . $this->db->lasterror() . '. Check setup of extra parameters.<br>'; print 'Error in request ' . $sql . ' ' . $this->db->lasterror() . '. Check setup of extra parameters.<br>';
}
} else {
$data = $form->select_all_categories(Categorie::$MAP_ID_TO_CODE[$InfoFieldList[5]], '', 'parent', 64, $InfoFieldList[6], 1, 1);
$out .= '<option value="0">&nbsp;</option>';
foreach ($data as $data_key => $data_value) {
$out .= '<option value="' . $data_key . '"';
$out .= ($value == $data_key ? ' selected' : '');
$out .= '>' . $data_value . '</option>';
}
} }
} }
$out.='</select>'; $out.='</select>';
@ -1367,6 +1363,8 @@ class ExtraFields
// 2 : key fields name (if differ of rowid) // 2 : key fields name (if differ of rowid)
// 3 : key field parent (for dependent lists) // 3 : key field parent (for dependent lists)
// 4 : where clause filter on column or table extrafield, syntax field='value' or extra.field=value // 4 : where clause filter on column or table extrafield, syntax field='value' or extra.field=value
// 5 : id category type
// 6 : ids categories list separated by comma for category root
$keyList = (empty($InfoFieldList[2]) ? 'rowid' : $InfoFieldList[2] . ' as rowid'); $keyList = (empty($InfoFieldList[2]) ? 'rowid' : $InfoFieldList[2] . ' as rowid');
if (count($InfoFieldList) > 3 && ! empty($InfoFieldList[3])) { if (count($InfoFieldList) > 3 && ! empty($InfoFieldList[3])) {
@ -1381,6 +1379,14 @@ class ExtraFields
} }
} }
$filter_categorie = false;
if (count($InfoFieldList) > 5) {
if ($InfoFieldList[0] == 'categorie') {
$filter_categorie = true;
}
}
if ($filter_categorie === false) {
$fields_label = explode('|', $InfoFieldList[1]); $fields_label = explode('|', $InfoFieldList[1]);
if (is_array($fields_label)) { if (is_array($fields_label)) {
$keyList .= ', '; $keyList .= ', ';
@ -1432,17 +1438,14 @@ class ExtraFields
if (!empty($matchCondition[1]) && !empty($matchCondition[3]) && $matchCondition[1] != $matchCondition[3]) { if (!empty($matchCondition[1]) && !empty($matchCondition[3]) && $matchCondition[1] != $matchCondition[3]) {
// Nobody sain would do that without parentheses // Nobody sain would do that without parentheses
$InfoFieldList[4] = str_replace('$ID$', '0', $InfoFieldList[4]); $InfoFieldList[4] = str_replace('$ID$', '0', $InfoFieldList[4]);
} } else {
else {
if (!empty($matchCondition[1])) { if (!empty($matchCondition[1])) {
$boolCond = (($matchCondition[1] == "AND") ? ' AND 1 ' : ' OR 0 '); $boolCond = (($matchCondition[1] == "AND") ? ' AND 1 ' : ' OR 0 ');
$InfoFieldList[4] = str_replace($matchCondition[0], $boolCond . $matchCondition[3], $InfoFieldList[4]); $InfoFieldList[4] = str_replace($matchCondition[0], $boolCond . $matchCondition[3], $InfoFieldList[4]);
} } elseif (!empty($matchCondition[3])) {
elseif (! empty($matchCondition[3])) {
$boolCond = (($matchCondition[3] == "AND") ? ' 1 AND ' : ' 0 OR'); $boolCond = (($matchCondition[3] == "AND") ? ' 1 AND ' : ' 0 OR');
$InfoFieldList[4] = str_replace($matchCondition[0], $boolCond, $InfoFieldList[4]); $InfoFieldList[4] = str_replace($matchCondition[0], $boolCond, $InfoFieldList[4]);
} } else {
else {
$InfoFieldList[4] = 1; $InfoFieldList[4] = 1;
} }
} }
@ -1450,8 +1453,7 @@ class ExtraFields
// Si l'on a un AND ou un OR, avant ou après // Si l'on a un AND ou un OR, avant ou après
preg_match('#(AND|OR|) *(' . $word . ') *(AND|OR|)#', $InfoFieldList[4], $matchCondition); preg_match('#(AND|OR|) *(' . $word . ') *(AND|OR|)#', $InfoFieldList[4], $matchCondition);
} }
} } else {
else {
$InfoFieldList[4] = str_replace('$ID$', '0', $InfoFieldList[4]); $InfoFieldList[4] = str_replace('$ID$', '0', $InfoFieldList[4]);
} }
@ -1466,8 +1468,7 @@ class ExtraFields
$sqlwhere .= ' WHERE 1=1'; $sqlwhere .= ' WHERE 1=1';
} }
// Some tables may have field, some other not. For the moment we disable it. // Some tables may have field, some other not. For the moment we disable it.
if (in_array($InfoFieldList[0], array ('tablewithentity'))) if (in_array($InfoFieldList[0], array('tablewithentity'))) {
{
$sqlwhere .= ' AND entity = ' . $conf->entity; $sqlwhere .= ' AND entity = ' . $conf->entity;
} }
// $sql.=preg_replace('/^ AND /','',$sqlwhere); // $sql.=preg_replace('/^ AND /','',$sqlwhere);
@ -1540,6 +1541,10 @@ class ExtraFields
$out = $form->multiselectarray($keyprefix . $key . $keysuffix, $data, $value_arr, '', 0, '', 0, '100%'); $out = $form->multiselectarray($keyprefix . $key . $keysuffix, $data, $value_arr, '', 0, '', 0, '100%');
} else { } else {
print 'Error in request ' . $sql . ' ' . $this->db->lasterror() . '. Check setup of extra parameters.<br>'; print 'Error in request ' . $sql . ' ' . $this->db->lasterror() . '. Check setup of extra parameters.<br>';
}
} else {
$data = $form->select_all_categories(Categorie::$MAP_ID_TO_CODE[$InfoFieldList[5]], '', 'parent', 64, $InfoFieldList[6], 1, 1);
$out = $form->multiselectarray($keyprefix . $key . $keysuffix, $data, $value_arr, '', 0, '', 0, '100%');
} }
} }
} }

View File

@ -3805,12 +3805,16 @@ class Form
* @param string $selected Id of category preselected or 'auto' (autoselect category if there is only one element) * @param string $selected Id of category preselected or 'auto' (autoselect category if there is only one element)
* @param string $htmlname HTML field name * @param string $htmlname HTML field name
* @param int $maxlength Maximum length for labels * @param int $maxlength Maximum length for labels
* @param int $excludeafterid Exclude all categories after this leaf in category tree. * @param int|string|array $markafterid Keep only or removed all categories including the leaf $markafterid in category tree (exclude) or Keep only of category is inside the leaf starting with this id.
* $markafterid can be an : int (id of category)
* string (categories ids seprated by comma)
* array (list of categories ids)
* @param int $outputmode 0=HTML select string, 1=Array * @param int $outputmode 0=HTML select string, 1=Array
* @param int $include [=0] Removed or 1=Keep only
* @return string * @return string
* @see select_categories() * @see select_categories()
*/ */
public function select_all_categories($type, $selected = '', $htmlname = "parent", $maxlength = 64, $excludeafterid = 0, $outputmode = 0) public function select_all_categories($type, $selected = '', $htmlname = "parent", $maxlength = 64, $markafterid = 0, $outputmode = 0, $include = 0)
{ {
// phpcs:enable // phpcs:enable
global $conf, $langs; global $conf, $langs;
@ -3850,7 +3854,7 @@ class Form
else else
{ {
$cat = new Categorie($this->db); $cat = new Categorie($this->db);
$cate_arbo = $cat->get_full_arbo($type, $excludeafterid); $cate_arbo = $cat->get_full_arbo($type, $markafterid, $include);
} }
$output = '<select class="flat" name="'.$htmlname.'" id="'.$htmlname.'">'; $output = '<select class="flat" name="'.$htmlname.'" id="'.$htmlname.'">';

View File

@ -77,7 +77,7 @@ top_htmlhead($head, $title, $disablejs, $disablehead, $arrayofjs, $arrayofcss);
<script type="text/javascript" src="js/jquery.colorbox-min.js"></script> <!-- TODO It seems we don't need this --> <script type="text/javascript" src="js/jquery.colorbox-min.js"></script> <!-- TODO It seems we don't need this -->
<script language="javascript"> <script language="javascript">
<?php <?php
$categories = $categorie->get_full_arbo('product', 0, (($conf->global->TAKEPOS_ROOT_CATEGORY_ID > 0)?$conf->global->TAKEPOS_ROOT_CATEGORY_ID:0)); $categories = $categorie->get_full_arbo('product', (($conf->global->TAKEPOS_ROOT_CATEGORY_ID > 0)?$conf->global->TAKEPOS_ROOT_CATEGORY_ID:0), 1);
// Search root category to know its level // Search root category to know its level