1<?php
2/* Copyright (C) 2011-2020 Laurent Destailleur  <eldy@users.sourceforge.net>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <https://www.gnu.org/licenses/>.
16 * or see https://www.gnu.org/
17 *
18 * $elementype must be defined.
19 */
20
21/**
22 *	\file			htdocs/core/actions_extrafields.inc.php
23 *  \brief			Code for actions on extrafields admin pages
24 */
25
26$maxsizestring = 255;
27$maxsizeint = 10;
28$mesg = array();
29
30$extrasize = GETPOST('size', 'intcomma');
31$type = GETPOST('type', 'alpha');
32$param = GETPOST('param', 'alpha');
33
34if ($type == 'double' && strpos($extrasize, ',') === false) $extrasize = '24,8';
35if ($type == 'date')     $extrasize = '';
36if ($type == 'datetime') $extrasize = '';
37if ($type == 'select')   $extrasize = '';
38
39
40// Add attribute
41if ($action == 'add')
42{
43	if (GETPOST("button") != $langs->trans("Cancel"))
44	{
45		// Check values
46		if (!$type)
47		{
48			$error++;
49			$langs->load("errors");
50			$mesg[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type"));
51			$action = 'create';
52		}
53		if ($type == 'varchar' && $extrasize <= 0)
54		{
55			$error++;
56			$langs->load("errors");
57			$mesg[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Size"));
58			$action = 'edit';
59		}
60		if ($type == 'varchar' && $extrasize > $maxsizestring)
61		{
62			$error++;
63			$langs->load("errors");
64			$mesg[] = $langs->trans("ErrorSizeTooLongForVarcharType", $maxsizestring);
65			$action = 'create';
66		}
67		if ($type == 'int' && $extrasize > $maxsizeint)
68		{
69			$error++;
70			$langs->load("errors");
71			$mesg[] = $langs->trans("ErrorSizeTooLongForIntType", $maxsizeint);
72			$action = 'create';
73		}
74		if ($type == 'select' && !$param)
75		{
76			$error++;
77			$langs->load("errors");
78			$mesg[] = $langs->trans("ErrorNoValueForSelectType");
79			$action = 'create';
80		}
81		if ($type == 'sellist' && !$param)
82		{
83			$error++;
84			$langs->load("errors");
85			$mesg[] = $langs->trans("ErrorNoValueForSelectListType");
86			$action = 'create';
87		}
88		if ($type == 'checkbox' && !$param)
89		{
90			$error++;
91			$langs->load("errors");
92			$mesg[] = $langs->trans("ErrorNoValueForCheckBoxType");
93			$action = 'create';
94		}
95		if ($type == 'link' && !$param)
96		{
97			$error++;
98			$langs->load("errors");
99			$mesg[] = $langs->trans("ErrorNoValueForLinkType");
100			$action = 'create';
101		}
102		if ($type == 'radio' && !$param)
103		{
104			$error++;
105			$langs->load("errors");
106			$mesg[] = $langs->trans("ErrorNoValueForRadioType");
107			$action = 'create';
108		}
109		if ((($type == 'radio') || ($type == 'checkbox')) && $param)
110		{
111			// Construct array for parameter (value of select list)
112			$parameters = $param;
113			$parameters_array = explode("\r\n", $parameters);
114			foreach ($parameters_array as $param_ligne)
115			{
116				if (!empty($param_ligne)) {
117					if (preg_match_all('/,/', $param_ligne, $matches))
118					{
119						if (count($matches[0]) > 1) {
120							$error++;
121							$langs->load("errors");
122							$mesg[] = $langs->trans("ErrorBadFormatValueList", $param_ligne);
123							$action = 'create';
124						}
125					} else {
126						$error++;
127						$langs->load("errors");
128						$mesg[] = $langs->trans("ErrorBadFormatValueList", $param_ligne);
129						$action = 'create';
130					}
131				}
132			}
133		}
134
135		if (!$error) {
136			if (strlen(GETPOST('attrname', 'aZ09')) < 3) {
137				$error++;
138				$langs->load("errors");
139				$mesg[] = $langs->trans("ErrorValueLength", $langs->transnoentitiesnoconv("AttributeCode"), 3);
140				$action = 'create';
141			}
142		}
143
144		// Check reserved keyword with more than 3 characters
145		if (!$error) {
146			if (in_array(GETPOST('attrname', 'aZ09'), array('and', 'keyword', 'table', 'index', 'integer', 'float', 'double', 'position'))) {
147				$error++;
148				$langs->load("errors");
149				$mesg[] = $langs->trans("ErrorReservedKeyword", GETPOST('attrname', 'aZ09'));
150				$action = 'create';
151			}
152		}
153
154		if (!$error) {
155			// attrname must be alphabetical and lower case only
156			if (GETPOSTISSET("attrname") && preg_match("/^[a-z0-9-_]+$/", GETPOST('attrname', 'aZ09')) && !is_numeric(GETPOST('attrname', 'aZ09'))) {
157				// Construct array for parameter (value of select list)
158				$default_value = GETPOST('default_value', 'alpha');
159				$parameters = $param;
160				$parameters_array = explode("\r\n", $parameters);
161				//In sellist we have only one line and it can have come to do SQL expression
162				if ($type == 'sellist' || $type == 'chkbxlst') {
163					foreach ($parameters_array as $param_ligne)
164					{
165						$params['options'] = array($parameters=>null);
166					}
167				} else {
168					// Else it's separated key/value and coma list
169					foreach ($parameters_array as $param_ligne)
170					{
171						list($key, $value) = explode(',', $param_ligne);
172						$params['options'][$key] = $value;
173					}
174				}
175
176				// Visibility: -1=not visible by default in list, 1=visible, 0=hidden
177				$visibility = GETPOST('list', 'alpha');
178				if ($type == 'separate') $visibility = 3;
179
180				$result = $extrafields->addExtraField(
181					GETPOST('attrname', 'aZ09'),
182					GETPOST('label', 'alpha'),
183					$type,
184					GETPOST('pos', 'int'),
185					$extrasize,
186					$elementtype,
187					(GETPOST('unique', 'alpha') ? 1 : 0),
188					(GETPOST('required', 'alpha') ? 1 : 0),
189					$default_value,
190					$params,
191					(GETPOST('alwayseditable', 'alpha') ? 1 : 0),
192					(GETPOST('perms', 'alpha') ?GETPOST('perms', 'alpha') : ''),
193					$visibility,
194					GETPOST('help', 'alpha'),
195					GETPOST('computed_value', 'alpha'),
196					(GETPOST('entitycurrentorall', 'alpha') ? 0 : ''),
197					GETPOST('langfile', 'alpha'),
198					1,
199					(GETPOST('totalizable', 'alpha') ? 1 : 0),
200					GETPOST('printable', 'alpha')
201				);
202				if ($result > 0)
203				{
204					setEventMessages($langs->trans('SetupSaved'), null, 'mesgs');
205					header("Location: ".$_SERVER["PHP_SELF"]);
206					exit;
207				} else {
208					$error++;
209					$mesg = $extrafields->error;
210					setEventMessages($mesg, null, 'errors');
211				}
212			} else {
213				$error++;
214				$langs->load("errors");
215				$mesg = $langs->trans("ErrorFieldCanNotContainSpecialNorUpperCharacters", $langs->transnoentities("AttributeCode"));
216				setEventMessages($mesg, null, 'errors');
217				$action = 'create';
218			}
219		} else {
220			setEventMessages($mesg, null, 'errors');
221		}
222	}
223}
224
225// Rename field
226if ($action == 'update')
227{
228	if (GETPOST("button") != $langs->trans("Cancel"))
229	{
230		// Check values
231		if (!$type)
232		{
233			$error++;
234			$langs->load("errors");
235			$mesg[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type"));
236			$action = 'edit';
237		}
238		if ($type == 'varchar' && $extrasize <= 0)
239		{
240			$error++;
241			$langs->load("errors");
242			$mesg[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Size"));
243			$action = 'edit';
244		}
245		if ($type == 'varchar' && $extrasize > $maxsizestring)
246		{
247			$error++;
248			$langs->load("errors");
249			$mesg[] = $langs->trans("ErrorSizeTooLongForVarcharType", $maxsizestring);
250			$action = 'edit';
251		}
252		if ($type == 'int' && $extrasize > $maxsizeint)
253		{
254			$error++;
255			$langs->load("errors");
256			$mesg[] = $langs->trans("ErrorSizeTooLongForIntType", $maxsizeint);
257			$action = 'edit';
258		}
259		if ($type == 'select' && !$param)
260		{
261			$error++;
262			$langs->load("errors");
263			$mesg[] = $langs->trans("ErrorNoValueForSelectType");
264			$action = 'edit';
265		}
266		if ($type == 'sellist' && !$param)
267		{
268			$error++;
269			$langs->load("errors");
270			$mesg[] = $langs->trans("ErrorNoValueForSelectListType");
271			$action = 'edit';
272		}
273		if ($type == 'checkbox' && !$param)
274		{
275			$error++;
276			$langs->load("errors");
277			$mesg[] = $langs->trans("ErrorNoValueForCheckBoxType");
278			$action = 'edit';
279		}
280		if ($type == 'radio' && !$param)
281		{
282			$error++;
283			$langs->load("errors");
284			$mesg[] = $langs->trans("ErrorNoValueForRadioType");
285			$action = 'edit';
286		}
287		if ((($type == 'radio') || ($type == 'checkbox')) && $param)
288		{
289			// Construct array for parameter (value of select list)
290			$parameters = $param;
291			$parameters_array = explode("\r\n", $parameters);
292			foreach ($parameters_array as $param_ligne)
293			{
294				if (!empty($param_ligne)) {
295					if (preg_match_all('/,/', $param_ligne, $matches))
296					{
297						if (count($matches[0]) > 1) {
298							$error++;
299							$langs->load("errors");
300							$mesg[] = $langs->trans("ErrorBadFormatValueList", $param_ligne);
301							$action = 'edit';
302						}
303					} else {
304						$error++;
305						$langs->load("errors");
306						$mesg[] = $langs->trans("ErrorBadFormatValueList", $param_ligne);
307						$action = 'edit';
308					}
309				}
310			}
311		}
312
313		if (!$error) {
314			if (strlen(GETPOST('attrname', 'aZ09')) < 3 && empty($conf->global->MAIN_DISABLE_EXTRAFIELDS_CHECK_FOR_UPDATE)) {
315				$error++;
316				$langs->load("errors");
317				$mesg[] = $langs->trans("ErrorValueLength", $langs->transnoentitiesnoconv("AttributeCode"), 3);
318				$action = 'edit';
319			}
320		}
321
322		// Check reserved keyword with more than 3 characters
323		if (!$error) {
324			if (in_array(GETPOST('attrname', 'aZ09'), array('and', 'keyword', 'table', 'index', 'integer', 'float', 'double', 'position')) && empty($conf->global->MAIN_DISABLE_EXTRAFIELDS_CHECK_FOR_UPDATE)) {
325				$error++;
326				$langs->load("errors");
327				$mesg[] = $langs->trans("ErrorReservedKeyword", GETPOST('attrname', 'aZ09'));
328				$action = 'edit';
329			}
330		}
331
332		if (!$error)
333		{
334			if (GETPOSTISSET("attrname") && preg_match("/^\w[a-zA-Z0-9-_]*$/", GETPOST('attrname', 'aZ09')) && !is_numeric(GETPOST('attrname', 'aZ09')))
335			{
336				$pos = GETPOST('pos', 'int');
337				// Construct array for parameter (value of select list)
338				$parameters = $param;
339				$parameters_array = explode("\r\n", $parameters);
340				//In sellist we have only one line and it can have come to do SQL expression
341				if ($type == 'sellist' || $type == 'chkbxlst') {
342					foreach ($parameters_array as $param_ligne)
343					{
344						$params['options'] = array($parameters=>null);
345					}
346				} else {
347					//Esle it's separated key/value and coma list
348					foreach ($parameters_array as $param_ligne)
349					{
350						list($key, $value) = explode(',', $param_ligne);
351						$params['options'][$key] = $value;
352					}
353				}
354
355				// Visibility: -1=not visible by default in list, 1=visible, 0=hidden
356				$visibility = GETPOST('list', 'alpha');
357				if ($type == 'separate') $visibility = 3;
358
359				// Example: is_object($object) ? ($object->id < 10 ? round($object->id / 2, 2) : (2 * $user->id) * (int) substr($mysoc->zip, 1, 2)) : 'objnotdefined'
360				$computedvalue = GETPOST('computed_value', 'nohtml');
361
362				$result = $extrafields->update(
363					GETPOST('attrname', 'aZ09'),
364					GETPOST('label', 'alpha'),
365					$type,
366					$extrasize,
367					$elementtype,
368					(GETPOST('unique', 'alpha') ? 1 : 0),
369					(GETPOST('required', 'alpha') ? 1 : 0),
370					$pos,
371					$params,
372					(GETPOST('alwayseditable', 'alpha') ? 1 : 0),
373					(GETPOST('perms', 'alpha') ?GETPOST('perms', 'alpha') : ''),
374					$visibility,
375					GETPOST('help', 'alpha'),
376					GETPOST('default_value', 'alpha'),
377					$computedvalue,
378					(GETPOST('entitycurrentorall', 'alpha') ? 0 : ''),
379					GETPOST('langfile'),
380					GETPOST('enabled', 'alpha'),
381					(GETPOST('totalizable', 'alpha') ? 1 : 0),
382					GETPOST('printable', 'alpha')
383				);
384				if ($result > 0) {
385					setEventMessages($langs->trans('SetupSaved'), null, 'mesgs');
386					header("Location: ".$_SERVER["PHP_SELF"]);
387					exit;
388				} else {
389					$error++;
390					$mesg = $extrafields->error;
391					setEventMessages($mesg, null, 'errors');
392				}
393			} else {
394				$error++;
395				$langs->load("errors");
396				$mesg = $langs->trans("ErrorFieldCanNotContainSpecialCharacters", $langs->transnoentities("AttributeCode"));
397				setEventMessages($mesg, null, 'errors');
398			}
399		} else {
400			setEventMessages($mesg, null, 'errors');
401		}
402	}
403}
404
405// Delete attribute
406if ($action == 'delete') {
407	if (GETPOSTISSET("attrname") && preg_match("/^\w[a-zA-Z0-9-_]*$/", GETPOST("attrname", 'aZ09'))) {
408		$result = $extrafields->delete(GETPOST("attrname", 'aZ09'), $elementtype);
409		if ($result >= 0) {
410			header("Location: ".$_SERVER["PHP_SELF"]);
411			exit;
412		} else $mesg = $extrafields->error;
413	} else {
414		$error++;
415		$langs->load("errors");
416		$mesg = $langs->trans("ErrorFieldCanNotContainSpecialCharacters", $langs->transnoentities("AttributeCode"));
417	}
418}
419