Issues (1098)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

src/dbo/fields.php (13 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
//------------------------------------------------------------------------------
4
//
5
//  eTraxis - Records tracking web-based system
6
//  Copyright (C) 2005-2011  Artem Rodygin
7
//
8
//  This program is free software: you can redistribute it and/or modify
9
//  it under the terms of the GNU General Public License as published by
10
//  the Free Software Foundation, either version 3 of the License, or
11
//  (at your option) any later version.
12
//
13
//  This program is distributed in the hope that it will be useful,
14
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
15
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
//  GNU General Public License for more details.
17
//
18
//  You should have received a copy of the GNU General Public License
19
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
//
21
//------------------------------------------------------------------------------
22
23
/**
24
 * Fields
25
 *
26
 * This module provides API to work with eTraxis fields.
27
 * See also {@link https://github.com/etraxis/etraxis-obsolete/wiki/tbl_fields tbl_fields} database table.
28
 *
29
 * @package DBO
30
 * @subpackage Fields
31
 */
32
33
/**#@+
34
 * Dependency.
35
 */
36
require_once('../engine/engine.php');
37
require_once('../dbo/values.php');
38
/**#@-*/
39
40
//------------------------------------------------------------------------------
41
//  Definitions.
42
//------------------------------------------------------------------------------
43
44
/**#@+
45
 * Data restriction.
46
 */
47
define('MAX_FIELD_NAME',        50);
48
define('MAX_FIELD_INTEGER',     1000000000);
49
define('MIN_FIELD_FLOAT',       '-9999999999.9999999999');
50
define('MAX_FIELD_FLOAT',       '+9999999999.9999999999');
51
define('MAX_FIELD_STRING',      250);
52
define('MAX_FIELD_MULTILINED',  4000);
53
define('MAX_FIELD_LIST_ITEMS',  1000);
54
define('MAX_LISTITEM_NAME',     50);
55
define('MIN_FIELD_DATE',        ~MAXINT);
56
define('MAX_FIELD_DATE',        MAXINT);
57
define('MIN_FIELD_DURATION',    0);
58
define('MAX_FIELD_DURATION',    59999999);
59
define('MAX_FIELD_DESCRIPTION', 1000);
60
define('MAX_FIELD_REGEX',       500);
61
/**#@-*/
62
63
/**
64
 * Unix Epoch of 1977-12-29.
65
 * Needed to evaluate maximum length of string with date, formatted in current user's locale.
66
 */
67
define('SAMPLE_DATE', mktime(0,0,0,12,29,1977));
68
69
/**#@+
70
 * Field type.
71
 */
72
define('FIELD_TYPE_MINIMUM',    1);
73
define('FIELD_TYPE_NUMBER',     1);
74
define('FIELD_TYPE_STRING',     2);
75
define('FIELD_TYPE_MULTILINED', 3);
76
define('FIELD_TYPE_CHECKBOX',   4);
77
define('FIELD_TYPE_LIST',       5);
78
define('FIELD_TYPE_RECORD',     6);
79
define('FIELD_TYPE_DATE',       7);
80
define('FIELD_TYPE_DURATION',   8);
81
define('FIELD_TYPE_FLOAT',      9);
82
define('FIELD_TYPE_MAXIMUM',    9);
83
/**#@-*/
84
85
/**#@+
86
 * Field permission.
87
 */
88
define('FIELD_RESTRICTED',     0);  // no permissions
89
define('FIELD_ALLOW_TO_READ',  1);  // read-only permissions
90
define('FIELD_ALLOW_TO_WRITE', 2);  // read and write permissions
91
/**#@-*/
92
93
/**#@+
94
 * Field role.
95
 */
96
define('FIELD_ROLE_AUTHOR',      -1);
97
define('FIELD_ROLE_RESPONSIBLE', -2);
98
define('FIELD_ROLE_REGISTERED',  -3);
99
define('MIN_FIELD_ROLE', FIELD_ROLE_REGISTERED);
100
/**#@-*/
101
102
// Field type resources.
103
$field_type_res = array
104
(
105
    FIELD_TYPE_NUMBER     => RES_NUMBER_ID,
106
    FIELD_TYPE_FLOAT      => RES_DECIMAL_ID,
107
    FIELD_TYPE_STRING     => RES_STRING_ID,
108
    FIELD_TYPE_MULTILINED => RES_MULTILINED_TEXT_ID,
109
    FIELD_TYPE_CHECKBOX   => RES_CHECKBOX_ID,
110
    FIELD_TYPE_LIST       => RES_LIST_ID,
111
    FIELD_TYPE_RECORD     => RES_RECORD_ID,
112
    FIELD_TYPE_DATE       => RES_DATE_ID,
113
    FIELD_TYPE_DURATION   => RES_DURATION_ID,
114
);
115
116
//------------------------------------------------------------------------------
117
//  Functions.
118
//------------------------------------------------------------------------------
119
120
/**
121
 * Finds in database and returns the information about specified field.
122
 *
123
 * @param int $id Field ID.
124
 * @return array Array with data if field is found in database, FALSE otherwise.
125
 */
126
function field_find ($id)
127
{
128
    debug_write_log(DEBUG_TRACE, '[field_find]');
129
    debug_write_log(DEBUG_DUMP,  '[field_find] $id = ' . $id);
130
131
    $rs = dal_query('fields/fndid.sql', $id);
132
133
    return ($rs->rows == 0 ? FALSE : $rs->fetch());
0 ignored issues
show
The property $rows is declared protected in CRecordset. Since you implemented __get(), maybe consider adding a @property or @property-read annotation. This makes it easier for IDEs to provide auto-completion.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
134
}
135
136
/**
137
 * Returns {@link CRecordset DAL recordset} which contains all existing fields of specified state,
138
 * sorted in accordance with current sort mode.
139
 *
140
 * @param int $id State ID.
141
 * @param int &$sort Sort mode (used as output only). The function retrieves current sort mode from
142
 * client cookie ({@link COOKIE_FIELDS_SORT}) and updates it, if it's out of valid range.
143
 * @param int &$page Number of current page tab (used as output only). The function retrieves current
144
 * page from client cookie ({@link COOKIE_FIELDS_PAGE}) and updates it, if it's out of valid range.
145
 * @return CRecordset Recordset with list of fields.
146
 */
147 View Code Duplication
function fields_list ($id, &$sort, &$page)
148
{
149
    debug_write_log(DEBUG_TRACE, '[fields_list]');
150
    debug_write_log(DEBUG_DUMP,  '[fields_list] $id = ' . $id);
151
152
    $sort_modes = array
153
    (
154
        1  => 'field_order asc',
155
        2  => 'field_name asc',
156
        3  => 'field_type asc, field_name asc',
157
        4  => 'is_required asc, field_name asc',
158
        5  => 'guest_access asc, field_name asc',
159
        6  => 'field_order desc',
160
        7  => 'field_name desc',
161
        8  => 'field_type desc, field_name desc',
162
        9  => 'is_required desc, field_name desc',
163
        10 => 'guest_access desc, field_name desc',
164
    );
165
166
    $sort = try_request('sort', try_cookie(COOKIE_FIELDS_SORT, 1));
167
    $sort = ustr2int($sort, 1, count($sort_modes));
168
169
    $page = try_request('page', try_cookie(COOKIE_FIELDS_PAGE));
170
    $page = ustr2int($page, 1, MAXINT);
171
172
    save_cookie(COOKIE_FIELDS_SORT, $sort);
173
    save_cookie(COOKIE_FIELDS_PAGE, $page);
174
175
    return dal_query('fields/list.sql', $id, $sort_modes[$sort]);
176
}
177
178
/**
179
 * Returns number of fields for specified state.
180
 *
181
 * @param int $id State ID.
182
 * @return int Current number of fields.
183
 */
184
function field_count ($id)
185
{
186
    debug_write_log(DEBUG_TRACE, '[field_count]');
187
    debug_write_log(DEBUG_DUMP,  '[field_count] $id = ' . $id);
188
189
    $rs = dal_query('fields/count.sql', $id);
190
191
    return ($rs->rows == 0 ? 0 : $rs->fetch(0));
0 ignored issues
show
The property $rows is declared protected in CRecordset. Since you implemented __get(), maybe consider adding a @property or @property-read annotation. This makes it easier for IDEs to provide auto-completion.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
192
}
193
194
/**
195
 * Returns list of all local and global groups which have specified permission for specified field.
196
 *
197
 * @param int $pid Project ID.
198
 * @param int $fid Field ID.
199
 * @param int $perms Permission:
200
 * <ul>
201
 * <li>{@link FIELD_ALLOW_TO_READ}</li>
202
 * <li>{@link FIELD_ALLOW_TO_WRITE}</li>
203
 * </ul>
204
 * @return CRecordset Recordset with list of groups.
205
 */
206
function field_amongs ($pid, $fid, $perms)
207
{
208
    debug_write_log(DEBUG_TRACE, '[field_amongs]');
209
    debug_write_log(DEBUG_DUMP,  '[field_amongs] $pid   = ' . $pid);
210
    debug_write_log(DEBUG_DUMP,  '[field_amongs] $fid   = ' . $fid);
211
    debug_write_log(DEBUG_DUMP,  '[field_amongs] $perms = ' . $perms);
212
213
    return dal_query('fields/fpamongs.sql', $pid, $fid, $perms);
214
}
215
216
/**
217
 * Returns list of all local and global groups which don't have specified permission for specified field.
218
 *
219
 * @param int $pid Project ID.
220
 * @param int $fid Field ID.
221
 * @param int $perms Permission:
222
 * <ul>
223
 * <li>{@link FIELD_ALLOW_TO_READ}</li>
224
 * <li>{@link FIELD_ALLOW_TO_WRITE}</li>
225
 * </ul>
226
 * @return CRecordset Recordset with list of groups.
227
 */
228
function field_others ($pid, $fid, $perms)
229
{
230
    debug_write_log(DEBUG_TRACE, '[field_others]');
231
    debug_write_log(DEBUG_DUMP,  '[field_others] $pid   = ' . $pid);
232
    debug_write_log(DEBUG_DUMP,  '[field_others] $fid   = ' . $fid);
233
    debug_write_log(DEBUG_DUMP,  '[field_others] $perms = ' . $perms);
234
235
    return dal_query('fields/fpothers.sql', $pid, $fid, $perms);
236
}
237
238
/**
239
 * Validates general field information before creation or modification.
240
 *
241
 * @param string $field_name Field name.
242
 * @return int Error code:
243
 * <ul>
244
 * <li>{@link NO_ERROR} - data are valid</li>
245
 * <li>{@link ERROR_INCOMPLETE_FORM} - at least one of required field is empty</li>
246
 * </ul>
247
 */
248 View Code Duplication
function field_validate ($field_name)
249
{
250
    debug_write_log(DEBUG_TRACE, '[field_validate]');
251
    debug_write_log(DEBUG_DUMP,  '[field_validate] $field_name = ' . $field_name);
252
253
    if (ustrlen($field_name) == 0)
254
    {
255
        debug_write_log(DEBUG_NOTICE, '[field_validate] At least one required field is empty.');
256
        return ERROR_INCOMPLETE_FORM;
257
    }
258
259
    return NO_ERROR;
260
}
261
262
/**
263
 * Validates 'Number' field information before creation or modification.
264
 *
265
 * @param string $field_name Field name.
266
 * @param int $min_value Minimum allowed value of the field.
267
 * @param int $max_value Maximum allowed value of the field.
268
 * @param int $def_value Default allowed value of the field (NULL by default).
269
 * @return int Error code:
270
 * <ul>
271
 * <li>{@link NO_ERROR} - data are valid</li>
272
 * <li>{@link ERROR_INCOMPLETE_FORM} - at least one of required field is empty</li>
273
 * <li>{@link ERROR_INVALID_INTEGER_VALUE} - at least one of specified integer values is invalid</li>
274
 * <li>{@link ERROR_INTEGER_VALUE_OUT_OF_RANGE} - at least one of specified integer values is less than -{@link MAX_FIELD_INTEGER}, or greater than {@link MAX_FIELD_INTEGER}</li>
275
 * <li>{@link ERROR_MIN_MAX_VALUES} - maximum value is less than minimum one</li>
276
 * <li>{@link ERROR_DEFAULT_VALUE_OUT_OF_RANGE} - default value is less than $min_value, or greater than $max_value</li>
277
 * </ul>
278
 */
279
function field_validate_number ($field_name, $min_value, $max_value, $def_value = NULL)
280
{
281
    debug_write_log(DEBUG_TRACE, '[field_validate_number]');
282
    debug_write_log(DEBUG_DUMP,  '[field_validate_number] $field_name = ' . $field_name);
283
    debug_write_log(DEBUG_DUMP,  '[field_validate_number] $min_value  = ' . $min_value);
284
    debug_write_log(DEBUG_DUMP,  '[field_validate_number] $max_value  = ' . $max_value);
285
    debug_write_log(DEBUG_DUMP,  '[field_validate_number] $def_value  = ' . $def_value);
286
287
    // Check that field name is not empty.
288
    if (ustrlen($field_name) == 0)
289
    {
290
        debug_write_log(DEBUG_NOTICE, '[field_validate_number] At least one required field is empty.');
291
        return ERROR_INCOMPLETE_FORM;
292
    }
293
294
    // Check that specified values are integer.
295 View Code Duplication
    if (!is_intvalue($min_value) ||
296
        !is_intvalue($max_value) ||
297
        (!is_null($def_value) && !is_intvalue($def_value)))
298
    {
299
        debug_write_log(DEBUG_NOTICE, '[field_validate_number] Invalid integer value.');
300
        return ERROR_INVALID_INTEGER_VALUE;
301
    }
302
303
    // Check that specified values are in the range of valid values.
304
    if ($min_value < -MAX_FIELD_INTEGER || $min_value > MAX_FIELD_INTEGER ||
305
        $max_value < -MAX_FIELD_INTEGER || $max_value > MAX_FIELD_INTEGER)
306
    {
307
        debug_write_log(DEBUG_NOTICE, '[field_validate_number] Integer value is out of range.');
308
        return ERROR_INTEGER_VALUE_OUT_OF_RANGE;
309
    }
310
311
    // Check that minimum value is less than maximum one.
312
    if ($min_value > $max_value)
313
    {
314
        debug_write_log(DEBUG_NOTICE, '[field_validate_number] Minimum value is greater then maximum one.');
315
        return ERROR_MIN_MAX_VALUES;
316
    }
317
318
    // Check that default value is in the range between minimum and maximum ones.
319 View Code Duplication
    if (!is_null($def_value) &&
320
        ($def_value < $min_value || $def_value > $max_value))
321
    {
322
        debug_write_log(DEBUG_NOTICE, '[field_validate_number] Default value is out of range.');
323
        return ERROR_DEFAULT_VALUE_OUT_OF_RANGE;
324
    }
325
326
    return NO_ERROR;
327
}
328
329
/**
330
 * Validates 'Decimal' field information before creation or modification.
331
 *
332
 * @param string $field_name Field name.
333
 * @param string $min_value Minimum allowed value of the field.
334
 * @param string $max_value Maximum allowed value of the field.
335
 * @param string $def_value Default allowed value of the field (NULL by default).
336
 * @return int Error code:
337
 * <ul>
338
 * <li>{@link NO_ERROR} - data are valid</li>
339
 * <li>{@link ERROR_INCOMPLETE_FORM} - at least one of required field is empty</li>
340
 * <li>{@link ERROR_INVALID_FLOAT_VALUE} - at least one of specified float values is invalid</li>
341
 * <li>{@link ERROR_FLOAT_VALUE_OUT_OF_RANGE} - at least one of specified float values is out of allowed range</li>
342
 * <li>{@link ERROR_MIN_MAX_VALUES} - maximum value is less than minimum one</li>
343
 * <li>{@link ERROR_DEFAULT_VALUE_OUT_OF_RANGE} - default value is less than $min_value, or greater than $max_value</li>
344
 * </ul>
345
 */
346
function field_validate_float ($field_name, $min_value, $max_value, $def_value = NULL)
347
{
348
    debug_write_log(DEBUG_TRACE, '[field_validate_float]');
349
    debug_write_log(DEBUG_DUMP,  '[field_validate_float] $field_name = ' . $field_name);
350
    debug_write_log(DEBUG_DUMP,  '[field_validate_float] $min_value  = ' . $min_value);
351
    debug_write_log(DEBUG_DUMP,  '[field_validate_float] $max_value  = ' . $max_value);
352
    debug_write_log(DEBUG_DUMP,  '[field_validate_float] $def_value  = ' . $def_value);
353
354
    // Check that field name is not empty.
355
    if (ustrlen($field_name) == 0)
356
    {
357
        debug_write_log(DEBUG_NOTICE, '[field_validate_float] At least one required field is empty.');
358
        return ERROR_INCOMPLETE_FORM;
359
    }
360
361
    // Check that specified values are float.
362 View Code Duplication
    if (!is_floatvalue($min_value) ||
363
        !is_floatvalue($max_value) ||
364
        (!is_null($def_value) && !is_floatvalue($def_value)))
365
    {
366
        debug_write_log(DEBUG_NOTICE, '[field_validate_float] Invalid float value.');
367
        return ERROR_INVALID_FLOAT_VALUE;
368
    }
369
370
    // Check that specified values are in the range of valid values.
371
    if (bccomp($min_value, MIN_FIELD_FLOAT) < 0 || bccomp($min_value, MAX_FIELD_FLOAT) > 0 ||
372
        bccomp($max_value, MIN_FIELD_FLOAT) < 0 || bccomp($max_value, MAX_FIELD_FLOAT) > 0)
373
    {
374
        debug_write_log(DEBUG_NOTICE, '[field_validate_float] Float value is out of range.');
375
        return ERROR_FLOAT_VALUE_OUT_OF_RANGE;
376
    }
377
378
    // Check that minimum value is less than maximum one.
379
    if (bccomp($min_value, $max_value) > 0)
380
    {
381
        debug_write_log(DEBUG_NOTICE, '[field_validate_float] Minimum value is greater then maximum one.');
382
        return ERROR_MIN_MAX_VALUES;
383
    }
384
385
    // Check that default value is in the range between minimum and maximum ones.
386
    if (!is_null($def_value) &&
387
        (bccomp($def_value, $min_value) < 0 || bccomp($def_value, $max_value) > 0))
388
    {
389
        debug_write_log(DEBUG_NOTICE, '[field_validate_float] Default value is out of range.');
390
        return ERROR_DEFAULT_VALUE_OUT_OF_RANGE;
391
    }
392
393
    return NO_ERROR;
394
}
395
396
/**
397
 * Validates 'String' field information before creation or modification.
398
 *
399
 * @param string $field_name Field name.
400
 * @param int $max_length Maximum allowed length of string value in this field.
401
 * @return int Error code:
402
 * <ul>
403
 * <li>{@link NO_ERROR} - data are valid</li>
404
 * <li>{@link ERROR_INCOMPLETE_FORM} - at least one of required field is empty</li>
405
 * <li>{@link ERROR_INVALID_INTEGER_VALUE} - specified maximum length is invalid</li>
406
 * <li>{@link ERROR_INTEGER_VALUE_OUT_OF_RANGE} - specified maximum length is greater than {@link MAX_FIELD_STRING}</li>
407
 * </ul>
408
 */
409 View Code Duplication
function field_validate_string ($field_name, $max_length)
410
{
411
    debug_write_log(DEBUG_TRACE, '[field_validate_string]');
412
    debug_write_log(DEBUG_DUMP,  '[field_validate_string] $field_name = ' . $field_name);
413
    debug_write_log(DEBUG_DUMP,  '[field_validate_string] $max_length = ' . $max_length);
414
415
    // Check that field name is not empty.
416
    if (ustrlen($field_name) == 0)
417
    {
418
        debug_write_log(DEBUG_NOTICE, '[field_validate_string] At least one required field is empty.');
419
        return ERROR_INCOMPLETE_FORM;
420
    }
421
422
    // Check that specified values are integer.
423
    if (!is_intvalue($max_length))
424
    {
425
        debug_write_log(DEBUG_NOTICE, '[field_validate_string] Invalid integer value.');
426
        return ERROR_INVALID_INTEGER_VALUE;
427
    }
428
429
    // Check that specified values are in the range of valid values.
430
    if ($max_length < 1 || $max_length > MAX_FIELD_STRING)
431
    {
432
        debug_write_log(DEBUG_NOTICE, '[field_validate_string] Integer value is out of range.');
433
        return ERROR_INTEGER_VALUE_OUT_OF_RANGE;
434
    }
435
436
    return NO_ERROR;
437
}
438
439
/**
440
 * Validates 'Multilined text' field information before creation or modification.
441
 *
442
 * @param string $field_name Field name.
443
 * @param int $max_length Maximum allowed length of string value in this field.
444
 * @return int Error code:
445
 * <ul>
446
 * <li>{@link NO_ERROR} - data are valid</li>
447
 * <li>{@link ERROR_INCOMPLETE_FORM} - at least one of required field is empty</li>
448
 * <li>{@link ERROR_INVALID_INTEGER_VALUE} - specified maximum length is invalid</li>
449
 * <li>{@link ERROR_INTEGER_VALUE_OUT_OF_RANGE} - specified maximum length is greater than {@link MAX_FIELD_MULTILINED}</li>
450
 * </ul>
451
 */
452 View Code Duplication
function field_validate_multilined ($field_name, $max_length)
453
{
454
    debug_write_log(DEBUG_TRACE, '[field_validate_multilined]');
455
    debug_write_log(DEBUG_DUMP,  '[field_validate_multilined] $field_name = ' . $field_name);
456
    debug_write_log(DEBUG_DUMP,  '[field_validate_multilined] $max_length = ' . $max_length);
457
458
    // Check that field name is not empty.
459
    if (ustrlen($field_name) == 0)
460
    {
461
        debug_write_log(DEBUG_NOTICE, '[field_validate_multilined] At least one required field is empty.');
462
        return ERROR_INCOMPLETE_FORM;
463
    }
464
465
    // Check that specified values are integer.
466
    if (!is_intvalue($max_length))
467
    {
468
        debug_write_log(DEBUG_NOTICE, '[field_validate_multilined] Invalid integer value.');
469
        return ERROR_INVALID_INTEGER_VALUE;
470
    }
471
472
    // Check that specified values are in the range of valid values.
473
    if ($max_length < 1 || $max_length > MAX_FIELD_MULTILINED)
474
    {
475
        debug_write_log(DEBUG_NOTICE, '[field_validate_multilined] Integer value is out of range.');
476
        return ERROR_INTEGER_VALUE_OUT_OF_RANGE;
477
    }
478
479
    return NO_ERROR;
480
}
481
482
/**
483
 * Validates 'Date' field information before creation or modification.
484
 *
485
 * @param string $field_name Field name.
486
 * @param int $min_value Minimum allowed value of the field.
487
 * @param int $max_value Maximum allowed value of the field.
488
 * @param int $def_value Default allowed value of the field (NULL by default).
489
 * @return int Error code:
490
 * <ul>
491
 * <li>{@link NO_ERROR} - data are valid</li>
492
 * <li>{@link ERROR_INCOMPLETE_FORM} - at least one of required field is empty</li>
493
 * <li>{@link ERROR_INVALID_DATE_VALUE} - at least one of specified dates is invalid integer value</li>
494
 * <li>{@link ERROR_DATE_VALUE_OUT_OF_RANGE} - at least one of specified date values is less than {@link MIN_FIELD_DATE}, or greater than {@link MAX_FIELD_DATE}</li>
495
 * <li>{@link ERROR_MIN_MAX_VALUES} - maximum value is less than minimum one</li>
496
 * <li>{@link ERROR_DEFAULT_VALUE_OUT_OF_RANGE} - default value is less than $min_value, or greater than $max_value</li>
497
 * </ul>
498
 */
499
function field_validate_date ($field_name, $min_value, $max_value, $def_value = NULL)
500
{
501
    debug_write_log(DEBUG_TRACE, '[field_validate_date]');
502
    debug_write_log(DEBUG_DUMP,  '[field_validate_date] $field_name = ' . $field_name);
503
    debug_write_log(DEBUG_DUMP,  '[field_validate_date] $min_value  = ' . $min_value);
504
    debug_write_log(DEBUG_DUMP,  '[field_validate_date] $max_value  = ' . $max_value);
505
    debug_write_log(DEBUG_DUMP,  '[field_validate_date] $def_value  = ' . $def_value);
506
507
    // Check that field name and specified values are not empty.
508 View Code Duplication
    if (ustrlen($field_name) == 0 ||
509
        ustrlen($min_value)  == 0 ||
510
        ustrlen($max_value)  == 0)
511
    {
512
        debug_write_log(DEBUG_NOTICE, '[field_validate_date] At least one required field is empty.');
513
        return ERROR_INCOMPLETE_FORM;
514
    }
515
516
    // Check that specified values are integer.
517 View Code Duplication
    if (!is_intvalue($min_value) ||
518
        !is_intvalue($max_value) ||
519
        (!is_null($def_value) && !is_intvalue($def_value)))
520
    {
521
        debug_write_log(DEBUG_NOTICE, '[field_validate_date] Invalid integer value.');
522
        return ERROR_INVALID_DATE_VALUE;
523
    }
524
525
    // Check that specified values are in the range of valid values.
526
    if ($min_value < MIN_FIELD_DATE || $min_value > MAX_FIELD_DATE ||
527
        $max_value < MIN_FIELD_DATE || $max_value > MAX_FIELD_DATE)
528
    {
529
        debug_write_log(DEBUG_NOTICE, '[field_validate_date] Integer value is out of range.');
530
        return ERROR_DATE_VALUE_OUT_OF_RANGE;
531
    }
532
533
    // Check that minimum value is less than maximum one.
534
    if ($min_value > $max_value)
535
    {
536
        debug_write_log(DEBUG_NOTICE, '[field_validate_date] Minimum value is greater then maximum one.');
537
        return ERROR_MIN_MAX_VALUES;
538
    }
539
540
    // Check that default value is in the range between minimum and maximum ones.
541 View Code Duplication
    if (!is_null($def_value) &&
542
        ($def_value < $min_value || $def_value > $max_value))
543
    {
544
        debug_write_log(DEBUG_NOTICE, '[field_validate_date] Default value is out of range.');
545
        return ERROR_DEFAULT_VALUE_OUT_OF_RANGE;
546
    }
547
548
    return NO_ERROR;
549
}
550
551
/**
552
 * Validates 'Duration' field information before creation or modification.
553
 *
554
 * @param string $field_name Field name.
555
 * @param int $min_value Minimum allowed value of the field.
556
 * @param int $max_value Maximum allowed value of the field.
557
 * @param int $def_value Default allowed value of the field (NULL by default).
558
 * @return int Error code:
559
 * <ul>
560
 * <li>{@link NO_ERROR} - data are valid</li>
561
 * <li>{@link ERROR_INCOMPLETE_FORM} - at least one of required field is empty</li>
562
 * <li>{@link ERROR_INVALID_TIME_VALUE} - at least one of specified duration values is invalid</li>
563
 * <li>{@link ERROR_TIME_VALUE_OUT_OF_RANGE} - at least one of specified duration values is less than {@link MIN_FIELD_DURATION}, or greater than {@link MAX_FIELD_DURATION}</li>
564
 * <li>{@link ERROR_MIN_MAX_VALUES} - maximum value is less than minimum one</li>
565
 * <li>{@link ERROR_DEFAULT_VALUE_OUT_OF_RANGE} - default value is less than $min_value, or greater than $max_value</li>
566
 * </ul>
567
 */
568
function field_validate_duration ($field_name, $min_value, $max_value, $def_value = NULL)
569
{
570
    debug_write_log(DEBUG_TRACE, '[field_validate_duration]');
571
    debug_write_log(DEBUG_DUMP,  '[field_validate_duration] $field_name = ' . $field_name);
572
    debug_write_log(DEBUG_DUMP,  '[field_validate_duration] $min_value  = ' . $min_value);
573
    debug_write_log(DEBUG_DUMP,  '[field_validate_duration] $max_value  = ' . $max_value);
574
    debug_write_log(DEBUG_DUMP,  '[field_validate_duration] $def_value  = ' . $def_value);
575
576
    // Check that field name and specified values are not empty.
577 View Code Duplication
    if (ustrlen($field_name) == 0 ||
578
        ustrlen($min_value)  == 0 ||
579
        ustrlen($max_value)  == 0)
580
    {
581
        debug_write_log(DEBUG_NOTICE, '[field_validate_duration] At least one required field is empty.');
582
        return ERROR_INCOMPLETE_FORM;
583
    }
584
585
    // Convert specified minimum and maximum duration values to amount of minutes.
586
    $min_duration = ustr2time($min_value);
587
    $max_duration = ustr2time($max_value);
588
    $def_duration = (is_null($def_value) ? NULL : ustr2time($def_value));
589
590
    if ($min_duration == -1 ||
591
        $max_duration == -1 ||
592
        $def_duration == -1)
593
    {
594
        debug_write_log(DEBUG_NOTICE, '[field_validate_duration] Invalid duration value.');
595
        return ERROR_INVALID_TIME_VALUE;
596
    }
597
598
    // Check that specified values are in the range of valid values.
599
    if ($min_duration < MIN_FIELD_DURATION || $min_duration > MAX_FIELD_DURATION ||
600
        $max_duration < MIN_FIELD_DURATION || $max_duration > MAX_FIELD_DURATION)
601
    {
602
        debug_write_log(DEBUG_NOTICE, '[field_validate_duration] Duration value is out of range.');
603
        return ERROR_TIME_VALUE_OUT_OF_RANGE;
604
    }
605
606
    if ($min_duration > $max_duration)
607
    {
608
        debug_write_log(DEBUG_NOTICE, '[field_validate_duration] Minimum value is greater then maximum one.');
609
        return ERROR_MIN_MAX_VALUES;
610
    }
611
612
    // Check that default value is in the range between minimum and maximum ones.
613
    if (!is_null($def_duration) &&
614
        ($def_duration < $min_duration || $def_duration > $max_duration))
615
    {
616
        debug_write_log(DEBUG_NOTICE, '[field_validate_duration] Default value is out of range.');
617
        return ERROR_DEFAULT_VALUE_OUT_OF_RANGE;
618
    }
619
620
    return NO_ERROR;
621
}
622
623
/**
624
 * @ignore List items related UI must be remastered via jQueryUI.
625
 */
626
function field_create_list_items ($state_id, $field_name, $list_items)
627
{
628
    debug_write_log(DEBUG_TRACE, '[field_create_list_items]');
629
    debug_write_log(DEBUG_DUMP,  '[field_create_list_items] $state_id   = ' . $state_id);
630
    debug_write_log(DEBUG_DUMP,  '[field_create_list_items] $field_name = ' . $field_name);
631
    debug_write_log(DEBUG_DUMP,  '[field_create_list_items] $list_items = ' . $list_items);
632
633
    $rs = dal_query('fields/fndk.sql', $state_id, ustrtolower($field_name));
634
635
    if ($rs->rows == 0)
0 ignored issues
show
The property $rows is declared protected in CRecordset. Since you implemented __get(), maybe consider adding a @property or @property-read annotation. This makes it easier for IDEs to provide auto-completion.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
636
    {
637
        debug_write_log(DEBUG_ERROR, '[field_create_list_items] Field not found.');
638
        return ERROR_NOT_FOUND;
639
    }
640
641
    $field_id = $rs->fetch('field_id');
642
643
    if (DATABASE_DRIVER == DRIVER_MYSQL50)
644
    {
645
        $rs = dal_query('values/mysql/lvselall.sql', $field_id);
646
647
        while (($row = $rs->fetch()))
648
        {
649
            dal_query('values/mysql/lvdelete.sql', $field_id, $row['int_value']);
650
        }
651
    }
652
    else
653
    {
654
        dal_query('values/lvdelall.sql', $field_id);
655
    }
656
657
    $items = explode("\n", $list_items);
658
659
    foreach ($items as $item)
660
    {
661
        $item = trim($item);
662
663
        if (ustrlen($item) == 0)
664
        {
665
            debug_write_log(DEBUG_NOTICE, '[field_create_list_items] Line is empty.');
666
            continue;
667
        }
668
669
        $pos = ustrpos($item, ' ');
670
671
        if ($pos === FALSE)
672
        {
673
            debug_write_log(DEBUG_NOTICE, '[field_create_list_items] Values separator not found.');
674
            continue;
675
        }
676
677
        $int_value = ustrcut(usubstr($item, 0, $pos), ustrlen(MAXINT));
678
        $str_value = ustrcut(usubstr($item, $pos + 1), MAX_LISTITEM_NAME);
679
680
        if (!is_intvalue($int_value))
681
        {
682
            debug_write_log(DEBUG_NOTICE, '[field_create_list_items] Invalid integer value.');
683
            continue;
684
        }
685
686
        if ($int_value < 1 || $int_value > MAXINT)
687
        {
688
            debug_write_log(DEBUG_NOTICE, '[field_create_list_items] Integer value is out of range.');
689
            continue;
690
        }
691
692
        $rs = dal_query('values/lvfndk2.sql', $field_id, $str_value);
693
694
        if ($rs->rows != 0)
0 ignored issues
show
The property $rows is declared protected in CRecordset. Since you implemented __get(), maybe consider adding a @property or @property-read annotation. This makes it easier for IDEs to provide auto-completion.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
695
        {
696
            debug_write_log(DEBUG_NOTICE, '[field_create_list_items] Specified list item already exists.');
697
            continue;
698
        }
699
700
        $rs = dal_query('values/lvfndk1.sql', $field_id, $int_value);
701
702
        dal_query(($rs->rows == 0 ? 'values/lvcreate.sql' : 'values/lvmodify.sql'),
0 ignored issues
show
The property $rows is declared protected in CRecordset. Since you implemented __get(), maybe consider adding a @property or @property-read annotation. This makes it easier for IDEs to provide auto-completion.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
703
                  $field_id,
704
                  $int_value,
705
                  $str_value);
706
    }
707
708
    return NO_ERROR;
709
}
710
711
/**
712
 * @ignore List items related UI must be remastered via jQueryUI.
713
 */
714 View Code Duplication
function field_pickup_list_items ($field_id)
715
{
716
    debug_write_log(DEBUG_TRACE, '[field_pickup_list_items]');
717
    debug_write_log(DEBUG_DUMP,  '[field_pickup_list_items] $field_id = ' . $field_id);
718
719
    $list_items = NULL;
720
721
    $rs = dal_query('values/lvlist.sql', $field_id);
722
723
    while (($row = $rs->fetch()))
724
    {
725
        $list_items .= sprintf("%u %s\n", $row['int_value'], $row['str_value']);
726
    }
727
728
    return $list_items;
729
}
730
731
/**
732
 * Creates new field.
733
 *
734
 * @param int $template_id ID of template which new field will belong to.
735
 * @param int $state_id ID of state which new field will belong to.
736
 * @param string $field_name Field name.
737
 * @param int $field_type Field type.
738
 * @param bool $is_required Whether the field is required.
739
 * @param bool $add_separator If TRUE, then eTraxis will add separator '<hr>' after the field, when record is being displayed.
740
 * @param bool $guest_access Ability of guest access to the field values.
741
 * @param bool $show_in_emails Whether to show the field in email notifications.
742
 * @param string $description Optional field description.
743
 * @param string $regex_check Perl-compatible regular expression, which values of the field must conform to.
744
 * @param string $regex_search Perl-compatible regular expression to modify values of the field, used to be searched for  (NULL by default).
745
 * @param string $regex_replace Perl-compatible regular expression to modify values of the field, used to replace with (NULL by default).
746
 * @param int $param1 First parameter of the field, specific to its type (NULL by default).
747
 * @param int $param2 Second parameter of the field, specific to its type (NULL by default).
748
 * @param int $value_id Default value of the field, specific to its type (NULL by default).
749
 * @return int Error code:
750
 * <ul>
751
 * <li>{@link NO_ERROR} - field is successfully created</li>
752
 * <li>{@link ERROR_INCOMPLETE_FORM} - at least one of required data is empty</li>
753
 * <li>{@link ERROR_ALREADY_EXISTS} - field with specified name already exists</li>
754
 * <li>{@link ERROR_NOT_FOUND} - failure on attempt to create field</li>
755
 * </ul>
756
 */
757
function field_create ($template_id, $state_id, $field_name, $field_type, $is_required, $add_separator, $guest_access, $show_in_emails, $description = NULL,
758
                       $regex_check = NULL, $regex_search = NULL, $regex_replace = NULL,
759
                       $param1 = NULL, $param2 = NULL, $value_id = NULL)
760
{
761
    debug_write_log(DEBUG_TRACE, '[field_create]');
762
    debug_write_log(DEBUG_DUMP,  '[field_create] $template_id    = ' . $template_id);
763
    debug_write_log(DEBUG_DUMP,  '[field_create] $state_id       = ' . $state_id);
764
    debug_write_log(DEBUG_DUMP,  '[field_create] $field_name     = ' . $field_name);
765
    debug_write_log(DEBUG_DUMP,  '[field_create] $field_type     = ' . $field_type);
766
    debug_write_log(DEBUG_DUMP,  '[field_create] $is_required    = ' . $is_required);
767
    debug_write_log(DEBUG_DUMP,  '[field_create] $add_separator  = ' . $add_separator);
768
    debug_write_log(DEBUG_DUMP,  '[field_create] $guest_access   = ' . $guest_access);
769
    debug_write_log(DEBUG_DUMP,  '[field_create] $show_in_emails = ' . $show_in_emails);
770
    debug_write_log(DEBUG_DUMP,  '[field_create] $description    = ' . $description);
771
    debug_write_log(DEBUG_DUMP,  '[field_create] $regex_check    = ' . $regex_check);
772
    debug_write_log(DEBUG_DUMP,  '[field_create] $regex_search   = ' . $regex_search);
773
    debug_write_log(DEBUG_DUMP,  '[field_create] $regex_replace  = ' . $regex_replace);
774
    debug_write_log(DEBUG_DUMP,  '[field_create] $param1         = ' . $param1);
775
    debug_write_log(DEBUG_DUMP,  '[field_create] $param2         = ' . $param2);
776
    debug_write_log(DEBUG_DUMP,  '[field_create] $value_id       = ' . $value_id);
777
778
    // Check that field name is not empty.
779
    if (ustrlen($field_name) == 0)
780
    {
781
        debug_write_log(DEBUG_NOTICE, '[field_create] At least one required field is empty.');
782
        return ERROR_INCOMPLETE_FORM;
783
    }
784
785
    // Check that there is no field with the same name in the specified state.
786
    $rs = dal_query('fields/fndk.sql', $state_id, ustrtolower($field_name));
787
788
    if ($rs->rows != 0)
0 ignored issues
show
The property $rows is declared protected in CRecordset. Since you implemented __get(), maybe consider adding a @property or @property-read annotation. This makes it easier for IDEs to provide auto-completion.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
789
    {
790
        debug_write_log(DEBUG_NOTICE, '[field_create] Field already exists.');
791
        return ERROR_ALREADY_EXISTS;
792
    }
793
794
    // Calculates field order.
795
    $rs = dal_query('fields/count.sql', $state_id);
796
    $field_order = $rs->fetch(0) + 1;
797
798
    // Create a field.
799
    dal_query('fields/create.sql',
800
              $template_id,
801
              $state_id,
802
              $field_name,
803
              $field_order,
804
              $field_type,
805
              bool2sql($is_required),
806
              bool2sql($add_separator),
807
              bool2sql($show_in_emails),
808
              bool2sql($guest_access),
809
              ustrlen($description)   == 0 ? NULL : $description,
810
              ustrlen($regex_check)   == 0 ? NULL : $regex_check,
811
              ustrlen($regex_search)  == 0 ? NULL : $regex_search,
812
              ustrlen($regex_replace) == 0 ? NULL : $regex_replace,
813
              is_null($param1)             ? NULL : $param1,
814
              is_null($param2)             ? NULL : $param2,
815
              is_null($value_id)           ? NULL : $value_id);
816
817
    $rs = dal_query('fields/fndk.sql', $state_id, ustrtolower($field_name));
818
819
    if ($rs->rows == 0)
0 ignored issues
show
The property $rows is declared protected in CRecordset. Since you implemented __get(), maybe consider adding a @property or @property-read annotation. This makes it easier for IDEs to provide auto-completion.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
820
    {
821
        debug_write_log(DEBUG_NOTICE, '[field_create] Field cannot be found.');
822
        return ERROR_NOT_FOUND;
823
    }
824
825
    $row = $rs->fetch();
826
827
    // Give permission to read to all local project groups.
828
    dal_query('fields/fpaddall.sql',
829
              $row['project_id'],
830
              $row['field_id'],
831
              FIELD_ALLOW_TO_READ);
832
833
    // Give permission to write to all local project groups.
834
    dal_query('fields/fpaddall.sql',
835
              $row['project_id'],
836
              $row['field_id'],
837
              FIELD_ALLOW_TO_WRITE);
838
839
    return NO_ERROR;
840
}
841
842
/**
843
 * Modifies specified field.
844
 *
845
 * @param int $id ID of field to be modified.
846
 * @param int $state_id ID of the state which the field belongs to.
847
 * @param int $state_name Name of the state which the field belongs to.
848
 * @param string $field_old_name Current field name.
849
 * @param string $field_new_name New field name.
850
 * @param int $field_old_order Current field order.
851
 * @param int $field_new_order New field order.
852
 * @param int $field_type Current field type (field type is not modifiable).
853
 * @param bool $is_required Whether the field is required.
854
 * @param bool $add_separator If TRUE, then eTraxis will add separator '<hr>' after the field, when record is being displayed.
855
 * @param bool $guest_access Ability of guest access to the field values.
856
 * @param bool $show_in_emails Whether to show the field in email notifications.
857
 * @param string $description Optional field description.
858
 * @param string $regex_check New perl-compatible regular expression, which values of the field must conform to.
859
 * @param string $regex_search New perl-compatible regular expression to modify values of the field, used to be searched for  (NULL by default).
860
 * @param string $regex_replace New perl-compatible regular expression to modify values of the field, used to replace with (NULL by default).
861
 * @param int $param1 New first parameter of the field, specific to its type (NULL by default).
862
 * @param int $param2 New second parameter of the field, specific to its type (NULL by default).
863
 * @param int $value_id New default value of the field, specific to its type (NULL by default).
864
 * @return int Error code:
865
 * <ul>
866
 * <li>{@link NO_ERROR} - field is successfully modified</li>
867
 * <li>{@link ERROR_INCOMPLETE_FORM} - at least one of required data is empty</li>
868
 * <li>{@link ERROR_ALREADY_EXISTS} - another field with specified name already exists</li>
869
 * </ul>
870
 */
871
function field_modify ($id, $state_id, $state_name, $field_old_name, $field_new_name, $field_old_order, $field_new_order, $field_type, $is_required, $add_separator, $guest_access, $show_in_emails, $description = NULL,
872
                       $regex_check = NULL, $regex_search = NULL, $regex_replace = NULL,
873
                       $param1 = NULL, $param2 = NULL, $value_id = NULL)
874
{
875
    debug_write_log(DEBUG_TRACE, '[field_modify]');
876
    debug_write_log(DEBUG_DUMP,  '[field_modify] $id              = ' . $id);
877
    debug_write_log(DEBUG_DUMP,  '[field_modify] $state_id        = ' . $state_id);
878
    debug_write_log(DEBUG_DUMP,  '[field_modify] $state_name      = ' . $state_name);
879
    debug_write_log(DEBUG_DUMP,  '[field_modify] $field_old_name  = ' . $field_old_name);
880
    debug_write_log(DEBUG_DUMP,  '[field_modify] $field_new_name  = ' . $field_new_name);
881
    debug_write_log(DEBUG_DUMP,  '[field_modify] $field_old_order = ' . $field_old_order);
882
    debug_write_log(DEBUG_DUMP,  '[field_modify] $field_new_order = ' . $field_new_order);
883
    debug_write_log(DEBUG_DUMP,  '[field_modify] $field_type      = ' . $field_type);
884
    debug_write_log(DEBUG_DUMP,  '[field_modify] $is_required     = ' . $is_required);
885
    debug_write_log(DEBUG_DUMP,  '[field_modify] $add_separator   = ' . $add_separator);
886
    debug_write_log(DEBUG_DUMP,  '[field_modify] $guest_access    = ' . $guest_access);
887
    debug_write_log(DEBUG_DUMP,  '[field_modify] $show_in_emails  = ' . $show_in_emails);
888
    debug_write_log(DEBUG_DUMP,  '[field_modify] $description     = ' . $description);
889
    debug_write_log(DEBUG_DUMP,  '[field_modify] $regex_check     = ' . $regex_check);
890
    debug_write_log(DEBUG_DUMP,  '[field_modify] $regex_search    = ' . $regex_search);
891
    debug_write_log(DEBUG_DUMP,  '[field_modify] $regex_replace   = ' . $regex_replace);
892
    debug_write_log(DEBUG_DUMP,  '[field_modify] $param1          = ' . $param1);
893
    debug_write_log(DEBUG_DUMP,  '[field_modify] $param2          = ' . $param2);
894
    debug_write_log(DEBUG_DUMP,  '[field_modify] $value_id        = ' . $value_id);
895
896
    // Check that field name is not empty.
897
    if (ustrlen($field_new_name) == 0)
898
    {
899
        debug_write_log(DEBUG_NOTICE, '[field_modify] At least one required field is empty.');
900
        return ERROR_INCOMPLETE_FORM;
901
    }
902
903
    // Check that there is no field with the same name, besides this one.
904
    $rs = dal_query('fields/fndku.sql', $id, $state_id, ustrtolower($field_new_name));
905
906
    if ($rs->rows != 0)
0 ignored issues
show
The property $rows is declared protected in CRecordset. Since you implemented __get(), maybe consider adding a @property or @property-read annotation. This makes it easier for IDEs to provide auto-completion.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
907
    {
908
        debug_write_log(DEBUG_NOTICE, '[field_modify] Field already exists.');
909
        return ERROR_ALREADY_EXISTS;
910
    }
911
912
    // Reorder field.
913
    $rs = dal_query('fields/count.sql', $state_id);
914
915
    if ($field_new_order < 1 || $field_new_order > $rs->fetch(0))
916
    {
917
        debug_write_log(DEBUG_NOTICE, '[field_modify] Field order is out of range.');
918
    }
919
    elseif ($field_old_order < $field_new_order)
920
    {
921
        debug_write_log(DEBUG_NOTICE, '[field_modify] Field order is being changed (going down).');
922
923
        dal_query('fields/setorder.sql', $state_id, $field_old_order, 0);
924
925 View Code Duplication
        for ($i = $field_old_order; $i < $field_new_order; $i++)
926
        {
927
            dal_query('fields/setorder.sql', $state_id, $i + 1, $i);
928
        }
929
930
        dal_query('fields/setorder.sql', $state_id, 0, $field_new_order);
931
    }
932
    elseif ($field_old_order > $field_new_order)
933
    {
934
        debug_write_log(DEBUG_NOTICE, '[field_modify] Field order is being changed (going up).');
935
936
        dal_query('fields/setorder.sql', $state_id, $field_old_order, 0);
937
938 View Code Duplication
        for ($i = $field_old_order; $i > $field_new_order; $i--)
939
        {
940
            dal_query('fields/setorder.sql', $state_id, $i - 1, $i);
941
        }
942
943
        dal_query('fields/setorder.sql', $state_id, 0, $field_new_order);
944
    }
945
946
    // Update existing views.
947
    dal_query('fields/views.sql',
948
              $state_name,
949
              $field_old_name,
950
              $field_new_name);
951
952
    // Modify the field.
953
    dal_query('fields/modify.sql',
954
              $id,
955
              $field_new_name,
956
              bool2sql($is_required),
957
              bool2sql($add_separator),
958
              bool2sql($guest_access),
959
              bool2sql($show_in_emails),
960
              ustrlen($description)   == 0 ? NULL : $description,
961
              ustrlen($regex_check)   == 0 ? NULL : $regex_check,
962
              ustrlen($regex_search)  == 0 ? NULL : $regex_search,
963
              ustrlen($regex_replace) == 0 ? NULL : $regex_replace,
964
              is_null($param1)             ? NULL : $param1,
965
              is_null($param2)             ? NULL : $param2,
966
              is_null($value_id)           ? NULL : $value_id);
967
968
    return NO_ERROR;
969
}
970
971
/**
972
 * Checks whether field can be deleted.
973
 *
974
 * @param int $id ID of field to be deleted.
975
 * @return bool TRUE if field can be deleted, FALSE otherwise.
976
 */
977
function is_field_removable ($id)
978
{
979
    debug_write_log(DEBUG_TRACE, '[is_field_removable]');
980
    debug_write_log(DEBUG_DUMP,  '[is_field_removable] $id = ' . $id);
981
982
    $rs = dal_query('fields/fvfndc.sql', $id);
983
984
    return ($rs->fetch(0) == 0);
985
}
986
987
/**
988
 * Deletes specified field if it's removable, or disables the field otherwise.
989
 *
990
 * @param int $id ID of field to be deleted.
991
 * @return int Error code:
992
 * <ul>
993
 * <li>{@link NO_ERROR} - field is successfully deleted/disabled</li>
994
 * <li>{@link ERROR_NOT_FOUND} - specified field cannot be found</li>
995
 * </ul>
996
 */
997
function field_delete ($id)
998
{
999
    debug_write_log(DEBUG_TRACE, '[field_delete]');
1000
    debug_write_log(DEBUG_DUMP,  '[field_delete] $id = ' . $id);
1001
1002
    // Find field in database.
1003
    $field = field_find($id);
1004
1005
    if (!$field)
1006
    {
1007
        debug_write_log(DEBUG_NOTICE, '[field_delete] Field cannot be found.');
1008
        return ERROR_NOT_FOUND;
1009
    }
1010
1011
    // Get current number of fields.
1012
    $rs = dal_query('fields/count.sql', $field['state_id']);
1013
    $last_field = $rs->fetch(0);
1014
1015
    if (is_field_removable($id))
1016
    {
1017
        // Delete all related data.
1018
        dal_query('fields/lvdelall.sql', $id);
1019
        dal_query('fields/ffdelall.sql', $id);
1020
        dal_query('fields/fpdelall.sql', $id);
1021
        dal_query('fields/delete.sql',   $id);
1022
    }
1023
    else
1024
    {
1025
        // Disable the field.
1026
        dal_query('fields/disable.sql', $id, time());
1027
    }
1028
1029
    // Reorder rest of fields in the same state.
1030
    for ($i = $field['field_order']; $i < $last_field; $i++)
1031
    {
1032
        dal_query('fields/setorder.sql', $field['state_id'], $i + 1, $i);