Completed
Push — master ( 9b72e4...2517d7 )
by Andreas
03:27
created

object::__debugInfo()   A

Complexity

Conditions 4
Paths 2

Size

Total Lines 16
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 4

Importance

Changes 0
Metric Value
cc 4
eloc 10
nc 2
nop 0
dl 0
loc 16
ccs 13
cts 13
cp 1
crap 4
rs 9.2
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 = array();
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 42
    public function get_by_id($id)
121
    {
122 42
        $entity = connection::get_em()->find(get_class($this), $id);
123
124 42
        if ($entity === null) {
125 3
            throw exception::not_exists();
126
        }
127
        // According to Doctrine documentation, proxies should be transparent, but in practice,
128
        // there will be problems if we don't force-load
129
        if (   $entity instanceof \Doctrine\ORM\Proxy\Proxy
130 41
            && !$entity->__isInitialized()) {
131
            try {
132 7
                $entity->__load();
133 7
            } catch (\Doctrine\ORM\EntityNotFoundException $e) {
134 1
                throw exception::object_purged();
135
            }
136 6
        }
137 41
        if ($entity instanceof metadata_interface && $entity->{metadata_interface::DELETED_FIELD}) {
138
            // This can happen when the "deleted" entity is still in EM's identity map
139
            throw exception::object_deleted();
140
        }
141 41
        if (empty($entity->guid)) {
142
            // This can happen when a reference proxy to a purged entity is still in EM's identity map
143
            throw exception::object_purged();
144
        }
145
146 41
        $this->populate_from_entity($entity);
147
148 41
        connection::get_em()->detach($entity);
149 41
        midgard_connection::get_instance()->set_error(MGD_ERR_OK);
150 41
        return true;
151
    }
152
153 18
    public function get_by_guid($guid)
154 2
    {
155 18
        if (!mgd_is_guid($guid)) {
156 3
            throw new \InvalidArgumentException("'$guid' is not a valid guid");
157
        }
158 15
        $entity = connection::get_em()->getRepository(get_class($this))->findOneBy(array('guid' => $guid));
159 15
        if ($entity === null) {
160
            throw exception::not_exists();
161
        }
162 15
        $this->populate_from_entity($entity);
163
164 15
        connection::get_em()->detach($entity);
165 15
        midgard_connection::get_instance()->set_error(MGD_ERR_OK);
166 15
        return true;
167 1
    }
168
169
    /**
170
     * @return boolean
171
     */
172 106
    public function create()
173
    {
174 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...
175 2
            exception::duplicate();
176 2
            return false;
177
        }
178 106
        if (   !$this->is_unique()
179 106
            || !$this->check_parent()) {
180 2
            return false;
181 2
        }
182 106
        if (!$this->check_fields()) {
183 3
            return false;
184 2
        }
185
        try {
186 105
            $om = new objectmanager(connection::get_em());
0 ignored issues
show
Compatibility introduced by
\midgard\portable\storage\connection::get_em() of type object<Doctrine\ORM\EntityManagerInterface> is not a sub-type of object<Doctrine\ORM\EntityManager>. It seems like you assume a concrete implementation of the interface Doctrine\ORM\EntityManagerInterface to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
187 105
            $om->create($this);
188 105
        } catch (\Exception $e) {
189
            exception::internal($e);
190
            return false;
191
        }
192
193 105
        midgard_connection::get_instance()->set_error(MGD_ERR_OK);
194
195 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...
196
    }
197
198
    /**
199
     * @return boolean
200
     */
201 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...
202
    {
203 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...
204 1
            midgard_connection::get_instance()->set_error(MGD_ERR_INTERNAL);
205 1
            return false;
206
        }
207 14
        if (!$this->check_fields()) {
208 1
            return false;
209
        }
210
        try {
211 13
            $om = new objectmanager(connection::get_em());
0 ignored issues
show
Compatibility introduced by
\midgard\portable\storage\connection::get_em() of type object<Doctrine\ORM\EntityManagerInterface> is not a sub-type of object<Doctrine\ORM\EntityManager>. It seems like you assume a concrete implementation of the interface Doctrine\ORM\EntityManagerInterface to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
212 13
            $om->update($this);
213 13
        } catch (\Exception $e) {
214
            exception::internal($e);
215
            return false;
216
        }
217 13
        midgard_connection::get_instance()->set_error(MGD_ERR_OK);
218
219 13
        return true;
220
    }
221
222
    /**
223
     * @todo: Tests indicate that $check_dependencies is ignored in the mgd2 extension,
224
     * so we might consider ignoring it, too
225
     *
226
     * @return boolean
227
     */
228 28
    public function delete($check_dependencies = true)
229
    {
230 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...
231 1
            midgard_connection::get_instance()->set_error(MGD_ERR_INVALID_PROPERTY_VALUE);
232 1
            return false;
233
        }
234
        if (   $check_dependencies
235 27
            && $this->has_dependents()) {
236 4
            exception::has_dependants();
237 4
            return false;
238
        }
239 27
        if (!($this instanceof metadata_interface)) {
240 1
            exception::invalid_property_value();
241 1
            return false;
242
        }
243 26
        if ($this->{metadata_interface::DELETED_FIELD}) {
244 1
            return true;
245
        }
246
247
        try {
248 26
            $om = new objectmanager(connection::get_em());
0 ignored issues
show
Compatibility introduced by
\midgard\portable\storage\connection::get_em() of type object<Doctrine\ORM\EntityManagerInterface> is not a sub-type of object<Doctrine\ORM\EntityManager>. It seems like you assume a concrete implementation of the interface Doctrine\ORM\EntityManagerInterface to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
249 26
            $om->delete($this);
250 26
        } catch (\Exception $e) {
251
            exception::internal($e);
252
            return false;
253
        }
254
255 26
        midgard_connection::get_instance()->set_error(MGD_ERR_OK);
256 26
        return true;
257
    }
258
259 106
    private function is_unique()
260
    {
261 106
        $this->initialize();
262
263 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...
264 100
            return true;
265
        }
266
267 8
        $qb = connection::get_em()->createQueryBuilder();
268 8
        $qb->from(get_class($this), 'c');
269 8
        $conditions = $qb->expr()->andX();
270 8 View Code Duplication
        if ($this->id) {
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...
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...
271
            $parameters = array(
272
                '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...
273
            );
274
            $conditions->add($qb->expr()->neq('c.id', ':id'));
275
        }
276 8
        $found = false;
277 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...
278 8
            if (empty($this->$field)) {
279
                //empty names automatically pass according to Midgard logic
280 2
                continue;
281
            }
282 7
            $conditions->add($qb->expr()->eq('c.' . $field, ':' . $field));
283 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...
284 7
            $found = true;
285 8
        }
286
287 8
        if (!$found) {
288 2
            return true;
289
        }
290
291 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...
292
            // TODO: This needs to be changed so that value is always numeric, since this is how midgard does it
293 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...
294 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...
295 6
            } else {
296 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...
297 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...
298
            }
299 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...
300
            // TODO: This needs to be changed so that value is always numeric, since this is how midgard does it
301 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...
302
                $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...
303
            } else {
304 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...
305 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...
306
            }
307 4
        }
308 7
        $qb->where($conditions)
309 7
            ->setParameters($parameters);
310
311 7
        $qb->select("count(c)");
312 7
        $count = intval($qb->getQuery()->getSingleScalarResult());
313
314 7
        if ($count !== 0) {
315 1
            exception::object_name_exists();
316 1
            return false;
317
        }
318 7
        return true;
319
    }
320
321 106
    private function check_parent()
322
    {
323 106
        $this->initialize();
324
325 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...
326 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...
327 106
            return true;
328
        }
329
330 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...
331 1
            exception::object_no_parent();
332 1
            return false;
333
        }
334 8
        return true;
335
    }
336
337 106
    private function check_fields()
338
    {
339 106
        $this->initialize();
340
341 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...
342 106
            if (   $field['midgard:midgard_type'] == translator::TYPE_GUID
343 106
                && !empty($this->$name)
344 106
                && !mgd_is_guid($this->$name)) {
345 2
                exception::invalid_property_value("'" . $name . "' property's value is not a guid.");
346 2
                return false;
347
            }
348 106
        }
349 105
        return true;
350
    }
351
352
    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...
353
    {
354
        return false;
355
    }
356
357
    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...
358
    {
359
        return false;
360
    }
361
362 34
    public function has_dependents()
363
    {
364 34
        $this->initialize();
365
366 34
        $stat = false;
367
368 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...
369 29
            $qb = connection::get_em()->createQueryBuilder();
370 29
            $qb->from(get_class($this), 'c')
371 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...
372 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...
373 29
                ->select("COUNT(c)");
374 29
            $results = intval($qb->getQuery()->getSingleScalarResult());
375 29
            $stat = ($results > 0);
376 29
        }
377
378
        if (   !$stat
379 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...
380 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...
381 27
                $qb = connection::get_em()->createQueryBuilder();
382 27
                $qb->from('midgard:' . $typename, 'c')
383 27
                    ->where('c.' . $parentfield . ' = ?0')
384 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...
385 27
                    ->select("COUNT(c)");
386
387 27
                $results = intval($qb->getQuery()->getSingleScalarResult());
388 27
                $stat = ($results > 0);
389 27
                if ($stat) {
390 3
                    break;
391
                }
392 27
            }
393 27
        }
394
395 34
        return $stat;
396
    }
397
398
    public function get_parent()
399
    {
400
        return null;
401
    }
402
403
    /**
404
     * This function is called list() in Midgard, but that doesn't work in plain PHP
405
     *
406
     * @return array
407
     */
408 1
    private function _list()
409
    {
410 1
        $this->initialize();
411
412 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...
413 1
            $qb = connection::get_em()->createQueryBuilder();
414 1
            $qb->from(get_class($this), 'c')
415 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...
416 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...
417 1
                ->select("c");
418 1
            return $qb->getQuery()->getResult();
419
        }
420
421
        return array();
422
    }
423
424
    /**
425
     * This should return child objects, but only if they are of a different type
426
     * For all other input, an empty array is returned
427
     * (not implemented yet)
428
     *
429
     * @param string $classname
430
     * @return array
431
     */
432
    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...
433
    {
434
        return array();
435
    }
436
437 1
    public function get_by_path($path)
438
    {
439 1
        $parts = explode('/', trim($path, '/'));
440 1
        if (empty($parts)) {
441
            return false;
442
        }
443 1
        $this->initialize();
444
445 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...
446
            return false;
447
        }
448
449 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...
450
451 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...
452 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...
453 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...
454 1
            $parentfield = $parent_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...
455 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...
456 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...
457 1
            $parentclass = get_class($this);
458 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...
459 1
            $parentfield = $upfield;
460 1
        } else {
461
            return false;
462
        }
463
464 1
        $name = array_pop($parts);
465 1
        $up = 0;
466 1
        foreach ($parts as $part) {
467 1
            $qb = $this->get_uniquefield_query($parentclass, $field, $part, $parentfield, $up);
468 1
            $qb->select("c.id");
469 1
            $up = intval($qb->getQuery()->getOneOrNullResult(Query::HYDRATE_SINGLE_SCALAR));
470 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...
471
                exception::not_exists();
472
                $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...
473
                $this->set_guid('');
474
                return false;
475
            }
476 1
        }
477
478 1
        $qb = $this->get_uniquefield_query(get_class($this), $field, $name, $upfield, $up);
479 1
        $qb->select("c");
480
481 1
        $entity = $qb->getQuery()->getOneOrNullResult();
482
483 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...
484 1
            exception::not_exists();
485 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...
486 1
            $this->set_guid('');
487 1
            return false;
488
        }
489 1
        $this->populate_from_entity($entity);
490
491 1
        return true;
492
    }
493
494
    /**
495
     * @return QueryBuilder
496
     */
497 1
    protected function get_uniquefield_query($classname, $field, $part, $upfield, $up)
498
    {
499 1
        $qb = connection::get_em()->createQueryBuilder();
500 1
        $qb->from($classname, 'c');
501 1
        $conditions = $qb->expr()->andX();
502 1
        $conditions->add($qb->expr()->eq('c.' . $field, ':' . $field));
503
        $parameters = array(
504
            $field => $part
505 1
        );
506
507 1
        if (empty($up)) {
508
            // If the database was created by Midgard, it might contain 0 instead of NULL, so...
509 1
            $empty_conditions = $qb->expr()->orX()
510 1
                ->add($qb->expr()->isNull('c.' . $upfield))
511 1
                ->add($qb->expr()->eq('c.' . $upfield, '0'));
512 1
            $conditions->add($empty_conditions);
513 1
        } else {
514 1
            $conditions->add($qb->expr()->eq('c.' . $upfield, ':' . $upfield));
515 1
            $parameters[$upfield] = $up;
516
        }
517
518 1
        $qb->where($conditions)
519 1
            ->setParameters($parameters);
520
521 1
        return $qb;
522
    }
523
524
    /**
525
     * @return boolean
526
     */
527
    public function parent()
528
    {
529
        return false;
530
    }
531
532
    /**
533
     * @return boolean
534
     */
535 1
    public function has_parameters()
536
    {
537 1
        return !$this->get_collection('midgard_parameter')->is_empty($this->guid);
538
    }
539
540 4
    public function list_parameters($domain = false)
541
    {
542 4
        $constraints = array();
543 4
        if ($domain) {
544 1
            $constraints[] = array("domain", "=", $domain);
545 1
        }
546
547 4
        return $this->get_collection('midgard_parameter')->find($this->guid, $constraints);
548
    }
549
550 3
    public function find_parameters(array $constraints = array())
551
    {
552 3
        return $this->get_collection('midgard_parameter')->find($this->guid, $constraints);
553
    }
554
555
    /**
556
     * @param array $constraints
557
     * @return number
558
     */
559 1
    public function delete_parameters(array $constraints = array())
560
    {
561 1
        return $this->get_collection('midgard_parameter')->delete($this->guid, $constraints);
562
    }
563
564
    /**
565
     * @param array $constraints
566
     * @return number
567
     */
568 1
    public function purge_parameters(array $constraints = array())
569
    {
570 1
        return $this->get_collection('midgard_parameter')->purge($this->guid, $constraints);
571
    }
572
573 2
    public function get_parameter($domain, $name)
574
    {
575 2
        if (!$this->guid) {
576 1
            return false;
577
        }
578 2
        $qb = connection::get_em()->createQueryBuilder();
579
        $qb
580 2
            ->select('c.value')
581 2
            ->from('midgard:midgard_parameter', 'c')
582 2
            ->where('c.domain = :domain AND c.name = :name AND c.parentguid = :parentguid')
583 2
            ->setParameters(array('domain' => $domain, 'name' => $name, 'parentguid' => $this->guid));
584
585
        // workaround for http://www.doctrine-project.org/jira/browse/DDC-2655
586
        try {
587 2
            return $qb->getQuery()->getOneOrNullResult(Query::HYDRATE_SINGLE_SCALAR);
588
        } catch (\Doctrine\ORM\NoResultException $e) {
589
            return null;
590
        }
591
    }
592
593
    /**
594
     * @param string $domain
595
     * @param string $name
596
     * @param mixed $value
597
     * @return boolean
598
     */
599 11
    public function set_parameter($domain, $name, $value)
600
    {
601
        $constraints = array(
602 11
            array('domain', '=', $domain),
603 11
            array('name', '=', $name),
604 11
        );
605 11
        $params = $this->get_collection('midgard_parameter')->find($this->guid, $constraints);
606
607
        // check value
608 11
        if ($value === false || $value === null || $value === "") {
609 2
            if (count($params) == 0) {
610 1
                exception::not_exists();
611 1
                return false;
612
            }
613 2
            foreach ($params as $param) {
614 2
                $stat = $param->delete();
615 2
            }
616 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...
617
        }
618
619 11
        $om = new objectmanager(connection::get_em());
0 ignored issues
show
Compatibility introduced by
\midgard\portable\storage\connection::get_em() of type object<Doctrine\ORM\EntityManagerInterface> is not a sub-type of object<Doctrine\ORM\EntityManager>. It seems like you assume a concrete implementation of the interface Doctrine\ORM\EntityManagerInterface to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
620
        try {
621
            // create new
622 11
            if (count($params) == 0) {
623 11
                $parameter = $om->new_instance(connection::get_em()->getClassMetadata('midgard:midgard_parameter')->getName());
624 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...
625 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...
626 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...
627 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...
628 11
                $om->create($parameter);
629 11
            }
630
            // use existing
631
            else {
632 1
                $parameter = array_shift($params);
633 1
                $parameter->value = $value;
634 1
                $om->update($parameter);
635
            }
636 11
            midgard_connection::get_instance()->set_error(MGD_ERR_OK);
637 11
            return true;
638
        } catch (\Exception $e) {
639
            exception::internal($e);
640
            return false;
641
        }
642
    }
643
644
    /**
645
     * The signature is a little different from original, because Doctrine doesn't support func_get_args() in proxies
646
     */
647 2
    public function parameter($domain, $name, $value = '__UNINITIALIZED__')
648
    {
649 2
        if ($value === '__UNINITIALIZED__') {
650 1
            return $this->get_parameter($domain, $name);
651
        }
652 2
        return $this->set_parameter($domain, $name, $value);
653
    }
654
655
    /**
656
     * @return boolean
657
     */
658 1
    public function has_attachments()
659
    {
660 1
        return !$this->get_collection('midgard_attachment')->is_empty($this->guid);
661
    }
662
663 2
    public function list_attachments()
664
    {
665 2
        return $this->get_collection('midgard_attachment')->find($this->guid, array());
666
    }
667
668
    public function find_attachments(array $constraints = array())
669
    {
670
        return $this->get_collection('midgard_attachment')->find($this->guid, $constraints);
671
    }
672
673
    /**
674
     * @param array $constraints
675
     * @return number
676
     */
677
    public function delete_attachments(array $constraints = array())
678
    {
679
        return $this->get_collection('midgard_attachment')->delete($this->guid, $constraints);
680
    }
681
682
    /**
683
     *
684
     * @param array $constraints
685
     * @param boolean $delete_blob
686
     * @return boolean False if one or more attachments couldn't be deleted
687
     * @todo Implement delete_blob & return value
688
     */
689
    public function purge_attachments(array $constraints = array(), $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...
690
    {
691
        return $this->get_collection('midgard_attachment')->purge($this->guid, $constraints);
692
    }
693
694 3
    public function create_attachment($name, $title = '', $mimetype = '')
695
    {
696 3
        $existing = $this->get_collection('midgard_attachment')->find($this->guid, array('name' => $name));
697 3
        if (count($existing) > 0) {
698 1
            exception::object_name_exists();
699 1
            return null;
700
        }
701 3
        $om = new objectmanager(connection::get_em());
0 ignored issues
show
Compatibility introduced by
\midgard\portable\storage\connection::get_em() of type object<Doctrine\ORM\EntityManagerInterface> is not a sub-type of object<Doctrine\ORM\EntityManager>. It seems like you assume a concrete implementation of the interface Doctrine\ORM\EntityManagerInterface to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
702 3
        $att = $om->new_instance(connection::get_em()->getClassMetadata('midgard:midgard_attachment')->getName());
703
704 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...
705 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...
706 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...
707 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...
708
        try {
709 3
            $om->create($att);
710 3
            midgard_connection::get_instance()->set_error(MGD_ERR_OK);
711 3
            return $att;
712
        } catch (\Exception $e) {
713
            exception::internal($e);
714
            return null;
715
        }
716
    }
717
718
    /**
719
     * @return boolean
720
     */
721
    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...
722
    {
723
        return false;
724
    }
725
726
    /**
727
     * @todo: Tests indicate that $check_dependencies is ignored in the mgd2 extension,
728
     * so we might consider ignoring it, too
729
     * @return boolean
730
     */
731 17
    public function purge($check_dependencies = true)
732
    {
733 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...
734
            // This usually means that the object has been purged already
735
            exception::not_exists();
736
            return false;
737
        }
738
        if (   $check_dependencies
739 17
            && $this->has_dependents()) {
740 2
            exception::has_dependants();
741 2
            return false;
742
        }
743
744
        try {
745 17
            $om = new objectmanager(connection::get_em());
0 ignored issues
show
Compatibility introduced by
\midgard\portable\storage\connection::get_em() of type object<Doctrine\ORM\EntityManagerInterface> is not a sub-type of object<Doctrine\ORM\EntityManager>. It seems like you assume a concrete implementation of the interface Doctrine\ORM\EntityManagerInterface to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
746 17
            $om->purge($this);
747 17
        } catch (\Doctrine\ORM\EntityNotFoundException $e) {
748 2
            exception::not_exists();
749 2
            return false;
750
        } catch (\Exception $e) {
751
            exception::internal($e);
752
            return false;
753
        }
754 17
        midgard_connection::get_instance()->set_error(MGD_ERR_OK);
755
756 17
        return true;
757
    }
758
759
    /**
760
     * @return boolean
761
     */
762 2
    public static function undelete($guid)
763
    {
764 2
        return \midgard_object_class::undelete($guid);
765
    }
766
767
    /**
768
     * @return boolean
769
     */
770
    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...
771
    {
772
        return false;
773
    }
774
775
    /**
776
     * @return \midgard_query_builder
777
     */
778 1
    public static function new_query_builder()
779
    {
780 1
        return new \midgard_query_builder(get_called_class());
781
    }
782
783
    /**
784
     *
785
     * @param string $field
786
     * @param mixed $value
787
     * @return \midgard_collector
788
     */
789 1
    public static function new_collector($field, $value)
790
    {
791 1
        return new \midgard_collector(get_called_class(), $field, $value);
792
    }
793
794
    /**
795
     * @return \midgard_reflection_property
796
     */
797
    public static function new_reflection_property()
798
    {
799
        return new \midgard_reflection_property(get_called_class());
800
    }
801
802 106
    public function set_guid($guid)
803
    {
804 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...
805 106
    }
806
807
    /**
808
     * @return boolean
809
     */
810
    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...
811
    {
812
        return false;
813
    }
814
815
    /**
816
     * Helper for managing the isapproved and islocked metadata properties
817
     *
818
     * @param string $action the property to manage (either approve or lock)
819
     * @param bool $value
820
     * @return boolean
821
     */
822 8
    private function manage_meta_property($action, $value)
823
    {
824 8
        if (!($this instanceof metadata_interface)) {
825 4
            exception::no_metadata();
826 4
            return false;
827
        }
828 4
        $user = connection::get_user();
829 4
        if ($user === null) {
830 4
            exception::access_denied();
831 4
            return false;
832
        }
833 4
        if ($action == 'lock') {
834 2
            $flag = 'islocked';
835 4
        } elseif ($action == 'approve') {
836 2
            $flag = 'isapproved';
837 2
        } else {
838
            throw new exception('Unsupported action ' . $action);
839
        }
840
        // same val
841 4
        if ($this->__get('metadata')->$flag === $value) {
842 3
            return false;
843
        }
844 4
        if ($value === false) {
845 2
            $action = 'un' . $action;
846 2
        }
847
848 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...
849
            try {
850 4
                $om = new objectmanager(connection::get_em());
0 ignored issues
show
Compatibility introduced by
\midgard\portable\storage\connection::get_em() of type object<Doctrine\ORM\EntityManagerInterface> is not a sub-type of object<Doctrine\ORM\EntityManager>. It seems like you assume a concrete implementation of the interface Doctrine\ORM\EntityManagerInterface to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
851 4
                $om->{$action}($this);
852 4
            } catch (\Exception $e) {
853
                exception::internal($e);
854
                return false;
855
            }
856 4
        }
857 4
        midgard_connection::get_instance()->set_error(MGD_ERR_OK);
858
859 4
        return true;
860
    }
861
862
    /**
863
     * @return boolean
864
     */
865 3
    public function approve()
866
    {
867 3
        return $this->manage_meta_property("approve", true);
868
    }
869
870
    /**
871
     * @return boolean
872
     */
873 2
    public function is_approved()
874
    {
875 2
        if (!($this instanceof metadata_interface)) {
876
            exception::no_metadata();
877
            return false;
878
        }
879 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...
880
    }
881
882
    /**
883
     * @return boolean
884
     */
885 2
    public function unapprove()
886
    {
887 2
        return $this->manage_meta_property("approve", false);
888
    }
889
890
    /**
891
     * @return boolean
892
     */
893 3
    public function lock()
894
    {
895 3
        if ($this->is_locked()) {
896 1
            exception::object_is_locked();
897 1
            return false;
898
        }
899 3
        return $this->manage_meta_property("lock", true);
900
    }
901
902
    /**
903
     * @return boolean
904
     */
905 3
    public function is_locked()
906
    {
907 3
        if (!($this instanceof metadata_interface)) {
908 1
            exception::no_metadata();
909 1
            return false;
910
        }
911 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...
912
    }
913
914
    /**
915
     * @return boolean
916
     */
917 2
    public function unlock()
918
    {
919 2
        return $this->manage_meta_property("lock", false);
920
    }
921
922
    /**
923
     * @return boolean
924
     */
925
    public function get_workspace()
926
    {
927
        return false;
928
    }
929
}
930