GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — master ( 99ec42...de979d )
by Robbie
9s
created

WorkflowService::executeTransition()   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 25
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 25
rs 8.5806
c 0
b 0
f 0
cc 4
eloc 14
nc 4
nop 2
1
<?php
2
3
namespace Symbiote\AdvancedWorkflow\Services;
4
5
use Exception;
6
use SilverStripe\Core\ClassInfo;
7
use SilverStripe\ORM\ArrayList;
8
use SilverStripe\ORM\DataList;
9
use SilverStripe\ORM\DataObject;
10
use SilverStripe\Security\Member;
11
use SilverStripe\Security\Permission;
12
use SilverStripe\Security\PermissionProvider;
13
use Symbiote\AdvancedWorkflow\Admin\WorkflowDefinitionImporter;
14
use Symbiote\AdvancedWorkflow\Extensions\FileWorkflowApplicable;
15
use Symbiote\AdvancedWorkflow\Extensions\WorkflowApplicable;
16
use Symbiote\AdvancedWorkflow\DataObjects\WorkflowAction;
17
use Symbiote\AdvancedWorkflow\DataObjects\WorkflowDefinition;
18
use Symbiote\AdvancedWorkflow\DataObjects\WorkflowInstance;
19
use Symbiote\AdvancedWorkflow\DataObjects\WorkflowTransition;
20
21
/**
22
 * A central point for interacting with workflows
23
 *
24
 * @author  [email protected]
25
 * @license BSD License (http://silverstripe.org/bsd-license/)
26
 * @package advancedworkflow
27
 */
28
29
class WorkflowService implements PermissionProvider
30
{
31
    /**
32
     * An array of templates that we can create from
33
     *
34
     * @var array
35
     */
36
    protected $templates;
37
38
    /**
39
     * Set the list of templates that can be created
40
     *
41
     * @param array $templates
42
     */
43
    public function setTemplates($templates)
44
    {
45
        $this->templates = $templates;
46
    }
47
48
    /**
49
     * Return the list of available templates
50
     * @return array
51
     */
52
    public function getTemplates()
53
    {
54
        return $this->templates;
55
    }
56
57
    /**
58
     * Get a template by name
59
     *
60
     * @param string $name
61
     * @return WorkflowTemplate|null
62
     */
63
    public function getNamedTemplate($name)
64
    {
65
        if ($importedTemplate = singleton(WorkflowDefinitionImporter::class)->getImportedWorkflows($name)) {
66
            return $importedTemplate;
67
        }
68
69
        if (!is_array($this->templates)) {
70
            return;
71
        }
72
        foreach ($this->templates as $template) {
73
            if ($template->getName() == $name) {
74
                return $template;
75
            }
76
        }
77
    }
78
79
    /**
80
     * Gets the workflow definition for a given dataobject, if there is one
81
     *
82
     * Will recursively query parent elements until it finds one, if available
83
     *
84
     * @param DataObject $dataObject
85
     */
86
    public function getDefinitionFor(DataObject $dataObject)
87
    {
88
        if ($dataObject->hasExtension(WorkflowApplicable::class)
89
            || $dataObject->hasExtension(FileWorkflowApplicable::class)
90
        ) {
91
            if ($dataObject->WorkflowDefinitionID) {
92
                return DataObject::get_by_id(WorkflowDefinition::class, $dataObject->WorkflowDefinitionID);
93
            }
94
            if ($dataObject->hasMethod('useInheritedWorkflow') && !$dataObject->useInheritedWorkflow()) {
95
                return null;
96
            }
97
            if ($dataObject->ParentID) {
98
                return $this->getDefinitionFor($dataObject->Parent());
99
            }
100
            if ($dataObject->hasMethod('workflowParent')) {
101
                $obj = $dataObject->workflowParent();
102
                if ($obj) {
103
                    return $this->getDefinitionFor($obj);
104
                }
105
            }
106
        }
107
        return null;
108
    }
109
110
    /**
111
     *  Retrieves a workflow definition by ID for a data object.
112
     *
113
     *  @param DataObject $object
114
     *  @param integer $workflowID
115
     *  @return WorkflowDefinition|null
116
     */
117
    public function getDefinitionByID($object, $workflowID)
118
    {
119
        // Make sure the correct extensions have been applied to the data object.
120
121
        $workflow = null;
122
        if ($object->hasExtension(WorkflowApplicable::class)
123
            || $object->hasExtension(FileWorkflowApplicable::class)
124
        ) {
125
            // Validate the workflow ID against the data object.
126
127
            if (($object->WorkflowDefinitionID == $workflowID)
128
                || ($workflow = $object->AdditionalWorkflowDefinitions()->byID($workflowID))
129
            ) {
130
                if (is_null($workflow)) {
131
                    $workflow = DataObject::get_by_id(WorkflowDefinition::class, $workflowID);
132
                }
133
            }
134
        }
135
        return $workflow ? $workflow : null;
136
    }
137
138
    /**
139
     * Retrieves and collates the workflow definitions for a data object, where the first element will be the
140
     * main workflow definition.
141
     *
142
     * @param DataObject object
143
     * @return array
144
     */
145
146
    public function getDefinitionsFor($object)
147
    {
148
149
        // Retrieve the main workflow definition.
150
151
        $default = $this->getDefinitionFor($object);
152
        if ($default) {
153
            // Merge the additional workflow definitions.
154
155
            return array_merge(array(
156
                $default
157
            ), $object->AdditionalWorkflowDefinitions()->toArray());
158
        }
159
        return null;
160
    }
161
162
    /**
163
     * Gets the workflow for the given item
164
     *
165
     * The item can be
166
     *
167
     * a data object in which case the ActiveWorkflow will be returned,
168
     * an action, in which case the Workflow will be returned
169
     * an integer, in which case the workflow with that ID will be returned
170
     *
171
     * @param mixed $item
172
     * @param bool $includeComplete
173
     * @return WorkflowInstance|null
174
     */
175
    public function getWorkflowFor($item, $includeComplete = false)
176
    {
177
        $id = $item;
0 ignored issues
show
Unused Code introduced by
$id is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
178
179
        if ($item instanceof WorkflowAction) {
180
            $id = $item->WorkflowID;
0 ignored issues
show
Documentation introduced by
The property WorkflowID does not exist on object<Symbiote\Advanced...Objects\WorkflowAction>. Since you implemented __set, maybe consider adding a @property annotation.

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...
181
            return DataObject::get_by_id(WorkflowInstance::class, $id);
182
        } elseif (is_object($item) && ($item->hasExtension(WorkflowApplicable::class)
183
                || $item->hasExtension(FileWorkflowApplicable::class))
184
        ) {
185
            $filter = sprintf('"TargetClass" = \'%s\' AND "TargetID" = %d', ClassInfo::baseDataClass($item), $item->ID);
0 ignored issues
show
Deprecated Code introduced by
The method SilverStripe\Core\ClassInfo::baseDataClass() has been deprecated with message: 4.0..5.0

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
186
            $complete = $includeComplete ? 'OR "WorkflowStatus" = \'Complete\' ' : '';
187
            return DataObject::get_one(
188
                WorkflowInstance::class,
189
                $filter . ' AND ("WorkflowStatus" = \'Active\' OR "WorkflowStatus"=\'Paused\' ' . $complete . ')'
190
            );
191
        }
192
    }
193
194
    /**
195
     * Get all the workflow action instances for an item
196
     *
197
     * @return DataList|null
198
     */
199
    public function getWorkflowHistoryFor($item, $limit = null)
200
    {
201
        if ($active = $this->getWorkflowFor($item, true)) {
202
            $limit = $limit ? "0,$limit" : '';
203
            return $active->Actions('', 'ID DESC ', null, $limit);
0 ignored issues
show
Bug introduced by
The method Actions() does not exist on SilverStripe\ORM\DataObject. Did you maybe mean getCMSActions()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
204
        }
205
    }
206
207
    /**
208
     * Get all the available workflow definitions
209
     *
210
     * @return DataList
211
     */
212
    public function getDefinitions()
213
    {
214
        return DataList::create(WorkflowDefinition::class);
215
    }
216
217
    /**
218
     * Given a transition ID, figure out what should happen to
219
     * the given $subject.
220
     *
221
     * In the normal case, this will load the current workflow instance for the object
222
     * and then transition as expected. However, in some cases (eg to start the workflow)
223
     * it is necessary to instead create a new instance.
224
     *
225
     * @param DataObject $target
226
     * @param int $transitionId
227
     * @throws Exception
228
     */
229
    public function executeTransition(DataObject $target, $transitionId)
230
    {
231
        $workflow   = $this->getWorkflowFor($target);
232
        $transition = DataObject::get_by_id(WorkflowTransition::class, $transitionId);
233
234
        if (!$transition) {
235
            throw new Exception(_t('WorkflowService.INVALID_TRANSITION_ID', "Invalid transition ID $transitionId"));
236
        }
237
238
        if (!$workflow) {
239
            throw new Exception(_t(
240
                'WorkflowService.INVALID_WORKFLOW_TARGET',
241
                "A transition was executed on a target that does not have a workflow."
242
            ));
243
        }
244
245
        if ($transition->Action()->WorkflowDefID != $workflow->DefinitionID) {
0 ignored issues
show
Bug introduced by
The method Action() does not exist on SilverStripe\ORM\DataObject. Did you maybe mean getCMSActions()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
246
            throw new Exception(_t(
247
                'WorkflowService.INVALID_TRANSITION_WORKFLOW',
248
                "Transition #$transition->ID is not attached to workflow #$workflow->ID."
249
            ));
250
        }
251
252
        $workflow->performTransition($transition);
253
    }
254
255
    /**
256
     * Starts the workflow for the given data object, assuming it or a parent has
257
     * a definition specified.
258
     *
259
     * @param DataObject $object
260
     * @param int $workflowID
261
     */
262
    public function startWorkflow(DataObject $object, $workflowID = null)
263
    {
264
        $existing = $this->getWorkflowFor($object);
265
        if ($existing) {
266
            throw new ExistingWorkflowException(_t(
267
                'WorkflowService.EXISTING_WORKFLOW_ERROR',
268
                "That object already has a workflow running"
269
            ));
270
        }
271
272
        $definition = null;
273
        if ($workflowID) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $workflowID of type integer|null is loosely compared to true; this is ambiguous if the integer can be zero. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
274
            // Retrieve the workflow definition that has been triggered.
275
276
            $definition = $this->getDefinitionByID($object, $workflowID);
277
        }
278
        if (is_null($definition)) {
279
            // Fall back to the main workflow definition.
280
281
            $definition = $this->getDefinitionFor($object);
282
        }
283
284
        if ($definition) {
285
            $instance = new WorkflowInstance();
286
            $instance->beginWorkflow($definition, $object);
287
            $instance->execute();
288
        }
289
    }
290
291
    /**
292
     * Get all the workflows that this user is responsible for
293
     *
294
     * @param Member $user The user to get workflows for
295
     * @return ArrayList The list of workflow instances this user owns
296
     */
297
    public function usersWorkflows(Member $user)
298
    {
299
300
        $groupIds = $user->Groups()->column('ID');
301
302
        $groupInstances = null;
303
304
        $filter = array('');
0 ignored issues
show
Unused Code introduced by
$filter is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
305
306
        if (is_array($groupIds)) {
307
            $groupInstances = DataList::create(WorkflowInstance::class)
308
                ->filter(array('Group.ID:ExactMatchMulti' => $groupIds))
309
                ->where('"WorkflowStatus" != \'Complete\'');
310
        }
311
312
        $userInstances = DataList::create(WorkflowInstance::class)
313
            ->filter(array('Users.ID:ExactMatch' => $user->ID))
314
            ->where('"WorkflowStatus" != \'Complete\'');
315
316
        if ($userInstances) {
317
            $userInstances = $userInstances->toArray();
318
        } else {
319
            $userInstances = array();
320
        }
321
322
        if ($groupInstances) {
323
            $groupInstances = $groupInstances->toArray();
324
        } else {
325
            $groupInstances = array();
326
        }
327
328
        $all = array_merge($groupInstances, $userInstances);
329
330
        return ArrayList::create($all);
331
    }
332
333
    /**
334
     * Get items that the passed-in user has awaiting for them to action
335
     *
336
     * @param Member $member
0 ignored issues
show
Bug introduced by
There is no parameter named $member. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
337
     * @return DataList
338
     */
339
    public function userPendingItems(Member $user)
340
    {
341
        // Don't restrict anything for ADMIN users
342
        $userInstances = DataList::create(WorkflowInstance::class)
343
            ->where('"WorkflowStatus" != \'Complete\'')
344
            ->sort('LastEdited DESC');
345
346
        if (Permission::checkMember($user, 'ADMIN')) {
347
            return $userInstances;
348
        }
349
        $instances = new ArrayList();
350
        foreach ($userInstances as $inst) {
351
            $instToArray = $inst->getAssignedMembers();
352
            if (!count($instToArray)>0 || !in_array($user->ID, $instToArray->column())) {
353
                continue;
354
            }
355
            $instances->push($inst);
356
        }
357
358
        return $instances;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $instances; (SilverStripe\ORM\ArrayList) is incompatible with the return type documented by Symbiote\AdvancedWorkflo...rvice::userPendingItems of type SilverStripe\ORM\DataList.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
359
    }
360
361
    /**
362
     * Get items that the passed-in user has submitted for workflow review
363
     *
364
     * @param Member $member
0 ignored issues
show
Bug introduced by
There is no parameter named $member. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
365
     * @return DataList
366
     */
367
    public function userSubmittedItems(Member $user)
368
    {
369
        $userInstances = DataList::create(WorkflowInstance::class)
370
            ->where('"WorkflowStatus" != \'Complete\'')
371
            ->sort('LastEdited DESC');
372
373
        // Restrict the user if they're not an ADMIN.
374
        if (!Permission::checkMember($user, 'ADMIN')) {
375
            $userInstances = $userInstances->filter('InitiatorID:ExactMatch', $user->ID);
376
        }
377
378
        return $userInstances;
379
    }
380
381
    /**
382
     * Generate a workflow definition based on a template
383
     *
384
     * @param WorkflowDefinition $definition
385
     * @param string $templateName
386
     * @return WorkflowDefinition|null
387
     */
388
    public function defineFromTemplate(WorkflowDefinition $definition, $templateName)
389
    {
390
        $template = null;
0 ignored issues
show
Unused Code introduced by
$template is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
391
        /* @var $template WorkflowTemplate */
392
393
        if (!is_array($this->templates)) {
394
            return;
395
        }
396
397
        $template = $this->getNamedTemplate($templateName);
398
399
        if (!$template) {
400
            return;
401
        }
402
403
        $template->createRelations($definition);
404
405
        // Set the version and do the write at the end so that we don't trigger an infinite loop!!
406
        if (!$definition->Description) {
0 ignored issues
show
Documentation introduced by
The property Description does not exist on object<Symbiote\Advanced...cts\WorkflowDefinition>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read 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.");
        }
    }

}

If the property has read access only, you can use the @property-read 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...
407
            $definition->Description = $template->getDescription();
0 ignored issues
show
Documentation introduced by
The property Description does not exist on object<Symbiote\Advanced...cts\WorkflowDefinition>. Since you implemented __set, maybe consider adding a @property annotation.

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...
408
        }
409
        $definition->TemplateVersion = $template->getVersion();
0 ignored issues
show
Documentation introduced by
The property TemplateVersion does not exist on object<Symbiote\Advanced...cts\WorkflowDefinition>. Since you implemented __set, maybe consider adding a @property annotation.

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...
410
        $definition->RemindDays = $template->getRemindDays();
0 ignored issues
show
Documentation introduced by
The property RemindDays does not exist on object<Symbiote\Advanced...cts\WorkflowDefinition>. Since you implemented __set, maybe consider adding a @property annotation.

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...
411
        $definition->Sort = $template->getSort();
0 ignored issues
show
Documentation introduced by
The property Sort does not exist on object<Symbiote\Advanced...cts\WorkflowDefinition>. Since you implemented __set, maybe consider adding a @property annotation.

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...
412
        $definition->write();
413
        return $definition;
414
    }
415
416
    /**
417
     * Reorders actions within a definition
418
     *
419
     * @param WorkflowDefinition|WorkflowAction $objects The objects to be reordered
420
     * @param array $newOrder An array of IDs of the actions in the order they should be.
421
     */
422
    public function reorder($objects, $newOrder)
423
    {
424
        $sortVals = array_values($objects->map('ID', 'Sort')->toArray());
425
        sort($sortVals);
426
427
        // save the new ID values - but only use existing sort values to prevent
428
        // conflicts with items not in the table
429
        foreach ($newOrder as $key => $id) {
430
            if (!$id) {
431
                continue;
432
            }
433
            $object = $objects->find('ID', $id);
434
            $object->Sort = $sortVals[$key];
435
            $object->write();
436
        }
437
    }
438
439
    /**
440
     *
441
     * @return array
442
     */
443
    public function providePermissions()
444
    {
445
        return array(
446
            'CREATE_WORKFLOW' => array(
447
                'name' => _t('AdvancedWorkflow.CREATE_WORKFLOW', 'Create workflow'),
448
                'category' => _t('AdvancedWorkflow.ADVANCED_WORKFLOW', 'Advanced Workflow'),
449
                'help' => _t('AdvancedWorkflow.CREATE_WORKFLOW_HELP', 'Users can create workflow definitions'),
450
                'sort' => 0
451
            ),
452
            'DELETE_WORKFLOW' => array(
453
                'name' => _t('AdvancedWorkflow.DELETE_WORKFLOW', 'Delete workflow'),
454
                'category' => _t('AdvancedWorkflow.ADVANCED_WORKFLOW', 'Advanced Workflow'),
455
                'help' => _t(
456
                    'AdvancedWorkflow.DELETE_WORKFLOW_HELP',
457
                    'Users can delete workflow definitions and active workflows'
458
                ),
459
                'sort' => 1
460
            ),
461
            'APPLY_WORKFLOW' => array(
462
                'name' => _t('AdvancedWorkflow.APPLY_WORKFLOW', 'Apply workflow'),
463
                'category' => _t('AdvancedWorkflow.ADVANCED_WORKFLOW', 'Advanced Workflow'),
464
                'help' => _t('AdvancedWorkflow.APPLY_WORKFLOW_HELP', 'Users can apply workflows to items'),
465
                'sort' => 2
466
            ),
467
            'VIEW_ACTIVE_WORKFLOWS' => array(
468
                'name'     => _t('AdvancedWorkflow.VIEWACTIVE', 'View active workflows'),
469
                'category' => _t('AdvancedWorkflow.ADVANCED_WORKFLOW', 'Advanced Workflow'),
470
                'help'     => _t(
471
                    'AdvancedWorkflow.VIEWACTIVEHELP',
472
                    'Users can view active workflows via the workflows admin panel'
473
                ),
474
                'sort'     => 3
475
            ),
476
            'REASSIGN_ACTIVE_WORKFLOWS' => array(
477
                'name'     => _t('AdvancedWorkflow.REASSIGNACTIVE', 'Reassign active workflows'),
478
                'category' => _t('AdvancedWorkflow.ADVANCED_WORKFLOW', 'Advanced Workflow'),
479
                'help'     => _t(
480
                    'AdvancedWorkflow.REASSIGNACTIVEHELP',
481
                    'Users can reassign active workflows to different users and groups'
482
                ),
483
                'sort'     => 4
484
            ),
485
            'EDIT_EMBARGOED_WORKFLOW' => array(
486
                'name'     => _t('AdvancedWorkflow.EDITEMBARGO', 'Editable embargoed item in workflow'),
487
                'category' => _t('AdvancedWorkflow.ADVANCED_WORKFLOW', 'Advanced Workflow'),
488
                'help'     => _t(
489
                    'AdvancedWorkflow.EDITEMBARGOHELP',
490
                    'Allow users to edit items that have been embargoed by a workflow'
491
                ),
492
                'sort'     => 5
493
            ),
494
        );
495
    }
496
}
497