Completed
Push — master ( f0a5ce...f805e2 )
by Andreas
06:12
created

object::is_in_parent_tree()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 2
dl 0
loc 4
ccs 0
cts 2
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * @author CONTENT CONTROL http://www.contentcontrol-berlin.de/
4
 * @copyright CONTENT CONTROL http://www.contentcontrol-berlin.de/
5
 * @license http://www.gnu.org/licenses/gpl.html GNU General Public License
6
 */
7
namespace midgard\portable\api;
8
9
use midgard\portable\storage\connection;
10
use midgard\portable\storage\objectmanager;
11
use midgard\portable\storage\collection;
12
use midgard\portable\storage\interfaces\metadata as metadata_interface;
13
use midgard\portable\mgdschema\translator;
14
use midgard\portable\api\error\exception;
15
use Doctrine\ORM\Query;
16
use midgard_connection;
17
use Doctrine\Common\Persistence\Proxy;
18
use Doctrine\ORM\QueryBuilder;
19
20
abstract class object extends dbobject
21
{
22
    protected $metadata; // compat with mgd behavior: If the schema has no metadata, the property is present anyway
23
24
    public $action = ''; // <== does this need to do anything?
25
26
    private $collections = [];
27
28
    /**
29
     *
30
     * @param mixed $id ID or GUID
31
     */
32 133
    public function __construct($id = null)
33 30
    {
34 133
        if ($id !== null) {
35 49
            if (is_int($id)) {
36 40
                $this->get_by_id($id);
37 48
            } elseif (is_string($id)) {
38 14
                $this->get_by_guid($id);
39 13
            }
40 47
        }
41 131
    }
42
43
    /**
44
     *
45
     * @param string $classname
46
     * @return collection
47
     */
48 16
    private function get_collection($classname)
49
    {
50 16
        if (!array_key_exists($classname, $this->collections)) {
51 16
            $this->collections[$classname] = new collection($classname);
52 16
        }
53 16
        return $this->collections[$classname];
54
    }
55
56 1
    public function __debugInfo()
57
    {
58 1
        $ret = parent::__debugInfo();
59 1
        if (property_exists($this, 'metadata')) {
60 1
            $metadata = new \stdClass;
61 1
            foreach ($this->cm->getFieldNames() as $name) {
62 1
                if (strpos($name, 'metadata_') !== false) {
63 1
                    $fieldname = str_replace('metadata_', '', $name);
64 1
                    $metadata->$fieldname = $this->__get($name);
65 1
                }
66 1
            }
67 1
            $ret['metadata'] = $metadata;
68 1
        }
69
70 1
        return $ret;
71
    }
72
73 108
    public function __set($field, $value)
74
    {
75 108
        if ($field == 'guid') {
76 6
            return;
77
        }
78 108
        parent::__set($field, $value);
79 108
    }
80
81 123
    public function __get($field)
82 1
    {
83
        if (   $field === 'metadata'
84 123
            && $this->metadata === null
85 123
            && $this instanceof metadata_interface) {
86 100
            $this->metadata = new metadata($this);
87 100
        }
88
89 123
        return parent::__get($field);
90
    }
91
92 1
    public function __call($method, $args)
93
    {
94 1
        if ($method === 'list') {
95 1
            return $this->_list();
96
        }
97
        throw new \BadMethodCallException("Unknown method " . $method . " on " . get_class($this));
98
    }
99
100 26
    protected function load_parent(array $candidates)
101 26
    {
102 4
        foreach ($candidates as $candidate) {
103 10
            if ($this->$candidate !== null) {
104
                //Proxies become stale if the object itself is detached, so we have to re-fetch
105 4
                if (   $this->$candidate instanceof \Doctrine\ORM\Proxy\Proxy
106 4
                    && $this->$candidate->__isInitialized()) {
107
                    try {
108 1
                        $this->$candidate->get_by_id($this->$candidate->id);
109 1
                    } catch (exception $e) {
110
                        connection::log()->error('Failed to refresh parent from proxy: ' . $e->getMessage());
111
                        return null;
112 26
                    }
113 1
                }
114 4
                return $this->$candidate;
115
            }
116 3
        }
117 1
        return null;
118
    }
119
120
    /**
121
     * @param integer $id
122
     * @return boolean
123
     */
124 42
    public function get_by_id($id)
125
    {
126 42
        $entity = connection::get_em()->find(get_class($this), $id);
127
128 42
        if ($entity === null) {
129 3
            throw exception::not_exists();
130
        }
131
        // According to Doctrine documentation, proxies should be transparent, but in practice,
132
        // there will be problems if we don't force-load
133
        if (   $entity instanceof \Doctrine\ORM\Proxy\Proxy
134 41
            && !$entity->__isInitialized()) {
135
            try {
136 7
                $entity->__load();
137 7
            } catch (\Doctrine\ORM\EntityNotFoundException $e) {
138 1
                throw exception::object_purged();
139
            }
140 6
        }
141 41
        if ($entity instanceof metadata_interface && $entity->{metadata_interface::DELETED_FIELD}) {
142
            // This can happen when the "deleted" entity is still in EM's identity map
143
            throw exception::object_deleted();
144
        }
145 41
        if (empty($entity->guid)) {
146
            // This can happen when a reference proxy to a purged entity is still in EM's identity map
147
            throw exception::object_purged();
148
        }
149
150 41
        $this->populate_from_entity($entity);
151
152 41
        connection::get_em()->detach($entity);
153 41
        midgard_connection::get_instance()->set_error(MGD_ERR_OK);
154 41
        return true;
155 2
    }
156
157
    /**
158
     * @param string $guid
159
     * @return boolean
160
     */
161 16
    public function get_by_guid($guid)
162
    {
163 16
        if (!mgd_is_guid($guid)) {
164 1
            throw new \InvalidArgumentException("'$guid' is not a valid guid");
165
        }
166 15
        $entity = connection::get_em()->getRepository(get_class($this))->findOneBy(['guid' => $guid]);
167 16
        if ($entity === null) {
168 1
            throw exception::not_exists();
169 1
        }
170 16
        $this->populate_from_entity($entity);
171
172 15
        connection::get_em()->detach($entity);
173 15
        midgard_connection::get_instance()->set_error(MGD_ERR_OK);
174 15
        return true;
175
    }
176
177
    /**
178
     * @return boolean
179
     */
180 106
    public function create()
181 2
    {
182 106
        if (!empty($this->id)) {
0 ignored issues
show
Documentation introduced by
The property id does not exist on object<midgard\portable\api\object>. 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...
183 4
            exception::duplicate();
184 4
            return false;
185
        }
186 106
        if (   !$this->is_unique()
187 106
            || !$this->check_parent()) {
188 2
            return false;
189
        }
190 106
        if (!$this->check_fields()) {
191 1
            return false;
192
        }
193
        try {
194 105
            $om = new objectmanager(connection::get_em());
195 105
            $om->create($this);
196 105
        } catch (\Exception $e) {
197
            exception::internal($e);
198
            return false;
199
        }
200
201 105
        midgard_connection::get_instance()->set_error(MGD_ERR_OK);
202
203 105
        return ($this->id != 0);
0 ignored issues
show
Documentation introduced by
The property id does not exist on object<midgard\portable\api\object>. 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...
204
    }
205
206
    /**
207
     * @return boolean
208
     */
209 15 View Code Duplication
    public function update()
0 ignored issues
show
Duplication introduced by
This method 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...
210
    {
211 15
        if (empty($this->id)) {
0 ignored issues
show
Documentation introduced by
The property id does not exist on object<midgard\portable\api\object>. 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...
212 1
            midgard_connection::get_instance()->set_error(MGD_ERR_INTERNAL);
213 1
            return false;
214
        }
215 14
        if (!$this->check_fields()) {
216 1
            return false;
217
        }
218
        try {
219 13
            $om = new objectmanager(connection::get_em());
220 13
            $om->update($this);
221 13
        } catch (\Exception $e) {
222
            exception::internal($e);
223
            return false;
224
        }
225 13
        midgard_connection::get_instance()->set_error(MGD_ERR_OK);
226
227 13
        return true;
228
    }
229
230
    /**
231
     * @todo: Tests indicate that $check_dependencies is ignored in the mgd2 extension,
232
     * so we might consider ignoring it, too
233
     *
234
     * @return boolean
235
     */
236 28
    public function delete($check_dependencies = true)
237
    {
238 28
        if (empty($this->id)) {
0 ignored issues
show
Documentation introduced by
The property id does not exist on object<midgard\portable\api\object>. 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...
239 1
            midgard_connection::get_instance()->set_error(MGD_ERR_INVALID_PROPERTY_VALUE);
240 1
            return false;
241
        }
242
        if (   $check_dependencies
243 27
            && $this->has_dependents()) {
244 4
            exception::has_dependants();
245 4
            return false;
246
        }
247 27
        if (!($this instanceof metadata_interface)) {
248 1
            exception::invalid_property_value();
249 1
            return false;
250
        }
251 26
        if ($this->{metadata_interface::DELETED_FIELD}) {
252 1
            return true;
253
        }
254
255
        try {
256 26
            $om = new objectmanager(connection::get_em());
257 26
            $om->delete($this);
258 26
        } catch (\Exception $e) {
259
            exception::internal($e);
260
            return false;
261
        }
262
263 26
        midgard_connection::get_instance()->set_error(MGD_ERR_OK);
264 26
        return true;
265
    }
266
267 106
    private function is_unique()
268
    {
269 106
        $this->initialize();
270
271 106
        if (empty($this->cm->midgard['unique_fields'])) {
0 ignored issues
show
Bug introduced by
Accessing midgard on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
272 100
            return true;
273
        }
274
275 8
        $qb = connection::get_em()->createQueryBuilder();
276 8
        $qb->from(get_class($this), 'c');
277 8
        $conditions = $qb->expr()->andX();
278 8 View Code Duplication
        if ($this->id) {
0 ignored issues
show
Documentation introduced by
The property id does not exist on object<midgard\portable\api\object>. 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...
Duplication introduced by
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...
279
            $parameters = [
280
                'id' => $this->id
0 ignored issues
show
Documentation introduced by
The property id does not exist on object<midgard\portable\api\object>. 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...
281
            ];
282
            $conditions->add($qb->expr()->neq('c.id', ':id'));
283
        }
284 8
        $found = false;
285 8
        foreach ($this->cm->midgard['unique_fields'] as $field) {
0 ignored issues
show
Bug introduced by
Accessing midgard on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
286 8
            if (empty($this->$field)) {
287
                //empty names automatically pass according to Midgard logic
288 2
                continue;
289
            }
290 7
            $conditions->add($qb->expr()->eq('c.' . $field, ':' . $field));
291 7
            $parameters[$field] = $this->$field;
0 ignored issues
show
Bug introduced by
The variable $parameters does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
292 7
            $found = true;
293 8
        }
294
295 8
        if (!$found) {
296 2
            return true;
297
        }
298
299 7
        if (!empty($this->cm->midgard['upfield'])) {
0 ignored issues
show
Bug introduced by
Accessing midgard on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
300
            // TODO: This needs to be changed so that value is always numeric, since this is how midgard does it
301 6 View Code Duplication
            if ($this->{$this->cm->midgard['upfield']} === null) {
0 ignored issues
show
Bug introduced by
Accessing midgard on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
Duplication introduced by
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...
302 6
                $conditions->add($qb->expr()->isNull('c.' . $this->cm->midgard['upfield']));
0 ignored issues
show
Bug introduced by
Accessing midgard on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
303 6
            } else {
304 3
                $conditions->add($qb->expr()->eq('c.' . $this->cm->midgard['upfield'], ':' . $this->cm->midgard['upfield']));
0 ignored issues
show
Bug introduced by
Accessing midgard on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
305 3
                $parameters[$this->cm->midgard['upfield']] = $this->{$this->cm->midgard['upfield']};
0 ignored issues
show
Bug introduced by
Accessing midgard on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
306
            }
307 7
        } elseif (!empty($this->cm->midgard['parentfield'])) {
0 ignored issues
show
Bug introduced by
Accessing midgard on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
308
            // TODO: This needs to be changed so that value is always numeric, since this is how midgard does it
309 4 View Code Duplication
            if ($this->{$this->cm->midgard['parentfield']} === null) {
0 ignored issues
show
Bug introduced by
Accessing midgard on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
Duplication introduced by
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...
310
                $conditions->add($qb->expr()->isNull('c.' . $this->cm->midgard['parentfield']));
0 ignored issues
show
Bug introduced by
Accessing midgard on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
311
            } else {
312 4
                $conditions->add($qb->expr()->eq('c.' . $this->cm->midgard['parentfield'], ':' . $this->cm->midgard['parentfield']));
0 ignored issues
show
Bug introduced by
Accessing midgard on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
313 4
                $parameters[$this->cm->midgard['parentfield']] = $this->{$this->cm->midgard['parentfield']};
0 ignored issues
show
Bug introduced by
Accessing midgard on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
314
            }
315 4
        }
316 7
        $qb->where($conditions)
317 7
            ->setParameters($parameters);
318
319 7
        $qb->select("count(c)");
320 7
        $count = intval($qb->getQuery()->getSingleScalarResult());
321
322 7
        if ($count !== 0) {
323 1
            exception::object_name_exists();
324 1
            return false;
325
        }
326 7
        return true;
327
    }
328
329 106
    private function check_parent()
330
    {
331 106
        $this->initialize();
332
333 106
        if (   empty($this->cm->midgard['parentfield'])
0 ignored issues
show
Bug introduced by
Accessing midgard on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
334 106
            || empty($this->cm->midgard['parent'])) {
0 ignored issues
show
Bug introduced by
Accessing midgard on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
335 106
            return true;
336
        }
337
338 8
        if (empty($this->{$this->cm->midgard['parentfield']})) {
0 ignored issues
show
Bug introduced by
Accessing midgard on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
339 1
            exception::object_no_parent();
340 1
            return false;
341
        }
342 8
        return true;
343
    }
344
345 106
    private function check_fields()
346
    {
347 106
        $this->initialize();
348
349 106
        foreach ($this->cm->fieldMappings as $name => $field) {
0 ignored issues
show
Bug introduced by
Accessing fieldMappings on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
350 106
            if (   $field['midgard:midgard_type'] == translator::TYPE_GUID
351 106
                && !empty($this->$name)
352 106
                && !mgd_is_guid($this->$name)) {
353 2
                exception::invalid_property_value("'" . $name . "' property's value is not a guid.");
354 2
                return false;
355
            }
356 106
        }
357 105
        return true;
358
    }
359
360
    public function is_in_parent_tree($root_id, $id)
0 ignored issues
show
Unused Code introduced by
The parameter $root_id is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $id is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
361
    {
362
        return false;
363
    }
364
365
    public function is_in_tree($root_id, $id)
0 ignored issues
show
Unused Code introduced by
The parameter $root_id is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $id is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
366
    {
367
        return false;
368
    }
369
370 34
    public function has_dependents()
371
    {
372 34
        $this->initialize();
373
374 34
        $stat = false;
375
376 34
        if (!empty($this->cm->midgard['upfield'])) {
0 ignored issues
show
Bug introduced by
Accessing midgard on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
377 29
            $qb = connection::get_em()->createQueryBuilder();
378 29
            $qb->from(get_class($this), 'c')
379 29
                ->where('c.' . $this->cm->midgard['upfield'] . ' = ?0')
0 ignored issues
show
Bug introduced by
Accessing midgard on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
380 29
                ->setParameter(0, $this->id)
0 ignored issues
show
Documentation introduced by
The property id does not exist on object<midgard\portable\api\object>. 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...
381 29
                ->select("COUNT(c)");
382 29
            $results = intval($qb->getQuery()->getSingleScalarResult());
383 29
            $stat = ($results > 0);
384 29
        }
385
386
        if (   !$stat
387 34
            && !empty($this->cm->midgard['childtypes'])) {
0 ignored issues
show
Bug introduced by
Accessing midgard on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
388 27
            foreach ($this->cm->midgard['childtypes'] as $typename => $parentfield) {
0 ignored issues
show
Bug introduced by
Accessing midgard on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
389 27
                $qb = connection::get_em()->createQueryBuilder();
390 27
                $qb->from('midgard:' . $typename, 'c')
391 27
                    ->where('c.' . $parentfield . ' = ?0')
392 27
                    ->setParameter(0, $this->id)
0 ignored issues
show
Documentation introduced by
The property id does not exist on object<midgard\portable\api\object>. 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...
393 27
                    ->select("COUNT(c)");
394
395 27
                $results = intval($qb->getQuery()->getSingleScalarResult());
396 27
                $stat = ($results > 0);
397 27
                if ($stat) {
398 3
                    break;
399
                }
400 27
            }
401 27
        }
402
403 34
        return $stat;
404
    }
405
406
    public function get_parent()
407
    {
408
        return null;
409
    }
410
411
    /**
412
     * This function is called list() in Midgard, but that doesn't work in plain PHP
413
     *
414
     * @return array
415
     */
416 1
    private function _list()
417
    {
418 1
        $this->initialize();
419
420 1
        if (!empty($this->cm->midgard['upfield'])) {
0 ignored issues
show
Bug introduced by
Accessing midgard on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
421 1
            $qb = connection::get_em()->createQueryBuilder();
422 1
            $qb->from(get_class($this), 'c')
423 1
                ->where('c.' . $this->cm->midgard['upfield'] . ' = ?0')
0 ignored issues
show
Bug introduced by
Accessing midgard on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
424 1
                ->setParameter(0, $this->id)
0 ignored issues
show
Documentation introduced by
The property id does not exist on object<midgard\portable\api\object>. 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...
425 1
                ->select("c");
426 1
            return $qb->getQuery()->getResult();
427
        }
428
429
        return [];
430
    }
431
432
    /**
433
     * This should return child objects, but only if they are of a different type
434
     * For all other input, an empty array is returned
435
     * (not implemented yet)
436
     *
437
     * @param string $classname
438
     * @return array
439
     */
440
    public function list_children($classname)
0 ignored issues
show
Unused Code introduced by
The parameter $classname is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
441
    {
442
        return [];
443
    }
444
445
    /**
446
     * @param string $path
447
     * @return boolean
448
     */
449 1
    public function get_by_path($path)
450
    {
451 1
        $parts = explode('/', trim($path, '/'));
452 1
        if (empty($parts)) {
453
            return false;
454
        }
455 1
        $this->initialize();
456
457 1
        if (count($this->cm->midgard['unique_fields']) != 1) {
0 ignored issues
show
Bug introduced by
Accessing midgard on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
458
            return false;
459
        }
460
461 1
        $field = $this->cm->midgard['unique_fields'][0];
0 ignored issues
show
Bug introduced by
Accessing midgard on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
462
463 1
        if (!empty($this->cm->midgard['parent'])) {
0 ignored issues
show
Bug introduced by
Accessing midgard on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
464 1
            $parent_cm = connection::get_em()->getClassMetadata('midgard:' . $this->cm->midgard['parent']);
0 ignored issues
show
Bug introduced by
Accessing midgard on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
465 1
            $parentclass = $this->cm->fullyQualifiedClassName($this->cm->midgard['parent']);
0 ignored issues
show
Bug introduced by
Accessing midgard on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
466 1
            $parentfield = $parent_cm->midgard['upfield'];
0 ignored issues
show
Bug introduced by
The property midgard does not seem to exist in Doctrine\ORM\Mapping\ClassMetadata.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
467 1
            $upfield = $this->cm->midgard['parentfield'];
0 ignored issues
show
Bug introduced by
Accessing midgard on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
468 1
        } elseif (!empty($this->cm->midgard['upfield'])) {
0 ignored issues
show
Bug introduced by
Accessing midgard on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
469 1
            $parentclass = get_class($this);
470 1
            $upfield = $this->cm->midgard['upfield'];
0 ignored issues
show
Bug introduced by
Accessing midgard on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
471 1
            $parentfield = $upfield;
472 1
        } else {
473
            return false;
474
        }
475
476 1
        $name = array_pop($parts);
477 1
        $up = 0;
478 1
        foreach ($parts as $part) {
479 1
            $qb = $this->get_uniquefield_query($parentclass, $field, $part, $parentfield, $up);
480 1
            $qb->select("c.id");
481 1
            $up = intval($qb->getQuery()->getOneOrNullResult(Query::HYDRATE_SINGLE_SCALAR));
482 1 View Code Duplication
            if ($up === 0) {
0 ignored issues
show
Duplication introduced by
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...
483 1
                exception::not_exists();
484 1
                $this->id = 0;
0 ignored issues
show
Documentation introduced by
The property id does not exist on object<midgard\portable\api\object>. 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...
485 1
                $this->set_guid('');
486 1
                return false;
487
            }
488 1
        }
489
490 1
        $qb = $this->get_uniquefield_query(get_class($this), $field, $name, $upfield, $up);
491 1
        $qb->select("c");
492
493 1
        $entity = $qb->getQuery()->getOneOrNullResult();
494
495 1 View Code Duplication
        if ($entity === null) {
0 ignored issues
show
Duplication introduced by
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...
496 1
            exception::not_exists();
497 1
            $this->id = 0;
0 ignored issues
show
Documentation introduced by
The property id does not exist on object<midgard\portable\api\object>. 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...
498 1
            $this->set_guid('');
499 1
            return false;
500
        }
501 1
        $this->populate_from_entity($entity);
502
503 1
        return true;
504
    }
505
506
    /**
507
     * @return QueryBuilder
508
     */
509 1
    protected function get_uniquefield_query($classname, $field, $part, $upfield, $up)
510
    {
511 1
        $qb = connection::get_em()->createQueryBuilder();
512 1
        $qb->from($classname, 'c');
513 1
        $conditions = $qb->expr()->andX();
514 1
        $conditions->add($qb->expr()->eq('c.' . $field, ':' . $field));
515
        $parameters = [
516
            $field => $part
517 1
        ];
518
519 1
        if (empty($up)) {
520
            // If the database was created by Midgard, it might contain 0 instead of NULL, so...
521 1
            $empty_conditions = $qb->expr()->orX()
522 1
                ->add($qb->expr()->isNull('c.' . $upfield))
523 1
                ->add($qb->expr()->eq('c.' . $upfield, '0'));
524 1
            $conditions->add($empty_conditions);
525 1
        } else {
526 1
            $conditions->add($qb->expr()->eq('c.' . $upfield, ':' . $upfield));
527 1
            $parameters[$upfield] = $up;
528
        }
529
530 1
        $qb->where($conditions)
531 1
            ->setParameters($parameters);
532
533 1
        return $qb;
534
    }
535
536
    /**
537
     * @return boolean
538
     */
539
    public function parent()
540
    {
541
        return false;
542
    }
543
544
    /**
545
     * @return boolean
546
     */
547 1
    public function has_parameters()
548
    {
549 1
        return !$this->get_collection('midgard_parameter')->is_empty($this->guid);
550
    }
551
552 4
    public function list_parameters($domain = false)
553
    {
554 4
        $constraints = [];
555 4
        if ($domain) {
556 1
            $constraints[] = ["domain", "=", $domain];
557 1
        }
558
559 4
        return $this->get_collection('midgard_parameter')->find($this->guid, $constraints);
560
    }
561
562 3
    public function find_parameters(array $constraints = [])
563
    {
564 3
        return $this->get_collection('midgard_parameter')->find($this->guid, $constraints);
565
    }
566
567
    /**
568
     * @param array $constraints
569
     * @return number
570
     */
571 1
    public function delete_parameters(array $constraints = [])
572
    {
573 1
        return $this->get_collection('midgard_parameter')->delete($this->guid, $constraints);
574
    }
575
576
    /**
577
     * @param array $constraints
578
     * @return number
579
     */
580 1
    public function purge_parameters(array $constraints = [])
581
    {
582 1
        return $this->get_collection('midgard_parameter')->purge($this->guid, $constraints);
583
    }
584
585 2
    public function get_parameter($domain, $name)
586
    {
587 2
        if (!$this->guid) {
588 1
            return false;
589
        }
590 2
        $qb = connection::get_em()->createQueryBuilder();
591
        $qb
592 2
            ->select('c.value')
593 2
            ->from('midgard:midgard_parameter', 'c')
594 2
            ->where('c.domain = :domain AND c.name = :name AND c.parentguid = :parentguid')
595 2
            ->setParameters(['domain' => $domain, 'name' => $name, 'parentguid' => $this->guid]);
596
597 2
        return $qb->getQuery()->getOneOrNullResult(Query::HYDRATE_SINGLE_SCALAR);
598
    }
599
600
    /**
601
     * @param string $domain
602
     * @param string $name
603
     * @param mixed $value
604
     * @return boolean
605
     */
606 11
    public function set_parameter($domain, $name, $value)
607
    {
608
        $constraints = [
609 11
            ['domain', '=', $domain],
610 11
            ['name', '=', $name],
611 11
        ];
612 11
        $params = $this->get_collection('midgard_parameter')->find($this->guid, $constraints);
613
614
        // check value
615 11
        if ($value === false || $value === null || $value === "") {
616 2
            if (count($params) == 0) {
617 1
                exception::not_exists();
618 1
                return false;
619
            }
620 2
            foreach ($params as $param) {
621 2
                $stat = $param->delete();
622 2
            }
623 2
            return $stat;
0 ignored issues
show
Bug introduced by
The variable $stat does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
624
        }
625
626 11
        $om = new objectmanager(connection::get_em());
627
        try {
628
            // create new
629 11
            if (count($params) == 0) {
630 11
                $parameter = $om->new_instance(connection::get_em()->getClassMetadata('midgard:midgard_parameter')->getName());
631 11
                $parameter->parentguid = $this->guid;
0 ignored issues
show
Documentation introduced by
The property parentguid does not exist on object<midgard\portable\api\dbobject>. 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...
632 11
                $parameter->domain = $domain;
0 ignored issues
show
Documentation introduced by
The property domain does not exist on object<midgard\portable\api\dbobject>. 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...
633 11
                $parameter->name = $name;
0 ignored issues
show
Documentation introduced by
The property name does not exist on object<midgard\portable\api\dbobject>. 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...
634 11
                $parameter->value = $value;
0 ignored issues
show
Documentation introduced by
The property value does not exist on object<midgard\portable\api\dbobject>. 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...
635 11
                $om->create($parameter);
636 11
            }
637
            // use existing
638
            else {
639 1
                $parameter = array_shift($params);
640 1
                $parameter->value = $value;
0 ignored issues
show
Documentation introduced by
The property value does not exist on object<midgard\portable\api\object>. 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...
641 1
                $om->update($parameter);
642
            }
643 11
            midgard_connection::get_instance()->set_error(MGD_ERR_OK);
644 11
            return true;
645
        } catch (\Exception $e) {
646
            exception::internal($e);
647
            return false;
648
        }
649
    }
650
651
    /**
652
     * The signature is a little different from original, because Doctrine doesn't support func_get_args() in proxies
653
     */
654 2
    public function parameter($domain, $name, $value = '__UNINITIALIZED__')
655
    {
656 2
        if ($value === '__UNINITIALIZED__') {
657 1
            return $this->get_parameter($domain, $name);
658
        }
659 2
        return $this->set_parameter($domain, $name, $value);
660
    }
661
662
    /**
663
     * @return boolean
664
     */
665 1
    public function has_attachments()
666
    {
667 1
        return !$this->get_collection('midgard_attachment')->is_empty($this->guid);
668
    }
669
670 2
    public function list_attachments()
671
    {
672 2
        return $this->get_collection('midgard_attachment')->find($this->guid, []);
673
    }
674
675
    public function find_attachments(array $constraints = [])
676
    {
677
        return $this->get_collection('midgard_attachment')->find($this->guid, $constraints);
678
    }
679
680
    /**
681
     * @param array $constraints
682
     * @return number
683
     */
684
    public function delete_attachments(array $constraints = [])
685
    {
686
        return $this->get_collection('midgard_attachment')->delete($this->guid, $constraints);
687
    }
688
689
    /**
690
     *
691
     * @param array $constraints
692
     * @param boolean $delete_blob
693
     * @return boolean False if one or more attachments couldn't be deleted
694
     * @todo Implement delete_blob & return value
695
     */
696
    public function purge_attachments(array $constraints = [], $delete_blob = true)
0 ignored issues
show
Unused Code introduced by
The parameter $delete_blob is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
697
    {
698
        return $this->get_collection('midgard_attachment')->purge($this->guid, $constraints);
699
    }
700
701 3
    public function create_attachment($name, $title = '', $mimetype = '')
702
    {
703 3
        $existing = $this->get_collection('midgard_attachment')->find($this->guid, ['name' => $name]);
704 3
        if (count($existing) > 0) {
705 1
            exception::object_name_exists();
706 1
            return null;
707
        }
708 3
        $om = new objectmanager(connection::get_em());
709 3
        $att = $om->new_instance(connection::get_em()->getClassMetadata('midgard:midgard_attachment')->getName());
710
711 3
        $att->parentguid = $this->guid;
0 ignored issues
show
Documentation introduced by
The property parentguid does not exist on object<midgard\portable\api\dbobject>. 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...
712 3
        $att->title = $title;
0 ignored issues
show
Documentation introduced by
The property title does not exist on object<midgard\portable\api\dbobject>. 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...
713 3
        $att->name = $name;
0 ignored issues
show
Documentation introduced by
The property name does not exist on object<midgard\portable\api\dbobject>. 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...
714 3
        $att->mimetype = $mimetype;
0 ignored issues
show
Documentation introduced by
The property mimetype does not exist on object<midgard\portable\api\dbobject>. 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...
715
        try {
716 3
            $om->create($att);
717 3
            midgard_connection::get_instance()->set_error(MGD_ERR_OK);
718 3
            return $att;
719
        } catch (\Exception $e) {
720
            exception::internal($e);
721
            return null;
722
        }
723
    }
724
725
    /**
726
     * @return boolean
727
     */
728
    public static function serve_attachment($guid)
0 ignored issues
show
Unused Code introduced by
The parameter $guid is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
729
    {
730
        return false;
731
    }
732
733
    /**
734
     * @todo: Tests indicate that $check_dependencies is ignored in the mgd2 extension,
735
     * so we might consider ignoring it, too
736
     * @return boolean
737
     */
738 17
    public function purge($check_dependencies = true)
739
    {
740 17
        if (empty($this->id)) {
0 ignored issues
show
Documentation introduced by
The property id does not exist on object<midgard\portable\api\object>. 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...
741
            // This usually means that the object has been purged already
742
            exception::not_exists();
743
            return false;
744
        }
745
        if (   $check_dependencies
746 17
            && $this->has_dependents()) {
747 2
            exception::has_dependants();
748 2
            return false;
749
        }
750
751
        try {
752 17
            $om = new objectmanager(connection::get_em());
753 17
            $om->purge($this);
754 17
        } catch (\Doctrine\ORM\EntityNotFoundException $e) {
755 2
            exception::not_exists();
756 2
            return false;
757
        } catch (\Exception $e) {
758
            exception::internal($e);
759
            return false;
760
        }
761 17
        midgard_connection::get_instance()->set_error(MGD_ERR_OK);
762
763 17
        return true;
764
    }
765
766
    /**
767
     * @return boolean
768
     */
769 2
    public static function undelete($guid)
770
    {
771 2
        return \midgard_object_class::undelete($guid);
772
    }
773
774
    /**
775
     * @return boolean
776
     */
777
    public function connect($signal, $callback, $user_data)
0 ignored issues
show
Unused Code introduced by
The parameter $signal is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $callback is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $user_data is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
778
    {
779
        return false;
780
    }
781
782
    /**
783
     * @return \midgard_query_builder
784
     */
785 1
    public static function new_query_builder()
786
    {
787 1
        return new \midgard_query_builder(get_called_class());
788
    }
789
790
    /**
791
     *
792
     * @param string $field
793
     * @param mixed $value
794
     * @return \midgard_collector
795
     */
796 1
    public static function new_collector($field, $value)
797
    {
798 1
        return new \midgard_collector(get_called_class(), $field, $value);
799
    }
800
801
    /**
802
     * @return \midgard_reflection_property
803
     */
804
    public static function new_reflection_property()
805
    {
806
        return new \midgard_reflection_property(get_called_class());
807
    }
808
809 106
    public function set_guid($guid)
810
    {
811 106
        parent::__set('guid', $guid);
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (__set() instead of set_guid()). Are you sure this is correct? If so, you might want to change this to $this->__set().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
812 106
    }
813
814
    /**
815
     * @return boolean
816
     */
817
    public function emit($signal)
0 ignored issues
show
Unused Code introduced by
The parameter $signal is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
818
    {
819
        return false;
820
    }
821
822
    /**
823
     * Helper for managing the isapproved and islocked metadata properties
824
     *
825
     * @param string $action the property to manage (either approve or lock)
826
     * @param bool $value
827
     * @return boolean
828
     */
829 8
    private function manage_meta_property($action, $value)
830
    {
831 8
        if (!($this instanceof metadata_interface)) {
832 4
            exception::no_metadata();
833 4
            return false;
834
        }
835 4
        $user = connection::get_user();
836 4
        if ($user === null) {
837 4
            exception::access_denied();
838 4
            return false;
839
        }
840 4
        if ($action == 'lock') {
841 2
            $flag = 'islocked';
842 4
        } elseif ($action == 'approve') {
843 2
            $flag = 'isapproved';
844 2
        } else {
845
            throw new exception('Unsupported action ' . $action);
846
        }
847
        // same val
848 4
        if ($this->__get('metadata')->$flag === $value) {
849 3
            return false;
850
        }
851 4
        if ($value === false) {
852 2
            $action = 'un' . $action;
853 2
        }
854
855 4
        if ($this->id) {
0 ignored issues
show
Documentation introduced by
The property id does not exist on object<midgard\portable\api\object>. 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...
856
            try {
857 4
                $om = new objectmanager(connection::get_em());
858 4
                $om->{$action}($this);
859 4
            } catch (\Exception $e) {
860
                exception::internal($e);
861
                return false;
862
            }
863 4
        }
864 4
        midgard_connection::get_instance()->set_error(MGD_ERR_OK);
865
866 4
        return true;
867
    }
868
869
    /**
870
     * @return boolean
871
     */
872 3
    public function approve()
873
    {
874 3
        return $this->manage_meta_property("approve", true);
875
    }
876
877
    /**
878
     * @return boolean
879
     */
880 2
    public function is_approved()
881
    {
882 2
        if (!($this instanceof metadata_interface)) {
883
            exception::no_metadata();
884
            return false;
885
        }
886 2
        return $this->metadata_isapproved;
0 ignored issues
show
Bug introduced by
The property metadata_isapproved does not seem to exist. Did you mean metadata?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
887
    }
888
889
    /**
890
     * @return boolean
891
     */
892 2
    public function unapprove()
893
    {
894 2
        return $this->manage_meta_property("approve", false);
895
    }
896
897
    /**
898
     * @return boolean
899
     */
900 3
    public function lock()
901
    {
902 3
        if ($this->is_locked()) {
903 1
            exception::object_is_locked();
904 1
            return false;
905
        }
906 3
        return $this->manage_meta_property("lock", true);
907
    }
908
909
    /**
910
     * @return boolean
911
     */
912 3
    public function is_locked()
913
    {
914 3
        if (!($this instanceof metadata_interface)) {
915 1
            exception::no_metadata();
916 1
            return false;
917
        }
918 2
        return $this->metadata_islocked;
0 ignored issues
show
Bug introduced by
The property metadata_islocked does not seem to exist. Did you mean metadata?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
919
    }
920
921
    /**
922
     * @return boolean
923
     */
924 2
    public function unlock()
925
    {
926 2
        return $this->manage_meta_property("lock", false);
927
    }
928
929
    /**
930
     * @return boolean
931
     */
932
    public function get_workspace()
933
    {
934
        return false;
935
    }
936
}
937