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);
1033
    }
1034
1035
    return NO_ERROR;
1036
}
1037
1038
/**
1039
 * Sets permissions of system role 'author' for specified field.
1040
 *
1041
 * @param int $fid ID of field which permissions should be set for.
1042
 * @param int $perm New permissions set.
1043
 * @return int Always {@link NO_ERROR}.
1044
 */
1045
function field_author_permission_set ($fid, $perm)
1046
{
1047
    debug_write_log(DEBUG_TRACE, '[field_author_permission_set]');
1048
    debug_write_log(DEBUG_DUMP,  '[field_author_permission_set] $fid  = ' . $fid);
1049
    debug_write_log(DEBUG_DUMP,  '[field_author_permission_set] $perm = ' . $perm);
1050
1051
    dal_query('fields/apset.sql', $fid, $perm);
1052
1053
    return NO_ERROR;
1054
}
1055
1056
/**
1057
 * Sets permissions of system role 'responsible' for specified field.
1058
 *
1059
 * @param int $fid ID of field which permissions should be set for.
1060
 * @param int $perm New permissions set.
1061
 * @return int Always {@link NO_ERROR}.
1062
 */
1063
function field_responsible_permission_set ($fid, $perm)
1064
{
1065
    debug_write_log(DEBUG_TRACE, '[field_responsible_permission_set]');
1066
    debug_write_log(DEBUG_DUMP,  '[field_responsible_permission_set] $fid  = ' . $fid);
1067
    debug_write_log(DEBUG_DUMP,  '[field_responsible_permission_set] $perm = ' . $perm);
1068
1069
    dal_query('fields/rpset.sql', $fid, $perm);
1070
1071
    return NO_ERROR;
1072
}
1073
1074
/**
1075
 * Sets permissions of system role 'registered' for specified field.
1076
 *
1077
 * @param int $fid ID of field which permissions should be set for.
1078
 * @param int $perm New permissions set.
1079
 * @return int Always {@link NO_ERROR}.
1080
 */
1081
function field_registered_permission_set ($fid, $perm)
1082
{
1083
    debug_write_log(DEBUG_TRACE, '[field_registered_permission_set]');
1084
    debug_write_log(DEBUG_DUMP,  '[field_registered_permission_set] $fid  = ' . $fid);
1085
    debug_write_log(DEBUG_DUMP,  '[field_registered_permission_set] $perm = ' . $perm);
1086
1087
    dal_query('fields/r2pset.sql', $fid, $perm);
1088
1089
    return NO_ERROR;
1090
}
1091
1092
/**
1093
 * Gives to specified group a specified permission for specified field.
1094
 *
1095
 * @param int $fid Field ID.
1096
 * @param int $gid Group ID.
1097
 * @param int $perm Permission (exactly one of the following):
1098
 * <ul>
1099
 * <li>{@link FIELD_ALLOW_TO_READ}</li>
1100
 * <li>{@link FIELD_ALLOW_TO_WRITE}</li>
1101
 * </ul>
1102
 * @return int Always {@link NO_ERROR}.
1103
 */
1104 View Code Duplication
function field_permission_add ($fid, $gid, $perm)
1105
{
1106
    debug_write_log(DEBUG_TRACE, '[field_permission_add]');
1107
    debug_write_log(DEBUG_DUMP,  '[field_permission_add] $fid  = ' . $fid);
1108
    debug_write_log(DEBUG_DUMP,  '[field_permission_add] $gid  = ' . $gid);
1109
    debug_write_log(DEBUG_DUMP,  '[field_permission_add] $perm = ' . $perm);
1110
1111
    dal_query('fields/fpadd.sql', $fid, $gid, $perm);
1112
1113
    return NO_ERROR;
1114
}
1115
1116
/**
1117
 * Revokes from specified group all permissions for specified field.
1118
 *
1119
 * @param int $fid Field ID.
1120
 * @param int $gid Group ID.
1121
 * @return int Always {@link NO_ERROR}.
1122
 */
1123
function field_permission_remove ($fid, $gid)
1124
{
1125
    debug_write_log(DEBUG_TRACE, '[field_permission_remove]');
1126
    debug_write_log(DEBUG_DUMP,  '[field_permission_remove] $fid  = ' . $fid);
1127
    debug_write_log(DEBUG_DUMP,  '[field_permission_remove] $gid  = ' . $gid);
1128
1129
    dal_query('fields/fpremove.sql', $fid, $gid);
1130
1131
    return NO_ERROR;
1132
}
1133
1134
/**
1135
 * Exports all fields of the specified state to XML code (see also {@link state_export}).
1136
 *
1137
 * @param int $id ID of state, which fields should be exported.
1138
 * @param array &$groups Array of IDs of groups, affected by this template (used for output only).
1139
 * @return string Generated XML code.
1140
 */
1141
function field_export ($id, &$groups)
1142
{
1143
    debug_write_log(DEBUG_TRACE, '[field_export]');
1144
    debug_write_log(DEBUG_DUMP,  '[field_export] $id = ' . $id);
1145
1146
    // Allocation of field types to XML code.
1147
    $types = array
1148
    (
1149
        FIELD_TYPE_NUMBER     => 'number',
1150
        FIELD_TYPE_FLOAT      => 'float',
1151
        FIELD_TYPE_STRING     => 'string',
1152
        FIELD_TYPE_MULTILINED => 'multi',
1153
        FIELD_TYPE_CHECKBOX   => 'check',
1154
        FIELD_TYPE_LIST       => 'list',
1155
        FIELD_TYPE_RECORD     => 'record',
1156
        FIELD_TYPE_DATE       => 'date',
1157
        FIELD_TYPE_DURATION   => 'duration',
1158
    );
1159
1160
    // List all fields of the state.
1161
    $rs = dal_query('fields/list.sql', $id, 'field_order');
1162
1163
    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...
1164
    {
1165
        return NULL;
1166
    }
1167
1168
    $xml = "        <fields>\n";
1169
1170
    // Add XML code for each found field.
1171
    while (($field = $rs->fetch()))
1172
    {
1173
        // Add XML code for general field information.
1174
        $xml .= sprintf("          <field name=\"%s\" type=\"%s\" required=\"%s\" guest_access=\"%s\" separator=\"%s\" show_in_emails=\"%s\"",
1175
                        ustr2html($field['field_name']),
1176
                        $types[$field['field_type']],
1177
                        ($field['is_required']    ? 'yes' : 'no'),
1178
                        ($field['guest_access']   ? 'yes' : 'no'),
1179
                        ($field['add_separator']  ? 'yes' : 'no'),
1180
                        ($field['show_in_emails'] ? 'yes' : 'no'));
1181
1182
        // Add XML code for information, specific to type of the field.
1183
        switch ($field['field_type'])
1184
        {
1185
            case FIELD_TYPE_NUMBER:
1186
                $xml .= sprintf(' minimum="%d" maximum="%d"', $field['param1'], $field['param2']);
1187
                break;
1188
1189 View Code Duplication
            case FIELD_TYPE_FLOAT:
1190
                $xml .= sprintf(' minimum="%.10f" maximum="%.10f"',
1191
                                value_find(FIELD_TYPE_FLOAT, $field['param1']),
1192
                                value_find(FIELD_TYPE_FLOAT, $field['param2']));
1193
                break;
1194
1195
            case FIELD_TYPE_STRING:
1196
            case FIELD_TYPE_MULTILINED:
1197
                $xml .= sprintf(' length="%u"', $field['param1']);
1198
                break;
1199
1200
            case FIELD_TYPE_DATE:
1201
                $xml .= sprintf(' minimum="%s" maximum="%s"', $field['param1'], $field['param2']);
1202
                break;
1203
1204
            case FIELD_TYPE_DURATION:
1205
                $xml .= sprintf(' minimum="%s" maximum="%s"', time2ustr($field['param1']), time2ustr($field['param2']));
1206
                break;
1207
1208
            default: ;  // nop
1209
        }
1210
1211
        // If default value is specified, add XML code for it.
1212
        if (!is_null($field['value_id']))
1213
        {
1214
            switch ($field['field_type'])
1215
            {
1216
                case FIELD_TYPE_NUMBER:
1217
                    $xml .= sprintf(' default="%d"', $field['value_id']);
1218
                    break;
1219
1220
                case FIELD_TYPE_FLOAT:
1221
                    $xml .= sprintf(' default="%.10f"', value_find(FIELD_TYPE_FLOAT, $field['value_id']));
1222
                    break;
1223
1224
                case FIELD_TYPE_LIST:
1225
                    $xml .= sprintf(' default="%u"', $field['value_id']);
1226
                    break;
1227
1228
                case FIELD_TYPE_STRING:
1229
                    $xml .= sprintf(' default="%s"', ustr2html(value_find(FIELD_TYPE_STRING, $field['value_id'])));
1230
                    break;
1231
1232
                case FIELD_TYPE_CHECKBOX:
1233
                    $xml .= sprintf(' default="%s"', ($field['value_id'] ? 'on' : 'off'));
1234
                    break;
1235
1236
                case FIELD_TYPE_DATE:
1237
                    $xml .= sprintf(' default="%s"', $field['value_id']);
1238
                    break;
1239
1240
                case FIELD_TYPE_DURATION:
1241
                    $xml .= sprintf(' default="%s"', time2ustr($field['value_id']));
1242
                    break;
1243
1244
                default: ;  // nop
1245
            }
1246
        }
1247
1248
        // If RegEx values are specified, add XML code for them.
1249
        if ($field['field_type'] == FIELD_TYPE_STRING ||
1250
            $field['field_type'] == FIELD_TYPE_MULTILINED)
1251
        {
1252
            if (!is_null($field['regex_check']))
1253
            {
1254
                $xml .= sprintf(' regex_check="%s"', ustr2html($field['regex_check']));
1255
            }
1256
1257
            if (!is_null($field['regex_search']))
1258
            {
1259
                $xml .= sprintf(' regex_search="%s"', ustr2html($field['regex_search']));
1260
            }
1261
1262
            if (!is_null($field['regex_replace']))
1263
            {
1264
                $xml .= sprintf(' regex_replace="%s"', ustr2html($field['regex_replace']));
1265
            }
1266
        }
1267
1268
        $xml .= ">\n";
1269
1270
        // Default value of 'multilined' field is processed in a specific way (must be out in dedicated XML tags).
1271
        if ($field['field_type'] == FIELD_TYPE_MULTILINED)
1272
        {
1273
            $default = value_find(FIELD_TYPE_MULTILINED, $field['value_id']);
1274
1275
            if (!is_null($default))
1276
            {
1277
                $xml .= "            <default>\n";
1278
                $xml .= ustr2html($default) . "\n";
1279
                $xml .= "            </default>\n";
1280
            }
1281
        }
1282
1283
        // Description of field is processed in a specific way (must be out in dedicated XML tags).
1284
        if (strlen($field['description']) != 0)
1285
        {
1286
            $xml .= "            <description>\n";
1287
            $xml .= ustr2html($field['description']) . "\n";
1288
            $xml .= "            </description>\n";
1289
        }
1290
1291
        // If field type is 'list', enumerate all its items.
1292
        if ($field['field_type'] == FIELD_TYPE_LIST)
1293
        {
1294
            $rsl = dal_query('values/lvlist.sql', $field['field_id']);
1295
1296
            if ($rsl->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...
1297
            {
1298
                $xml .= "            <list>\n";
1299
1300
                while (($item = $rsl->fetch()))
1301
                {
1302
                    $xml .= "              <item value=\"{$item['int_value']}\">" . ustr2html($item['str_value']) . "</item>\n";
1303
                }
1304
1305
                $xml .= "            </list>\n";
1306
            }
1307
        }
1308
1309
        // Enumerate permissions of all groups for this field.
1310
        $rsp = dal_query('fields/fplist.sql', $field['field_id']);
1311
1312
        if ($field['author_perm']      != 0 ||
1313
            $field['responsible_perm'] != 0 ||
1314
            $field['registered_perm']  != 0 ||
1315
            $rsp->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...
1316
        {
1317
            $xml .= "            <permissions>\n";
1318
1319
            if     ($field['author_perm'] == 1)
1320
            {
1321
                $xml .= "              <author>read</author>\n";
1322
            }
1323
            elseif ($field['author_perm'] == 2)
1324
            {
1325
                $xml .= "              <author>write</author>\n";
1326
            }
1327
1328
            if     ($field['responsible_perm'] == 1)
1329
            {
1330
                $xml .= "              <responsible>read</responsible>\n";
1331
            }
1332
            elseif ($field['responsible_perm'] == 2)
1333
            {
1334
                $xml .= "              <responsible>write</responsible>\n";
1335
            }
1336
1337
            if     ($field['registered_perm'] == 1)
1338
            {
1339
                $xml .= "              <registered>read</registered>\n";
1340
            }
1341
            elseif ($field['registered_perm'] == 2)
1342
            {
1343
                $xml .= "              <registered>write</registered>\n";
1344
            }
1345
1346
            while (($group = $rsp->fetch()))
1347
            {
1348
                array_push($groups, $group['group_id']);
1349
1350
                $xml .= sprintf("              <group name=\"%s\" type=\"%s\">",
1351
                                ustr2html($group['group_name']),
1352
                                (is_null($group['project_id']) ? 'global' : 'local'));
1353
1354
                $xml .= ($group['perms'] == FIELD_ALLOW_TO_WRITE ? 'write' : 'read');
1355
                $xml .= "</group>\n";
1356
            }
1357
1358
            $xml .= "            </permissions>\n";
1359
        }
1360
1361
        $xml .= "          </field>\n";
1362
    }
1363
1364
    $xml .= "        </fields>\n";
1365
1366
    return $xml;
1367
}
1368
1369
/**
1370
 * Imports fields described as XML code into the specified state.
1371
 *
1372
 * @param int $template_id ID of destination template.
1373
 * @param int $state_id ID of destination state.
1374
 * @param string $xml Valid XML code.
1375
 * @param string &$error In case of failure - the error message (used as output only).
1376
 * @return bool Whether the import was successful.
1377
 */
1378
function fields_import ($template_id, $state_id, $xml, &$error)
1379
{
1380
    debug_write_log(DEBUG_TRACE, '[fields_import]');
1381
    debug_write_log(DEBUG_DUMP,  '[fields_import] $template_id = ' . $template_id);
1382
    debug_write_log(DEBUG_DUMP,  '[fields_import] $state_id    = ' . $state_id);
1383
1384
    // Allocation of XML code to field types.
1385
    $types = array
1386
    (
1387
        'number'   => FIELD_TYPE_NUMBER,
1388
        'float'    => FIELD_TYPE_FLOAT,
1389
        'string'   => FIELD_TYPE_STRING,
1390
        'multi'    => FIELD_TYPE_MULTILINED,
1391
        'check'    => FIELD_TYPE_CHECKBOX,
1392
        'list'     => FIELD_TYPE_LIST,
1393
        'record'   => FIELD_TYPE_RECORD,
1394
        'date'     => FIELD_TYPE_DATE,
1395
        'duration' => FIELD_TYPE_DURATION,
1396
    );
1397
1398
    // Enumerate fields.
1399
    $fields = $xml->xpath('./fields/field');
1400
1401
    if ($fields !== FALSE)
1402
    {
1403
        foreach ($fields as $field)
1404
        {
1405
            $field_type = strval($field['type']);
1406
1407
            if (!array_key_exists($field_type, $types))
1408
            {
1409
                continue;
1410
            }
1411
1412
            $field_name     = ustrcut($field['name'], MAX_FIELD_NAME);
1413
            $field_type     = $types[$field_type];
1414
1415
            $is_required    = ($field['required']       == 'yes');
1416
            $add_separator  = ($field['separator']      == 'yes');
1417
            $guest_access   = ($field['guest_access']   == 'yes');
1418
            $show_in_emails = ($field['show_in_emails'] == 'yes');
1419
1420
            $description    = isset($field->description)
1421
                            ? ustrcut($field->description, MAX_FIELD_DESCRIPTION)
1422
                            : NULL;
1423
1424
            $regex_check    = NULL;
1425
            $regex_search   = NULL;
1426
            $regex_replace  = NULL;
1427
            $param1         = NULL;
1428
            $param2         = NULL;
1429
            $default        = NULL;
1430
1431
            // Validate field (number).
1432
            if ($field_type == FIELD_TYPE_NUMBER)
1433
            {
1434
                $param1  = ustrcut($field['minimum'], ustrlen(MAX_FIELD_INTEGER) + 1);
1435
                $param2  = ustrcut($field['maximum'], ustrlen(MAX_FIELD_INTEGER) + 1);
1436
                $default = ustrcut($field['default'], ustrlen(MAX_FIELD_INTEGER) + 1);
1437
1438
                $default = (ustrlen($default) == 0) ? NULL : intval($default);
1439
1440
                switch (field_validate_number($field_name, $param1, $param2, $default))
1441
                {
1442
                    case NO_ERROR:
1443
                        break;  // nop
1444
                    case ERROR_INCOMPLETE_FORM:
1445
                        $error = get_html_resource(RES_ALERT_REQUIRED_ARE_EMPTY_ID);
1446
                        return FALSE;
1447
                    case ERROR_INVALID_INTEGER_VALUE:
1448
                        $error = get_html_resource(RES_ALERT_INVALID_INTEGER_VALUE_ID);
1449
                        return FALSE;
1450
                    case ERROR_INTEGER_VALUE_OUT_OF_RANGE:
1451
                        $error = ustrprocess(get_html_resource(RES_ALERT_INTEGER_VALUE_OUT_OF_RANGE_ID), -MAX_FIELD_INTEGER, +MAX_FIELD_INTEGER);
1452
                        return FALSE;
1453
                    case ERROR_MIN_MAX_VALUES:
1454
                        $error = get_html_resource(RES_ALERT_MIN_MAX_VALUES_ID);
1455
                        return FALSE;
1456
                    case ERROR_DEFAULT_VALUE_OUT_OF_RANGE:
1457
                        $error = ustrprocess(get_html_resource(RES_ALERT_DEFAULT_VALUE_OUT_OF_RANGE_ID), $param1, $param2);
1458
                        return FALSE;
1459
                    default:
1460
                        debug_write_log(DEBUG_WARNING, '[fields_import] Field validation failure (number).');
1461
                        $error = get_html_resource(RES_ALERT_UNKNOWN_ERROR_ID);
1462
                        return FALSE;
1463
                }
1464
            }
1465
1466
            // Validate field (float).
1467
            elseif ($field_type == FIELD_TYPE_FLOAT)
1468
            {
1469
                $param1  = ustrcut($field['minimum'], ustrlen(MIN_FIELD_FLOAT));
1470
                $param2  = ustrcut($field['maximum'], ustrlen(MAX_FIELD_FLOAT));
1471
                $default = ustrcut($field['default'], ustrlen(MAX_FIELD_FLOAT));
1472
1473
                $default = (ustrlen($default) == 0) ? NULL : $default;
1474
1475 View Code Duplication
                switch (field_validate_float($field_name, $param1, $param2, $default))
1476
                {
1477
                    case NO_ERROR:
1478
                        $param1  = value_find_float($param1);
1479
                        $param2  = value_find_float($param2);
1480
                        $default = is_null($default) ? NULL : value_find_float($default);
1481
                        break;  // nop
1482
                    case ERROR_INCOMPLETE_FORM:
1483
                        $error = get_html_resource(RES_ALERT_REQUIRED_ARE_EMPTY_ID);
1484
                        return FALSE;
1485
                    case ERROR_INVALID_FLOAT_VALUE:
1486
                        $error = get_html_resource(RES_ALERT_INVALID_DECIMAL_VALUE_ID);
1487
                        return FALSE;
1488
                    case ERROR_FLOAT_VALUE_OUT_OF_RANGE:
1489
                        $error = ustrprocess(get_html_resource(RES_ALERT_DECIMAL_VALUE_OUT_OF_RANGE_ID), MIN_FIELD_FLOAT, MAX_FIELD_FLOAT);
1490
                        return FALSE;
1491
                    case ERROR_MIN_MAX_VALUES:
1492
                        $error = get_html_resource(RES_ALERT_MIN_MAX_VALUES_ID);
1493
                        return FALSE;
1494
                    case ERROR_DEFAULT_VALUE_OUT_OF_RANGE:
1495
                        $error = ustrprocess(get_html_resource(RES_ALERT_DEFAULT_VALUE_OUT_OF_RANGE_ID), $param1, $param2);
1496
                        return FALSE;
1497
                    default:
1498
                        debug_write_log(DEBUG_WARNING, '[fields_import] Field validation failure (float).');
1499
                        $error = get_html_resource(RES_ALERT_UNKNOWN_ERROR_ID);
1500
                        return FALSE;
1501
                }
1502
            }
1503
1504
            // Validate field (string).
1505 View Code Duplication
            elseif ($field_type == FIELD_TYPE_STRING)
1506
            {
1507
                $regex_check   = ustrcut($field['regex_check'],   MAX_FIELD_REGEX);
1508
                $regex_search  = ustrcut($field['regex_search'],  MAX_FIELD_REGEX);
1509
                $regex_replace = ustrcut($field['regex_replace'], MAX_FIELD_REGEX);
1510
                $param1        = ustrcut($field['length'],        ustrlen(MAX_FIELD_STRING));
1511
1512
                switch (field_validate_string($field_name, $param1))
1513
                {
1514
                    case NO_ERROR:
1515
                        $default = ustrcut($field['default'], $param1);
1516
                        $default = (ustrlen($default) == 0) ? NULL : value_find_string($default);
1517
                        break;  // nop
1518
                    case ERROR_INCOMPLETE_FORM:
1519
                        $error = get_html_resource(RES_ALERT_REQUIRED_ARE_EMPTY_ID);
1520
                        return FALSE;
1521
                    case ERROR_INVALID_INTEGER_VALUE:
1522
                        $error = get_html_resource(RES_ALERT_INVALID_INTEGER_VALUE_ID);
1523
                        return FALSE;
1524
                    case ERROR_INTEGER_VALUE_OUT_OF_RANGE:
1525
                        $error = ustrprocess(get_html_resource(RES_ALERT_INTEGER_VALUE_OUT_OF_RANGE_ID), 1, MAX_FIELD_STRING);
1526
                        return FALSE;
1527
                    default:
1528
                        debug_write_log(DEBUG_WARNING, '[fields_import] Field validation failure (string).');
1529
                        $error = get_html_resource(RES_ALERT_UNKNOWN_ERROR_ID);
1530
                        return FALSE;
1531
                }
1532
            }
1533
1534
            // Validate field (multilined).
1535 View Code Duplication
            elseif ($field_type == FIELD_TYPE_MULTILINED)
1536
            {
1537
                $regex_check   = ustrcut($field['regex_check'],   MAX_FIELD_REGEX);
1538
                $regex_search  = ustrcut($field['regex_search'],  MAX_FIELD_REGEX);
1539
                $regex_replace = ustrcut($field['regex_replace'], MAX_FIELD_REGEX);
1540
                $param1        = ustrcut($field['length'],        ustrlen(MAX_FIELD_MULTILINED));
1541
1542
                switch (field_validate_multilined($field_name, $param1))
1543
                {
1544
                    case NO_ERROR:
1545
                        if (isset($field->default))
1546
                        {
1547
                            $default = ustrcut($field->default, $param1);
1548
                            $default = (ustrlen($default) == 0) ? NULL : value_find_multilined($default);
1549
                        }
1550
                        break;  // nop
1551
                    case ERROR_INCOMPLETE_FORM:
1552
                        $error = get_html_resource(RES_ALERT_REQUIRED_ARE_EMPTY_ID);
1553
                        return FALSE;
1554
                    case ERROR_INVALID_INTEGER_VALUE:
1555
                        $error = get_html_resource(RES_ALERT_INVALID_INTEGER_VALUE_ID);
1556
                        return FALSE;
1557
                    case ERROR_INTEGER_VALUE_OUT_OF_RANGE:
1558
                        $error = ustrprocess(get_html_resource(RES_ALERT_INTEGER_VALUE_OUT_OF_RANGE_ID), 1, MAX_FIELD_MULTILINED);
1559
                        return FALSE;
1560
                    default:
1561
                        debug_write_log(DEBUG_WARNING, '[fields_import] Field validation failure (multilined).');
1562
                        $error = get_html_resource(RES_ALERT_UNKNOWN_ERROR_ID);
1563
                        return FALSE;
1564
                }
1565
            }
1566
1567
            // Validate field (check).
1568
            elseif ($field_type == FIELD_TYPE_CHECKBOX)
1569
            {
1570
                $default = ($field['default'] == 'on') ? 1 : 0;
1571
            }
1572
1573
            // Validate field (list).
1574
            elseif ($field_type == FIELD_TYPE_LIST)
1575
            {
1576
                $default = (ustrlen($field['default']) == 0)
1577
                         ? NULL
1578
                         : ustr2int($field['default'], 1, MAXINT);
1579
            }
1580
1581
            // Validate field (record).
1582
            elseif ($field_type == FIELD_TYPE_RECORD)
1583
            {
1584
                // nop
1585
            }
1586
1587
            // Validate field (date).
1588
            elseif ($field_type == FIELD_TYPE_DATE)
1589
            {
1590
                $param1  = ustrcut($field['minimum'], ustrlen(MIN_FIELD_DATE));
1591
                $param2  = ustrcut($field['maximum'], ustrlen(MIN_FIELD_DATE));
1592
                $default = ustrcut($field['default'], ustrlen(MIN_FIELD_DATE));
1593
1594
                $default = (ustrlen($default) == 0) ? NULL : $default;
1595
1596
                switch (field_validate_date($field_name, $param1, $param2, $default))
1597
                {
1598
                    case NO_ERROR:
1599
                        $default = is_null($default) ? NULL : ustr2int($default, MIN_FIELD_DATE, MAX_FIELD_DATE);
1600
                        break;  // nop
1601
                    case ERROR_INCOMPLETE_FORM:
1602
                        $error = get_html_resource(RES_ALERT_REQUIRED_ARE_EMPTY_ID);
1603
                        return FALSE;
1604
                    case ERROR_INVALID_DATE_VALUE:
1605
                        $error = get_html_resource(RES_ALERT_INVALID_DATE_VALUE_ID);
1606
                        return FALSE;
1607
                    case ERROR_DATE_VALUE_OUT_OF_RANGE:
1608
                        $error = ustrprocess(get_html_resource(RES_ALERT_DATE_VALUE_OUT_OF_RANGE_ID), MIN_FIELD_DATE, MAX_FIELD_DATE);
1609
                        return FALSE;
1610
                    case ERROR_MIN_MAX_VALUES:
1611
                        $error = get_html_resource(RES_ALERT_MIN_MAX_VALUES_ID);
1612
                        return FALSE;
1613
                    case ERROR_DEFAULT_VALUE_OUT_OF_RANGE:
1614
                        $error = ustrprocess(get_html_resource(RES_ALERT_DEFAULT_VALUE_OUT_OF_RANGE_ID), $param1, $param2);
1615
                        return FALSE;
1616
                    default:
1617
                        debug_write_log(DEBUG_WARNING, '[fields_import] Field validation failure (date).');
1618
                        $error = get_html_resource(RES_ALERT_UNKNOWN_ERROR_ID);
1619
                        return FALSE;
1620
                }
1621
            }
1622
1623
            // Validate field (duration).
1624
            elseif ($field_type == FIELD_TYPE_DURATION)
1625
            {
1626
                $param1  = ustrcut($field['minimum'], ustrlen(time2ustr(MAX_FIELD_DURATION)));
1627
                $param2  = ustrcut($field['maximum'], ustrlen(time2ustr(MAX_FIELD_DURATION)));
1628
                $default = ustrcut($field['default'], ustrlen(time2ustr(MAX_FIELD_DURATION)));
1629
1630
                $default = (ustrlen($default) == 0) ? NULL : $default;
1631
1632 View Code Duplication
                switch (field_validate_duration($field_name, $param1, $param2, $default))
1633
                {
1634
                    case NO_ERROR:
1635
                        $param1  = ustr2time($param1);
1636
                        $param2  = ustr2time($param2);
1637
                        $default = is_null($default) ? NULL : ustr2time($default);
1638
                        break;  // nop
1639
                    case ERROR_INCOMPLETE_FORM:
1640
                        $error = get_html_resource(RES_ALERT_REQUIRED_ARE_EMPTY_ID);
1641
                        return FALSE;
1642
                    case ERROR_INVALID_TIME_VALUE:
1643
                        $error = get_html_resource(RES_ALERT_INVALID_TIME_VALUE_ID);
1644
                        return FALSE;
1645
                    case ERROR_TIME_VALUE_OUT_OF_RANGE:
1646
                        $error = ustrprocess(get_html_resource(RES_ALERT_TIME_VALUE_OUT_OF_RANGE_ID), time2ustr(MIN_FIELD_DURATION), time2ustr(MAX_FIELD_DURATION));
1647
                        return FALSE;
1648
                    case ERROR_MIN_MAX_VALUES:
1649
                        $error = get_html_resource(RES_ALERT_MIN_MAX_VALUES_ID);
1650
                        return FALSE;
1651
                    case ERROR_DEFAULT_VALUE_OUT_OF_RANGE:
1652
                        $error = ustrprocess(get_html_resource(RES_ALERT_DEFAULT_VALUE_OUT_OF_RANGE_ID), $param1, $param2);
1653
                        return FALSE;
1654
                    default:
1655
                        debug_write_log(DEBUG_WARNING, '[fields_import] Field validation failure (duration).');
1656
                        $error = get_html_resource(RES_ALERT_UNKNOWN_ERROR_ID);
1657
                        return FALSE;
1658
                }
1659
            }
1660
1661
            // Create field.
1662
            switch (field_create($template_id,
1663
                                 $state_id,
1664
                                 $field_name,
1665
                                 $field_type,
1666
                                 $is_required,
1667
                                 $add_separator,
1668
                                 $guest_access,
1669
                                 $show_in_emails,
1670
                                 $description,
1671
                                 $regex_check,
1672
                                 $regex_search,
1673
                                 $regex_replace,
1674
                                 $param1,
1675
                                 $param2,
1676
                                 $default))
1677
            {
1678
                case NO_ERROR:
1679
                    break;  // nop
1680
                case ERROR_INCOMPLETE_FORM:
1681
                    $error = get_html_resource(RES_ALERT_REQUIRED_ARE_EMPTY_ID);
1682
                    return FALSE;
1683
                case ERROR_ALREADY_EXISTS:
1684
                    $error = get_html_resource(RES_ALERT_FIELD_ALREADY_EXISTS_ID);
1685
                    return FALSE;
1686
                default:
1687
                    debug_write_log(DEBUG_WARNING, '[fields_import] Field validation failure.');
1688
                    $error = get_html_resource(RES_ALERT_UNKNOWN_ERROR_ID);
1689
                    return FALSE;
1690
            }
1691
1692
            $rs = dal_query('fields/fndk.sql', $state_id, ustrtolower($field_name));
1693
1694 View Code Duplication
            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...
1695
            {
1696
                debug_write_log(DEBUG_WARNING, '[fields_import] Created field not found.');
1697
                $error = get_html_resource(RES_ALERT_UNKNOWN_ERROR_ID);
1698
                return FALSE;
1699
            }
1700
1701
            $row        = $rs->fetch();
1702
            $project_id = $row['project_id'];
1703
            $field_id   = $row['field_id'];
1704
1705
            // Create list items fpr list field.
1706
            if ($field_type == FIELD_TYPE_LIST)
1707
            {
1708
                $list = $field->xpath('./list/item');
1709
1710
                if ($list !== FALSE)
1711
                {
1712
                    $list_items = NULL;
1713
1714
                    foreach ($list as $item)
1715
                    {
1716
                        $list_items .= sprintf("%s %s\n", $item['value'], $item);
1717
                    }
1718
1719
                    field_create_list_items($state_id, $field_name, $list_items);
1720
                }
1721
            }
1722
1723
            // Set author permissions.
1724 View Code Duplication
            if (isset($field->permissions->author))
1725
            {
1726
                if ($field->permissions->author == 'read')
1727
                {
1728
                    field_author_permission_set($field_id, FIELD_ALLOW_TO_READ);
1729
                }
1730
                elseif ($field->permissions->author == 'write')
1731
                {
1732
                    field_author_permission_set($field_id, FIELD_ALLOW_TO_WRITE);
1733
                }
1734
            }
1735
1736
            // Set responsible permissions.
1737 View Code Duplication
            if (isset($field->permissions->responsible))
1738
            {
1739
                if ($field->permissions->responsible == 'read')
1740
                {
1741
                    field_responsible_permission_set($field_id, FIELD_ALLOW_TO_READ);
1742
                }
1743
                elseif ($field->permissions->responsible == 'write')
1744
                {
1745
                    field_responsible_permission_set($field_id, FIELD_ALLOW_TO_WRITE);
1746
                }
1747
            }
1748
1749
            // Set registered permissions.
1750 View Code Duplication
            if (isset($field->permissions->registered))
1751
            {
1752
                if ($field->permissions->registered == 'read')
1753
                {
1754
                    field_registered_permission_set($field_id, FIELD_ALLOW_TO_READ);
1755
                }
1756
                elseif ($field->permissions->registered == 'write')
1757
                {
1758
                    field_registered_permission_set($field_id, FIELD_ALLOW_TO_WRITE);
1759
                }
1760
            }
1761
1762
            // Remove default field permissions.
1763
            dal_query('fields/fpdelall.sql', $field_id);
1764
1765
            // Enumerate groups permissions.
1766
            $groups = $field->xpath('./permissions/group');
1767
1768
            if ($groups !== FALSE)
1769
            {
1770
                foreach ($groups as $group)
1771
                {
1772
                    $rs = dal_query('groups/fndk.sql',
1773
                                    $group['type'] == 'global' ? 'is null' : '=' . $project_id,
1774
                                    ustrtolower(ustrcut($group['name'], MAX_GROUP_NAME)));
1775
1776
                    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...
1777
                    {
1778
                        $group_id = $rs->fetch('group_id');
1779
1780
                        // Set group permissions.
1781
                        if (strval($group) == 'read')
1782
                        {
1783
                            field_permission_add($field_id, $group_id, FIELD_ALLOW_TO_READ);
1784
                        }
1785
                        elseif (strval($group) == 'write')
1786
                        {
1787
                            field_permission_add($field_id, $group_id, FIELD_ALLOW_TO_READ);
1788
                            field_permission_add($field_id, $group_id, FIELD_ALLOW_TO_WRITE);
1789
                        }
1790
                    }
1791
                }
1792
            }
1793
        }
1794
    }
1795
1796
    return TRUE;
1797
}
1798
1799
?>
1800