76 $options = is_array($options) ? $options : array();
77 $paramList = array_keys($options);
78 $paramList = preg_split(
'/[\r\n]+/', $paramList[0]);
90 $all = (
string) $paramList[0];
91 $InfoFieldList = explode(
":", $all, 5);
94 if (!empty($InfoFieldList[4])) {
97 while (substr($InfoFieldList[4], $pos, 1) !==
'' && ($parenthesisopen || $pos == 0 || substr($InfoFieldList[4], $pos, 1) !=
':')) {
98 if (substr($InfoFieldList[4], $pos, 1) ==
'(') {
101 if (substr($InfoFieldList[4], $pos, 1) ==
')') {
106 $tmpbefore = substr($InfoFieldList[4], 0, $pos);
107 $tmpafter = substr($InfoFieldList[4], $pos + 1);
108 $InfoFieldList[4] = $tmpbefore;
109 if ($tmpafter !==
'') {
110 $InfoFieldList = array_merge($InfoFieldList, explode(
':', $tmpafter));
115 if (preg_match(
'/^\(?([a-z0-9]+)([=<>]+)(\d+)\)?$/i', $InfoFieldList[4], $reg)) {
116 $InfoFieldList[4] =
'(' . $reg[1] .
':' . $reg[2] .
':' . $reg[3] .
')';
120 $tableName = (
string) ($InfoFieldList[0] ??
'');
121 $labelFullFields = (
string) ($InfoFieldList[1] ??
'');
123 $labelFullFields = array_filter(array_map(
'trim', explode(
'|', $labelFullFields)),
'strlen');
124 $labelFields = array();
125 $labelAlias = array();
126 foreach ($labelFullFields as $labelFullField) {
128 $labelFields[] = $tmp[
'field'];
129 $labelAlias[] = $tmp[
'alias'];
131 $keyField = (
string) ($InfoFieldList[2] ??
'');
132 if (empty($keyField)) {
135 $keyFieldParent = (
string) ($InfoFieldList[3] ??
'');
136 $tmp = array_map(
'trim', explode(
'|', $keyFieldParent));
137 $parentName = (
string) ($tmp[0] ??
'');
138 $parentFullField = (
string) ($tmp[1] ??
'');
140 $parentField = $tmp[
'field'];
141 $parentAlias = $tmp[
'alias'];
142 $filter = (
string) ($InfoFieldList[4] ??
'');
143 $categoryType = (
string) ($InfoFieldList[5] ??
'');
144 if (is_numeric($categoryType)) {
145 require_once DOL_DOCUMENT_ROOT .
'/categories/class/categorie.class.php';
146 $categoryType = self::MAP_ID_TO_CODE[(int) $categoryType] ??
'';
148 $categoryRoots = (
string) ($InfoFieldList[6] ??
'');
149 $sortField = (
string) ($InfoFieldList[7] ??
'');
153 'tableName' => $tableName,
154 'labelFullFields' => $labelFullFields,
155 'labelFields' => $labelFields,
156 'labelAlias' => $labelAlias,
157 'keyField' => $keyField,
158 'parentName' => $parentName,
159 'parentFullField' => $parentFullField,
160 'parentField' => $parentField,
161 'parentAlias' => $parentAlias,
163 'categoryType' => $categoryType,
164 'categoryRoots' => $categoryRoots,
165 'sortField' => $sortField,
205 public function getOptions($fieldInfos, $key, $addEmptyValue =
false, $reload =
false, $selectedValues = array())
207 global
$conf, $langs;
209 $selectedValues = array_map(
'trim', is_array($selectedValues) ? $selectedValues : array($selectedValues));
211 if (!isset(self::$options[$key]) || $reload) {
213 if (!empty($fieldInfos->options) && is_array($fieldInfos->options)) {
216 if ($optionsParams[
'tableName'] ==
'categorie' && !empty($optionsParams[
'categoryType'])) {
217 $data = self::$form->select_all_categories($optionsParams[
'categoryType'],
'',
'parent', 64, $optionsParams[
'categoryRoots'], 1, 1);
218 if (is_array($data)) {
219 foreach ($data as $data_key => $data_value) {
220 $options[$data_key] = array(
221 'label' => $data_value,
227 $filter = $optionsParams[
'filter'];
228 $hasExtra = !empty($filter) && strpos($filter,
'extra.') !==
false;
229 $keyField = ($hasExtra ?
'main.' :
'') . $optionsParams[
'keyField'];
231 $keyList = $keyField .
' AS rowid';
232 if (!empty($optionsParams[
'parentFullField'])) {
233 $keyList .=
', ' . $optionsParams[
'parentFullField'];
235 if (!empty($optionsParams[
'labelFullFields'])) {
236 $keyList .=
', ' . implode(
', ', $optionsParams[
'labelFullFields']);
239 $sql =
"SELECT " . $this->db->sanitize($keyList, 0, 0, 1);
240 $sql .=
" FROM " . $this->db->sanitize($this->db->prefix() . $optionsParams[
'tableName']);
243 $sql .=
" LEFT JOIN " . $this->db->sanitize($this->db->prefix() . $optionsParams[
'tableName']) .
"_extrafields AS extra ON extra.fk_object = " . $keyField;
247 if (!empty($filter)) {
249 if (strpos($filter,
'$ENTITY$') !==
false) {
250 $filter = str_replace(
'$ENTITY$', (
string)
$conf->entity, $filter);
253 global $dolibarr_allow_unsecured_select_in_extrafields_filter;
254 if (strpos($filter,
'$SEL$') !==
false && !empty($dolibarr_allow_unsecured_select_in_extrafields_filter)) {
255 $filter = str_replace(
'$SEL$',
'SELECT', $filter);
258 if (strpos($filter,
'$MODE$') !==
false) {
259 $filter = str_replace(
'$MODE$', empty($fieldInfos->mode) ?
'view' : $fieldInfos->mode, $filter);
263 $objectid = isset($fieldInfos->otherParams[
'objectId']) ? (int) $fieldInfos->otherParams[
'objectId'] : (isset($fieldInfos->object) && is_object($fieldInfos->object) ? (int) $fieldInfos->object->id : 0);
264 if (strpos($filter,
'$ID$') !==
false && !empty($objectid)) {
265 $filter = str_replace(
'$ID$', (
string) $objectid, $filter);
266 } elseif (substr($_SERVER[
"PHP_SELF"], -8) ==
'list.php') {
270 $filter = preg_replace(
'#\b([a-zA-Z0-9-\.-_]+)\b *= *\$ID\$#',
'$1', $filter);
272 $filter = preg_replace(
'#\$ID\$ *= *\b([a-zA-Z0-9-\.-_]+)\b#',
'$1', $filter);
274 $filter = str_replace(
'$ID$',
'0', $filter);
278 if (isset($fieldInfos->object) && is_object($fieldInfos->object)) {
281 preg_match_all(
'/\$(.*?)\$/', $filter, $tags);
282 foreach ($tags[0] as $keytag => $valuetag) {
283 $property = preg_replace(
'/[^a-z0-9_]/',
'', strtolower($tags[1][$keytag]));
284 if (strpos($filter, $valuetag) !==
false && property_exists(
$object, $property) && !empty(
$object->$property)) {
285 $filter = str_replace($valuetag, (
string)
$object->$property, $filter);
287 $filter = str_replace($valuetag,
'0', $filter);
293 $sql .=
" WHERE " . forgeSQLFromUniversalSearchCriteria($filter, $errstr, 1);
295 $sql .=
' WHERE 1=1';
298 if (in_array($optionsParams[
'tableName'], array(
'tablewithentity'))) {
299 $sql .=
" AND entity = " . ((int)
$conf->entity);
302 if (isset($fieldInfos->optionsSqlDependencyValue)) {
304 $sql .=
" AND " . $this->db->sanitize($optionsParams[
'parentField']) .
" = '" . $this->db->escape($fieldInfos->optionsSqlDependencyValue) .
"'";
307 if (!empty($selectedValues)) {
308 $sanitizedSqlIn =
"'" . implode(
"','", array_map(array($this->db,
'escape'), $selectedValues)) .
"'";
309 $sql .=
" AND " . $this->db->sanitize($keyField) .
" IN (" . $sanitizedSqlIn .
")";
313 if (preg_match(
'/^[a-z0-9_\-,]+$/i', $optionsParams[
'sortField'])) {
314 $sql .= $this->db->order($optionsParams[
'sortField']);
316 $sql .= $this->db->order(implode(
', ', $optionsParams[
'labelFields']));
319 $limit =
getDolGlobalInt(
'MAIN_EXTRAFIELDS_LIMIT_SELLIST_SQL', $fieldInfos->optionsSqlLimit ?? 1000);
320 $offset = $fieldInfos->optionsSqlOffset ?? (isset($fieldInfos->optionsSqlPage) ? (((int) $fieldInfos->optionsSqlPage) - 1) * $limit : 0);
321 $sql .= $this->db->plimit($limit, $offset);
323 dol_syslog(get_class($this) .
'::getOptions', LOG_DEBUG);
324 $resql = $this->db->query($sql);
326 while ($obj = $this->db->fetch_object($resql)) {
327 $optionKey = (
string) $obj->rowid;
330 foreach ($optionsParams[
'labelAlias'] as $fieldToShow) {
331 $toPrint[] = is_string($obj->$fieldToShow) ? $langs->trans($obj->$fieldToShow) : $obj->$fieldToShow;
333 $optionLabel = implode(
' ', $toPrint);
335 if (empty($optionLabel)) {
336 $optionLabel =
'(not defined)';
340 $fieldValueParent = !empty($optionsParams[
'parentName']) && !empty($optionsParams[
'parentAlias']) ? $optionsParams[
'parentName'] .
':' . ((
string) $obj->{$optionsParams[
'parentAlias']}) :
'';
342 $options[$optionKey] = array(
344 'label' => $optionLabel,
345 'parent' => $fieldValueParent,
348 $this->db->free($resql);
350 $this->error =
'Error in request ' . $sql .
' ' . $this->db->lasterror() .
'. Check setup of extra parameters.<br>';
355 if ($addEmptyValue && (!$fieldInfos->required || count($options) > 1)) {
366 self::$options[$key] = $options;
369 $options = self::$options[$key];
371 if (!empty($selectedValues)) {
372 $options = array_intersect_key($options, array_flip($selectedValues));