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/states.php (36 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
 * States
25
 *
26
 * This module provides API to work with eTraxis states.
27
 * See also {@link https://github.com/etraxis/etraxis-obsolete/wiki/tbl_states tbl_states} database table.
28
 *
29
 * @package DBO
30
 * @subpackage States
31
 */
32
33
/**#@+
34
 * Dependency.
35
 */
36
require_once('../engine/engine.php');
37
require_once('../dbo/fields.php');
38
/**#@-*/
39
40
//------------------------------------------------------------------------------
41
//  Definitions.
42
//------------------------------------------------------------------------------
43
44
/**#@+
45
 * Data restriction.
46
 */
47
define('MAX_STATE_NAME', 50);
48
define('MAX_STATE_ABBR', 50);
49
/**#@-*/
50
51
/**#@+
52
 * State type.
53
 */
54
define('STATE_TYPE_INITIAL',      1);
55
define('STATE_TYPE_INTERMEDIATE', 2);
56
define('STATE_TYPE_FINAL',        3);
57
/**#@-*/
58
59
// State type resources.
60
$state_type_res = array
61
(
62
    STATE_TYPE_INITIAL      => RES_INITIAL_ID,
63
    STATE_TYPE_INTERMEDIATE => RES_INTERMEDIATE_ID,
64
    STATE_TYPE_FINAL        => RES_FINAL_ID,
65
);
66
67
/**#@+
68
 * State responsibility.
69
 */
70
define('STATE_RESPONSIBLE_REMAIN', 1);
71
define('STATE_RESPONSIBLE_ASSIGN', 2);
72
define('STATE_RESPONSIBLE_REMOVE', 3);
73
/**#@-*/
74
75
// State responsibility resources.
76
$state_responsible_res = array
77
(
78
    STATE_RESPONSIBLE_REMAIN => RES_REMAIN_ID,
79
    STATE_RESPONSIBLE_ASSIGN => RES_ASSIGN_ID,
80
    STATE_RESPONSIBLE_REMOVE => RES_REMOVE_ID,
81
);
82
83
/**#@+
84
 * State role.
85
 */
86
define('STATE_ROLE_AUTHOR',      -1);
87
define('STATE_ROLE_RESPONSIBLE', -2);
88
define('STATE_ROLE_REGISTERED',  -3);
89
define('MIN_STATE_ROLE', STATE_ROLE_REGISTERED);
90
/**#@-*/
91
92
//------------------------------------------------------------------------------
93
//  Functions.
94
//------------------------------------------------------------------------------
95
96
/**
97
 * Finds in database and returns the information about specified state.
98
 *
99
 * @param int $id State ID.
100
 * @return array Array with data if template is found in database, FALSE otherwise.
101
 */
102
function state_find ($id)
103
{
104
    debug_write_log(DEBUG_TRACE, '[state_find]');
105
    debug_write_log(DEBUG_DUMP,  '[state_find] $id = ' . $id);
106
107
    $rs = dal_query('states/fndid.sql', $id);
108
109
    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...
110
}
111
112
/**
113
 * Returns {@link CRecordset DAL recordset} which contains all existing states of specified template,
114
 * sorted in accordance with current sort mode.
115
 *
116
 * @param int $id Template ID.
117
 * @param int &$sort Sort mode (used as output only). The function retrieves current sort mode from
118
 * client cookie ({@link COOKIE_STATES_SORT}) and updates it, if it's out of valid range.
119
 * @param int &$page Number of current page tab (used as output only). The function retrieves current
120
 * page from client cookie ({@link COOKIE_STATES_PAGE}) and updates it, if it's out of valid range.
121
 * @return CRecordset Recordset with list of states.
122
 */
123 View Code Duplication
function states_list ($id, &$sort, &$page)
0 ignored issues
show
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
124
{
125
    debug_write_log(DEBUG_TRACE, '[states_list]');
126
    debug_write_log(DEBUG_DUMP,  '[states_list] $id = ' . $id);
127
128
    $sort_modes = array
129
    (
130
        1  => 'state_name asc',
131
        2  => 'state_abbr asc',
132
        3  => 'state_type asc, state_name asc',
133
        4  => 'responsible asc, state_name asc',
134
        5  => 'next_state asc, state_name asc',
135
        6  => 'state_name desc',
136
        7  => 'state_abbr desc',
137
        8  => 'state_type desc, state_name desc',
138
        9  => 'responsible desc, state_name desc',
139
        10 => 'next_state desc, state_name desc',
140
    );
141
142
    $sort = try_request('sort', try_cookie(COOKIE_STATES_SORT, 3));
143
    $sort = ustr2int($sort, 1, count($sort_modes));
144
145
    $page = try_request('page', try_cookie(COOKIE_STATES_PAGE));
146
    $page = ustr2int($page, 1, MAXINT);
147
148
    save_cookie(COOKIE_STATES_SORT, $sort);
149
    save_cookie(COOKIE_STATES_PAGE, $page);
150
151
    return dal_query('states/list.sql', $id, $sort_modes[$sort]);
152
}
153
154
/**
155
 * Validates state information before creation or modification.
156
 *
157
 * @param string $state_name State name.
158
 * @param string $state_abbr State abbreviation.
159
 * @return int Error code:
160
 * <ul>
161
 * <li>{@link NO_ERROR} - data are valid</li>
162
 * <li>{@link ERROR_INCOMPLETE_FORM} - at least one of required field is empty</li>
163
 * </ul>
164
 */
165 View Code Duplication
function state_validate ($state_name, $state_abbr)
0 ignored issues
show
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
166
{
167
    debug_write_log(DEBUG_TRACE, '[state_validate]');
168
    debug_write_log(DEBUG_DUMP,  '[state_validate] $state_name = ' . $state_name);
169
    debug_write_log(DEBUG_DUMP,  '[state_validate] $state_abbr = ' . $state_abbr);
170
171
    if (ustrlen($state_name) == 0 ||
172
        ustrlen($state_abbr) == 0)
173
    {
174
        debug_write_log(DEBUG_NOTICE, '[state_validate] At least one required field is empty.');
175
        return ERROR_INCOMPLETE_FORM;
176
    }
177
178
    return NO_ERROR;
179
}
180
181
/**
182
 * Creates new state.
183
 *
184
 * @param int $template_id ID of template which new state will belong to.
185
 * @param string $state_name State name.
186
 * @param string $state_abbr State abbreviation.
187
 * @param int $state_type Type of state.
188
 * @param int $next_state_id ID of state, which should be next by default in this dataflow (NULL by default).
189
 * @param int $responsible State responsibility ({@STATE_RESPONSIBLE_REMOVE} by default).
190
 * @return int Error code:
191
 * <ul>
192
 * <li>{@link NO_ERROR} - state is successfully created</li>
193
 * <li>{@link ERROR_ALREADY_EXISTS} - state with specified name or abbreviation already exists</li>
194
 * <li>{@link ERROR_NOT_FOUND} - failure on attempt to create state</li>
195
 * </ul>
196
 */
197
function state_create ($template_id, $state_name, $state_abbr, $state_type, $next_state_id = NULL, $responsible = STATE_RESPONSIBLE_REMOVE)
198
{
199
    debug_write_log(DEBUG_TRACE, '[state_create]');
200
    debug_write_log(DEBUG_DUMP,  '[state_create] $template_id   = ' . $template_id);
201
    debug_write_log(DEBUG_DUMP,  '[state_create] $state_name    = ' . $state_name);
202
    debug_write_log(DEBUG_DUMP,  '[state_create] $state_abbr    = ' . $state_abbr);
203
    debug_write_log(DEBUG_DUMP,  '[state_create] $state_type    = ' . $state_type);
204
    debug_write_log(DEBUG_DUMP,  '[state_create] $next_state_id = ' . $next_state_id);
205
    debug_write_log(DEBUG_DUMP,  '[state_create] $responsible   = ' . $responsible);
206
207
    // Check that there is no state with the same name or abbreviation in the specified template.
208
    $rs = dal_query('states/fndk.sql', $template_id, ustrtolower($state_name), ustrtolower($state_abbr));
209
210
    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...
211
    {
212
        debug_write_log(DEBUG_NOTICE, '[state_create] State already exists.');
213
        return ERROR_ALREADY_EXISTS;
214
    }
215
216
    // Create a state.
217
    dal_query('states/create.sql',
218
              $template_id,
219
              $state_name,
220
              $state_abbr,
221
              $state_type,
222
              is_null($next_state_id) ? NULL : $next_state_id,
223
              $responsible);
224
225
    $rs = dal_query('states/fndk.sql', $template_id, ustrtolower($state_name), ustrtolower($state_abbr));
226
227
    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...
228
    {
229
        debug_write_log(DEBUG_NOTICE, '[state_create] State cannot be found.');
230
        return ERROR_NOT_FOUND;
231
    }
232
233
    return NO_ERROR;
234
}
235
236
/**
237
 * Modifies specified state.
238
 *
239
 * @param int $id ID of state to be modified.
240
 * @param int $template_id ID of template which the state belongs to.
241
 * @param string $state_old_name Current state name.
242
 * @param string $state_new_name New state name.
243
 * @param string $state_abbr New state abbreviation.
244
 * @param int $next_state_id New ID of state, which will be next by default in this dataflow.
245
 * @param int $responsible New state responsibility.
246
 * @return int Error code:
247
 * <ul>
248
 * <li>{@link NO_ERROR} - state is successfully modified</li>
249
 * <li>{@link ERROR_ALREADY_EXISTS} - state with specified name or abbreviation already exists</li>
250
 * </ul>
251
 */
252
function state_modify ($id, $template_id, $state_old_name, $state_new_name, $state_abbr, $next_state_id, $responsible)
253
{
254
    debug_write_log(DEBUG_TRACE, '[state_modify]');
255
    debug_write_log(DEBUG_DUMP,  '[state_modify] $id             = ' . $id);
256
    debug_write_log(DEBUG_DUMP,  '[state_modify] $template_id    = ' . $template_id);
257
    debug_write_log(DEBUG_DUMP,  '[state_modify] $state_old_name = ' . $state_old_name);
258
    debug_write_log(DEBUG_DUMP,  '[state_modify] $state_new_name = ' . $state_new_name);
259
    debug_write_log(DEBUG_DUMP,  '[state_modify] $state_abbr     = ' . $state_abbr);
260
    debug_write_log(DEBUG_DUMP,  '[state_modify] $next_state_id  = ' . $next_state_id);
261
    debug_write_log(DEBUG_DUMP,  '[state_modify] $responsible    = ' . $responsible);
262
263
    // Check that there is no state with the same name or abbreviation, besides this one.
264
    $rs = dal_query('states/fndku.sql', $id, $template_id, ustrtolower($state_new_name), ustrtolower($state_abbr));
265
266
    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...
267
    {
268
        debug_write_log(DEBUG_NOTICE, '[state_modify] State already exists.');
269
        return ERROR_ALREADY_EXISTS;
270
    }
271
272
    // Update existing views.
273
    dal_query('states/views.sql',
274
              $state_old_name,
275
              $state_new_name);
276
277
    // Modify the state.
278
    dal_query('states/modify.sql',
279
              $id,
280
              $state_new_name,
281
              $state_abbr,
282
              is_null($next_state_id) ? NULL : $next_state_id,
283
              $responsible);
284
285
    return NO_ERROR;
286
}
287
288
/**
289
 * Checks whether state can be deleted.
290
 *
291
 * @param int $id ID of state to be deleted.
292
 * @return bool TRUE if state can be deleted, FALSE otherwise.
293
 */
294
function is_state_removable ($id)
295
{
296
    debug_write_log(DEBUG_TRACE, '[is_state_removable]');
297
    debug_write_log(DEBUG_DUMP,  '[is_state_removable] $id = ' . $id);
298
299
    $rs = dal_query('states/efndc.sql', $id);
300
301
    return ($rs->fetch(0) == 0);
302
}
303
304
/**
305
 * Deletes specified state.
306
 *
307
 * @param int $id ID of state to be deleted.
308
 * @return int Always {@link NO_ERROR}.
309
 */
310 View Code Duplication
function state_delete ($id)
0 ignored issues
show
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
311
{
312
    debug_write_log(DEBUG_TRACE, '[state_delete]');
313
    debug_write_log(DEBUG_DUMP,  '[state_delete] $id = ' . $id);
314
315
    dal_query('filters/fadelalls.sql', $id);
316
    dal_query('filters/fdelalls.sql',  $id);
317
318
    dal_query('states/rdelall.sql',  $id);
319
    dal_query('states/ftdelall.sql', $id);
320
    dal_query('states/fsdelall.sql', $id);
321
    dal_query('states/lvdelall.sql', $id);
322
    dal_query('states/fpdelall.sql', $id);
323
    dal_query('states/fdelall.sql',  $id);
324
    dal_query('states/gtdelall.sql', $id);
325
    dal_query('states/rtdelall.sql', $id);
326
    dal_query('states/sadelall.sql', $id);
327
    dal_query('states/clrdef.sql',   $id);
328
    dal_query('states/delete.sql',   $id);
329
330
    return NO_ERROR;
331
}
332
333
/**
334
 * Marks specified state as initial in its dataflow.
335
 *
336
 * @param int $template_id ID of template which the state belongs to.
337
 * @param int $state_id ID of state to be made initial.
338
 * @return int Always {@link NO_ERROR}.
339
 */
340
function state_set_initial ($template_id, $state_id)
341
{
342
    debug_write_log(DEBUG_TRACE, '[state_set_initial]');
343
    debug_write_log(DEBUG_DUMP,  '[state_set_initial] $template_id = ' . $template_id);
344
    debug_write_log(DEBUG_DUMP,  '[state_set_initial] $state_id    = ' . $state_id);
345
346
    dal_query('states/clrinit.sql', $template_id);
347
    dal_query('states/setinit.sql', $template_id, $state_id);
348
349
    return NO_ERROR;
350
}
351
352
/**
353
 * Exports all states of the specified template to XML code (see also {@link template_export}).
354
 *
355
 * @param int $id ID of template, which states should be exported.
356
 * @param array &$groups Array of IDs of groups, affected by this template (used for output only).
357
 * @return string Generated XML code.
358
 */
359
function state_export ($id, &$groups)
360
{
361
    debug_write_log(DEBUG_TRACE, '[state_export]');
362
    debug_write_log(DEBUG_DUMP,  '[state_export] $id = ' . $id);
363
364
    // Allocation of state types to XML code.
365
    $state_type = array
366
    (
367
        STATE_TYPE_INITIAL      => 'initial',
368
        STATE_TYPE_INTERMEDIATE => 'intermed',
369
        STATE_TYPE_FINAL        => 'final',
370
    );
371
372
    // Allocation of state responsibility to XML code.
373
    $state_resp = array
374
    (
375
        STATE_RESPONSIBLE_REMAIN => 'remain',
376
        STATE_RESPONSIBLE_ASSIGN => 'assign',
377
        STATE_RESPONSIBLE_REMOVE => 'remove',
378
    );
379
380
    $xml = "    <states>\n";
381
382
    // List all states of the template.
383
    $rs = dal_query('states/list2.sql', $id);
384
385
    // Add XML code for each found state.
386
    while (($state = $rs->fetch()))
387
    {
388
        // Add XML code for general state information.
389
        $xml .= sprintf("      <state name=\"%s\" abbr=\"%s\" type=\"%s\" responsible=\"%s\"",
390
                        ustr2html($state['state_name']),
391
                        ustr2html($state['state_abbr']),
392
                        $state_type[$state['state_type']],
393
                        $state_resp[$state['responsible']]);
394
395
        // Add XML code for "next state by default", if such information is specified for the state.
396
        $xml .= (is_null($state['next_state']) ? ">\n" : " next=\"" . ustr2html($state['next_state']) . "\">\n");
397
398
        // If state must be assigned, enumerate groups of allowed responsibles.
399
        if ($state['responsible'] == STATE_RESPONSIBLE_ASSIGN)
400
        {
401
            $rsr = dal_query('states/saallowed.sql', $state['state_id']);
402
403
            if ($rsr->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...
404
            {
405
                $xml .= "        <responsibles>\n";
406
407
                while (($row = $rsr->fetch()))
408
                {
409
                    $xml .= sprintf("          <group type=\"%s\">%s</group>\n",
410
                                    ($row['is_global'] ? 'global' : 'local'),
411
                                    ustr2html($row['group_name']));
412
                }
413
414
                $xml .= "        </responsibles>\n";
415
            }
416
        }
417
418
        // If state is not final, enumerate all possible transition from this state.
419
        if ($state['state_type'] != STATE_TYPE_FINAL)
420
        {
421
            $xml .= "        <transitions>\n";
422
423
            // List all transitions for system role "author".
424
            $rst = dal_query('states/rtlist2.sql', $state['state_id'], STATE_ROLE_AUTHOR);
425
426 View Code Duplication
            if ($rst->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...
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
427
            {
428
                $xml .= "          <author>\n";
429
430
                while (($next = $rst->fetch()))
431
                {
432
                    $xml .= "            <state>" . ustr2html($next['state_name']) . "</state>\n";
433
                }
434
435
                $xml .= "          </author>\n";
436
            }
437
438
            // List all transitions for system role "responsible".
439
            $rst = dal_query('states/rtlist2.sql', $state['state_id'], STATE_ROLE_RESPONSIBLE);
440
441 View Code Duplication
            if ($rst->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...
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
442
            {
443
                $xml .= "          <responsible>\n";
444
445
                while (($next = $rst->fetch()))
446
                {
447
                    $xml .= "            <state>" . ustr2html($next['state_name']) . "</state>\n";
448
                }
449
450
                $xml .= "          </responsible>\n";
451
            }
452
453
            // List all transitions for system role "registered".
454
            $rst = dal_query('states/rtlist2.sql', $state['state_id'], STATE_ROLE_REGISTERED);
455
456 View Code Duplication
            if ($rst->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...
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
457
            {
458
                $xml .= "          <registered>\n";
459
460
                while (($next = $rst->fetch()))
461
                {
462
                    $xml .= "            <state>" . ustr2html($next['state_name']) . "</state>\n";
463
                }
464
465
                $xml .= "          </registered>\n";
466
            }
467
468
            // Enumerate local groups of the same project and all global groups.
469
            $rsg = dal_query('groups/list.sql', $state['project_id'], 'is_global, group_name');
470
471
            while (($group = $rsg->fetch()))
472
            {
473
                // List all transitions for this group.
474
                $rst = dal_query('states/gtlist2.sql', $state['state_id'], $group['group_id']);
475
476
                if ($rst->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...
477
                {
478
                    // Save ID of processed group for future reference.
479
                    array_push($groups, $group['group_id']);
480
481
                    // Add XML code for group name and type.
482
                    $xml .= sprintf("          <group name=\"%s\" type=\"%s\">\n",
483
                                    ustr2html($group['group_name']),
484
                                    (is_null($group['project_id']) ? 'global' : 'local'));
485
486
                    // Add XML code for transition information.
487
                    while (($next = $rst->fetch()))
488
                    {
489
                        $xml .= "            <state>" . ustr2html($next['state_name']) . "</state>\n";
490
                    }
491
492
                    $xml .= "          </group>\n";
493
                }
494
            }
495
496
            $xml .= "        </transitions>\n";
497
        }
498
499
        // Export all existing fields of the state.
500
        $xml .= field_export($state['state_id'], $groups);
501
        $xml .= "      </state>\n";
502
    }
503
504
    $xml .= "    </states>\n";
505
506
    return $xml;
507
}
508
509
/**
510
 * Imports states described as XML code into the specified template.
511
 *
512
 * @param int $template_id ID of destination template.
513
 * @param string $xml Valid XML code.
514
 * @param string &$error In case of failure - the error message (used as output only).
515
 * @return bool Whether the import was successful.
516
 */
517
function states_import ($template_id, $xml, &$error)
518
{
519
    debug_write_log(DEBUG_TRACE, '[states_import]');
520
    debug_write_log(DEBUG_DUMP,  '[states_import] $template_id = ' . $template_id);
521
522
    // Allocation of XML code to state types.
523
    $state_type = array
524
    (
525
        'initial'  => STATE_TYPE_INITIAL,
526
        'intermed' => STATE_TYPE_INTERMEDIATE,
527
        'final'    => STATE_TYPE_FINAL,
528
    );
529
530
    // Allocation of XML code to state responsibility.
531
    $state_resp = array
532
    (
533
        'remain' => STATE_RESPONSIBLE_REMAIN,
534
        'assign' => STATE_RESPONSIBLE_ASSIGN,
535
        'remove' => STATE_RESPONSIBLE_REMOVE,
536
    );
537
538
    // Enumerate states.
539
    $states = $xml->xpath('./states/state');
0 ignored issues
show
The method xpath cannot be called on $xml (of type string).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
540
541
    if ($states !== FALSE)
542
    {
543
        // Create all states before setting transitions btw them.
544
        foreach ($states as $state)
545
        {
546
            $state['name'] = ustrcut($state['name'], MAX_STATE_NAME);
547
            $state['abbr'] = ustrcut($state['abbr'], MAX_STATE_ABBR);
548
549
            // Validate state.
550 View Code Duplication
            switch (state_validate($state['name'], $state['abbr']))
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
551
            {
552
                case NO_ERROR:
553
                    break;  // nop
554
                case ERROR_INCOMPLETE_FORM:
555
                    $error = get_html_resource(RES_ALERT_REQUIRED_ARE_EMPTY_ID);
556
                    return FALSE;
557
                default:
558
                    debug_write_log(DEBUG_WARNING, '[states_import] State validation failure.');
559
                    $error = get_html_resource(RES_ALERT_UNKNOWN_ERROR_ID);
560
                    return FALSE;
561
            }
562
563
            $type        = strval($state['type']);
564
            $responsible = strval($state['responsible']);
565
566
            if (!array_key_exists($type, $state_type))
567
            {
568
                $type = 'intermed';
569
            }
570
571
            if (!array_key_exists($responsible, $state_resp))
572
            {
573
                $responsible = 'remain';
574
            }
575
576
            // Create state.
577
            switch (state_create($template_id,
578
                                 $state['name'],
579
                                 $state['abbr'],
580
                                 $state_type[$type],
581
                                 NULL,
582
                                 $state_resp[$responsible]))
583
            {
584
                case NO_ERROR:
585
                    break;  // nop
586
                case ERROR_ALREADY_EXISTS:
587
                    $error = get_html_resource(RES_ALERT_STATE_ALREADY_EXISTS_ID);
588
                    return FALSE;
589
                default:
590
                    debug_write_log(DEBUG_WARNING, '[states_import] State creation failure.');
591
                    $error = get_html_resource(RES_ALERT_UNKNOWN_ERROR_ID);
592
                    return FALSE;
593
            }
594
        }
595
596
        // Set up rest of the stuff on already created states.
597
        foreach ($states as $state)
598
        {
599
            $state['name'] = ustrcut($state['name'], MAX_STATE_NAME);
600
601
            // Find the state.
602
            $rs = dal_query('states/fndk2.sql', $template_id, ustrtolower($state['name']));
603
604 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...
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
605
            {
606
                debug_write_log(DEBUG_WARNING, '[states_import] Created state not found.');
607
                $error = get_html_resource(RES_ALERT_UNKNOWN_ERROR_ID);
608
                return FALSE;
609
            }
610
611
            $row        = $rs->fetch();
612
            $project_id = $row['project_id'];
613
            $state_id   = $row['state_id'];
614
615
            // Set author transitions.
616
            $transitions = $state->xpath('./transitions/author/state');
0 ignored issues
show
The method xpath cannot be called on $state (of type array<string,string,{"name":"string"}>).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
617
618 View Code Duplication
            if ($transitions !== FALSE)
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
619
            {
620
                foreach ($transitions as $transit)
621
                {
622
                    $rs = dal_query('states/fndk2.sql', $template_id, ustrtolower(ustrcut($transit, MAX_STATE_NAME)));
623
624
                    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...
625
                    {
626
                        dal_query('states/rtadd.sql', $state_id, $rs->fetch('state_id'), STATE_ROLE_AUTHOR);
627
                    }
628
                }
629
            }
630
631
            // Set responsible transitions.
632
            $transitions = $state->xpath('./transitions/responsible/state');
0 ignored issues
show
The method xpath cannot be called on $state (of type array<string,string,{"name":"string"}>).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
633
634 View Code Duplication
            if ($transitions !== FALSE)
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
635
            {
636
                foreach ($transitions as $transit)
637
                {
638
                    $rs = dal_query('states/fndk2.sql', $template_id, ustrtolower(ustrcut($transit, MAX_STATE_NAME)));
639
640
                    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...
641
                    {
642
                        dal_query('states/rtadd.sql', $state_id, $rs->fetch('state_id'), STATE_ROLE_RESPONSIBLE);
643
                    }
644
                }
645
            }
646
647
            // Set registered transitions.
648
            $transitions = $state->xpath('./transitions/registered/state');
0 ignored issues
show
The method xpath cannot be called on $state (of type array<string,string,{"name":"string"}>).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
649
650 View Code Duplication
            if ($transitions !== FALSE)
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
651
            {
652
                foreach ($transitions as $transit)
653
                {
654
                    $rs = dal_query('states/fndk2.sql', $template_id, ustrtolower(ustrcut($transit, MAX_STATE_NAME)));
655
656
                    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...
657
                    {
658
                        dal_query('states/rtadd.sql', $state_id, $rs->fetch('state_id'), STATE_ROLE_REGISTERED);
659
                    }
660
                }
661
            }
662
663
            // Enumerate groups transitions.
664
            $groups = $state->xpath('./transitions/group');
0 ignored issues
show
The method xpath cannot be called on $state (of type array<string,string,{"name":"string"}>).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
665
666
            if ($groups !== FALSE)
667
            {
668
                foreach ($groups as $group)
669
                {
670
                    // Set group transitions.
671
                    if (isset($group->state))
672
                    {
673
                        $rs = dal_query('groups/fndk.sql',
674
                                        $group['type'] == 'global' ? 'is null' : '=' . $project_id,
675
                                        ustrtolower(ustrcut($group['name'], MAX_GROUP_NAME)));
676
677
                        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...
678
                        {
679
                            $group_id = $rs->fetch('group_id');
680
681
                            foreach ($group->state as $transit)
682
                            {
683
                                $rs = dal_query('states/fndk2.sql', $template_id, ustrtolower(ustrcut($transit, MAX_STATE_NAME)));
684
685
                                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...
686
                                {
687
                                    dal_query('states/gtadd.sql', $state_id, $rs->fetch('state_id'), $group_id);
688
                                }
689
                            }
690
                        }
691
                    }
692
                }
693
            }
694
695
            // Set groups of allowed responsibles.
696
            if (strval($state['responsible']) == 'assign')
697
            {
698
                $groups = $state->xpath('./responsibles/group');
0 ignored issues
show
The method xpath cannot be called on $state (of type array<string,string,{"name":"string"}>).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
699
700
                if ($groups !== FALSE)
701
                {
702
                    foreach ($groups as $group)
703
                    {
704
                        $rs = dal_query('groups/fndk.sql',
705
                                        $group['type'] == 'global' ? 'is null' : '=' . $project_id,
706
                                        ustrtolower(ustrcut($group, MAX_GROUP_NAME)));
707
708
                        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...
709
                        {
710
                            dal_query('states/saadd.sql', $state_id, $rs->fetch('group_id'));
711
                        }
712
                    }
713
                }
714
            }
715
716
            // Set "Next by default" where it's specified.
717
            if (isset($state['next']))
718
            {
719
                $rs = dal_query('states/fndk2.sql', $template_id, ustrtolower(ustrcut($state['next'], MAX_STATE_NAME)));
720
721
                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...
722
                {
723
                    dal_query('states/setnext.sql', $state_id, $rs->fetch('state_id'));
724
                }
725
            }
726
727
            // Import fields.
728
            if (!fields_import($template_id, $state_id, $state, $error))
0 ignored issues
show
$state is of type array<string,string|null...,"next":"string|null"}>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
729
            {
730
                return FALSE;
731
            }
732
        }
733
    }
734
735
    return TRUE;
736
}
737
738
?>
0 ignored issues
show
It is not recommended to use PHP's closing tag ?> in files other than templates.

Using a closing tag in PHP files that only contain PHP code is not recommended as you might accidentally add whitespace after the closing tag which would then be output by PHP. This can cause severe problems, for example headers cannot be sent anymore.

A simple precaution is to leave off the closing tag as it is not required, and it also has no negative effects whatsoever.

Loading history...
739