Completed
Push — master ( 1af4f5...caaac4 )
by Andreas
03:43
created

object::delete_attachments()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 4
ccs 0
cts 2
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * @author CONTENT CONTROL http://www.contentcontrol-berlin.de/
4
 * @copyright CONTENT CONTROL http://www.contentcontrol-berlin.de/
5
 * @license http://www.gnu.org/licenses/gpl.html GNU General Public License
6
 */
7
namespace midgard\portable\api;
8
9
use midgard\portable\storage\connection;
10
use midgard\portable\storage\objectmanager;
11
use midgard\portable\storage\collection;
12
use midgard\portable\storage\metadata\entity 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
19
abstract class object extends dbobject
20
{
21
    public $action = ''; // <== does this need to do anything?
22
23
    private $collections = array();
24
25
    /**
26
     *
27
     * @param mixed $id ID or GUID
28
     */
29 119
    public function __construct($id = null)
30
    {
31 119
        if ($id !== null) {
32 46
            if (is_int($id)) {
33 56
                $this->get_by_id($id);
34 45
            } elseif (is_string($id)) {
35 12
                $this->get_by_guid($id);
36 11
            }
37 44
        }
38 117
    }
39
40
    /**
41
     *
42
     * @param string $classname
43
     * @return collection
44
     */
45 16
    private function get_collection($classname)
46
    {
47 16
        if (!array_key_exists($classname, $this->collections)) {
48 16
            $this->collections[$classname] = new collection($classname);
49 16
        }
50 16
        return $this->collections[$classname];
51
    }
52
53 1
    public function __debugInfo()
54
    {
55 1
        $ret = parent::__debugInfo();
56 1
        if (property_exists($this, 'metadata')) {
57 1
            $metadata = new \stdClass;
58 1
            foreach ($this->cm->getFieldNames() as $name) {
59 1
                if (strpos($name, 'metadata_') !== false) {
60 1
                    $fieldname = str_replace('metadata_', '', $name);
61 1
                    $metadata->$fieldname = $this->__get($name);
62 1
                }
63 1
            }
64 1
            $ret['metadata'] = $metadata;
65 1
        }
66
67 1
        return $ret;
68
    }
69
70 101
    public function __set($field, $value)
71
    {
72 101
        if ($field == 'guid') {
73 6
            return;
74
        }
75 101
        parent::__set($field, $value);
76 101
    }
77
78 110
    public function __get($field)
79
    {
80
        if (   $field === 'metadata'
81 110
            && property_exists($this, 'metadata')
82 110
            && $this->metadata === null) {
0 ignored issues
show
Documentation introduced by
The property metadata 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...
83 97
            $this->metadata = new metadata($this);
0 ignored issues
show
Documentation introduced by
The property metadata 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...
84 97
        }
85
86 110
        return parent::__get($field);
87
    }
88
89 1
    public function __call($method, $args)
90
    {
91 1
        if ($method === 'list') {
92 1
            return $this->_list();
93
        }
94
        throw new \BadMethodCallException("Unknown method " . $method . " on " . get_class($this));
95
    }
96
97 26
    protected function load_parent(array $candidates)
98
    {
99 4
        foreach ($candidates as $candidate) {
100 4
            if ($this->$candidate !== null) {
101
                //Proxies become stale if the object itself is detached, so we have to re-fetch
102 4
                if (   $this->$candidate instanceof \Doctrine\ORM\Proxy\Proxy
103 10
                    && $this->$candidate->__isInitialized()) {
104
                    try {
105 1
                        $this->$candidate->get_by_id($this->$candidate->id);
106 1
                    } catch (exception $e) {
107
                        connection::log()->error('Failed to refresh parent from proxy: ' . $e->getMessage());
108
                        return null;
109
                    }
110 1
                }
111 4
                return $this->$candidate;
112 26
            }
113 2
        }
114 1
        return null;
115
    }
116
117 40
    public function get_by_id($id)
118
    {
119 40
        $entity = connection::get_em()->find(get_class($this), $id);
120
121 40
        if ($entity === null) {
122 3
            throw exception::not_exists();
123
        }
124
        // According to Doctrine documentation, proxies should be transparent, but in practice,
125
        // there will be problems if we don't force-load
126
        if (   $entity instanceof \Doctrine\ORM\Proxy\Proxy
127 39
            && !$entity->__isInitialized()) {
128
            try {
129 7
                $entity->__load();
130 7
            } catch (\Doctrine\ORM\EntityNotFoundException $e) {
131 1
                throw exception::object_purged();
132
            }
133 6
        }
134 39
        if ($entity->metadata_deleted) {
135
            // This can happen when the "deleted" entity is still in EM's identity map
136
            throw exception::object_deleted();
137
        }
138 39
        if (empty($entity->guid)) {
139
            // This can happen when a reference proxy to a purged entity is still in EM's identity map
140
            throw exception::object_purged();
141
        }
142
143 39
        $this->populate_from_entity($entity);
144
145 39
        connection::get_em()->detach($entity);
146 39
        midgard_connection::get_instance()->set_error(MGD_ERR_OK);
147 39
        return true;
148
    }
149
150 15
    public function get_by_guid($guid)
151
    {
152 14
        if (!mgd_is_guid($guid)) {
153 3
            throw new \InvalidArgumentException("'$guid' is not a valid guid");
154 2
        }
155 15
        $entity = connection::get_em()->getRepository(get_class($this))->findOneBy(array('guid' => $guid));
156 15
        if ($entity === null) {
157
            throw exception::not_exists();
158
        }
159 13
        $this->populate_from_entity($entity);
160
161 13
        connection::get_em()->detach($entity);
162 13
        midgard_connection::get_instance()->set_error(MGD_ERR_OK);
163 13
        return true;
164
    }
165
166 94
    public function create()
167 1
    {
168 94
        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...
169 2
            exception::duplicate();
170 2
            return false;
171
        }
172 94
        if (   !$this->is_unique()
173 94
            || !$this->check_parent()) {
174 2
            return false;
175
        }
176 94
        if (!$this->check_fields()) {
177 1
            return false;
178
        }
179
        try {
180 93
            $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...
181 93
            $om->create($this);
182 93
        } catch (\Exception $e) {
183 2
            exception::internal($e);
184 2
            return false;
185
        }
186
187 93
        midgard_connection::get_instance()->set_error(MGD_ERR_OK);
188
189 93
        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...
190
    }
191
192 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...
193
    {
194 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...
195 2
            midgard_connection::get_instance()->set_error(MGD_ERR_INTERNAL);
196 1
            return false;
197
        }
198 13
        if (!$this->check_fields()) {
199 1
            return false;
200
        }
201
        try {
202 12
            $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...
203 12
            $om->update($this);
204 12
        } catch (\Exception $e) {
205
            exception::internal($e);
206
            return false;
207
        }
208 12
        midgard_connection::get_instance()->set_error(MGD_ERR_OK);
209
210 12
        return true;
211
    }
212
213
    /**
214
     * @todo: Tests indicate that $check_dependencies is ignored in the mgd2 extension,
215
     * so we might consider ignoring it, too
216
     */
217 27
    public function delete($check_dependencies = true)
218
    {
219 27
        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...
220 1
            midgard_connection::get_instance()->set_error(MGD_ERR_INVALID_PROPERTY_VALUE);
221 1
            return false;
222
        }
223
        if (   $check_dependencies
224 26
            && $this->has_dependents()) {
225 4
            exception::has_dependants();
226 4
            return false;
227
        }
228 26
        if (!($this instanceof metadata_interface)) {
229
            return $this->purge($check_dependencies);
230
        }
231 26
        if ($this->metadata_deleted) {
0 ignored issues
show
Documentation introduced by
The property metadata_deleted 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...
232 1
            return true;
233
        }
234
235
        try {
236 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...
237 26
            $om->delete($this);
238 26
        } catch (\Exception $e) {
239
            exception::internal($e);
240
            return false;
241
        }
242
243 26
        midgard_connection::get_instance()->set_error(MGD_ERR_OK);
244 26
        return true;
245
    }
246
247 94
    private function is_unique()
248
    {
249 94
        $this->initialize();
250
251 94
        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...
252 89
            return true;
253
        }
254
255 7
        $qb = connection::get_em()->createQueryBuilder();
256 7
        $qb->from(get_class($this), 'c');
257 7
        $conditions = $qb->expr()->andX();
258 7 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...
259
            $parameters = array(
260
                '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...
261
            );
262
            $conditions->add($qb->expr()->neq('c.id', ':id'));
263
        }
264 7
        $found = false;
265 7
        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...
266 7
            if (empty($this->$field)) {
267
                //empty names automatically pass according to Midgard logic
268 2
                continue;
269
            }
270 6
            $conditions->add($qb->expr()->eq('c.' . $field, ':' . $field));
271 6
            $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...
272 6
            $found = true;
273 7
        }
274
275 7
        if (!$found) {
276 2
            return true;
277
        }
278
279 6
        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...
280
            // TODO: This needs to be changed so that value is always numeric, since this is how midgard does it
281 5
            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...
282 5
                $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...
283 5
            } else {
284 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...
285 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...
286
            }
287 5
        }
288 6
        $qb->where($conditions)
289 6
            ->setParameters($parameters);
290
291 6
        $qb->select("count(c)");
292 6
        $count = intval($qb->getQuery()->getSingleScalarResult());
293
294 6
        if ($count !== 0) {
295 1
            exception::object_name_exists();
296 1
            return false;
297
        }
298 6
        return true;
299
    }
300
301 94
    private function check_parent()
302
    {
303 94
        $this->initialize();
304
305 94
        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...
306 94
            || 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...
307 94
            return true;
308
        }
309
310 7
        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...
311 1
            exception::object_no_parent();
312 1
            return false;
313
        }
314 7
        return true;
315
    }
316
317 94
    private function check_fields()
318
    {
319 94
        $this->initialize();
320
321 94
        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...
322 94
            if (   $field['midgard:midgard_type'] == translator::TYPE_GUID
323 94
                && !empty($this->$name)
324 94
                && !mgd_is_guid($this->$name)) {
325 2
                exception::invalid_property_value("'" . $name . "' property's value is not a guid.");
326 2
                return false;
327
            }
328 94
        }
329 93
        return true;
330
    }
331
332
    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...
333
    {
334
        return false;
335
    }
336
337
    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...
338
    {
339
        return false;
340
    }
341
342 32
    public function has_dependents()
343
    {
344 32
        $this->initialize();
345
346 32
        $stat = false;
347
348 32
        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...
349 27
            $qb = connection::get_em()->createQueryBuilder();
350 27
            $qb->from(get_class($this), 'c')
351 27
                ->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...
352 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...
353 27
                ->select("COUNT(c)");
354 27
            $results = intval($qb->getQuery()->getSingleScalarResult());
355 27
            $stat = ($results > 0);
356 27
        }
357
358
        if (   !$stat
359 32
            && !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...
360 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...
361 27
                $qb = connection::get_em()->createQueryBuilder();
362 27
                $qb->from('midgard:' . $typename, 'c')
363 27
                    ->where('c.' . $parentfield . ' = ?0')
364 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...
365 27
                    ->select("COUNT(c)");
366
367 27
                $results = intval($qb->getQuery()->getSingleScalarResult());
368 27
                $stat = ($results > 0);
369 27
                if ($stat) {
370 3
                    break;
371
                }
372 27
            }
373 27
        }
374
375 32
        return $stat;
376
    }
377
378
    public function get_parent()
379
    {
380
        return null;
381
    }
382
383
    /**
384
     * This function is called list() in Midgard, but that doesn't work in plain PHP
385
     *
386
     * @return array
387
     */
388 1
    private function _list()
389
    {
390 1
        $this->initialize();
391
392 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...
393 1
            $qb = connection::get_em()->createQueryBuilder();
394 1
            $qb->from(get_class($this), 'c')
395 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...
396 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...
397 1
                ->select("c");
398 1
            return $qb->getQuery()->getResult();
399
        }
400
401
        return array();
402
    }
403
404
    /**
405
     * This should return child objects, but only if they are of a different type
406
     * For all other input, an empty array is returned
407
     * (not implemented yet)
408
     *
409
     * @param string $classname
410
     * @return array
411
     */
412
    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...
413
    {
414
        return array();
415
    }
416
417 1
    public function get_by_path($path)
418
    {
419 1
        $parts = explode('/', trim($path, '/'));
420 1
        if (empty($parts)) {
421
            return false;
422
        }
423 1
        $this->initialize();
424
425 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...
426
            return false;
427
        }
428
429 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...
430
431 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...
432 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...
433 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...
434 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...
435 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...
436 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...
437 1
            $parentclass = get_class($this);
438 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...
439 1
            $parentfield = $upfield;
440 1
        } else {
441
            return false;
442
        }
443
444 1
        $name = array_pop($parts);
445 1
        $up = 0;
446 1
        foreach ($parts as $part) {
447 1
            $qb = $this->get_uniquefield_query($parentclass, $field, $part, $parentfield, $up);
448 1
            $qb->select("c.id");
449 1
            $up = intval($qb->getQuery()->getOneOrNullResult(Query::HYDRATE_SINGLE_SCALAR));
450 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...
451
                exception::not_exists();
452
                $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...
453
                $this->set_guid('');
454
                return false;
455
            }
456 1
        }
457
458 1
        $qb = $this->get_uniquefield_query(get_class($this), $field, $name, $upfield, $up);
459 1
        $qb->select("c");
460
461 1
        $entity = $qb->getQuery()->getOneOrNullResult();
462
463 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...
464 1
            exception::not_exists();
465 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...
466 1
            $this->set_guid('');
467 1
            return false;
468
        }
469 1
        $this->populate_from_entity($entity);
470
471 1
        return true;
472
    }
473
474
    /**
475
     * @return int
476
     */
477 1
    protected function get_uniquefield_query($classname, $field, $part, $upfield, $up)
478
    {
479 1
        $qb = connection::get_em()->createQueryBuilder();
480 1
        $qb->from($classname, 'c');
481 1
        $conditions = $qb->expr()->andX();
482 1
        $conditions->add($qb->expr()->eq('c.' . $field, ':' . $field));
483
        $parameters = array(
484
            $field => $part
485 1
        );
486
487 1
        if (empty($up)) {
488
            // If the database was created by Midgard, it might contain 0 instead of NULL, so...
489 1
            $empty_conditions = $qb->expr()->orX()
490 1
                ->add($qb->expr()->isNull('c.' . $upfield))
491 1
                ->add($qb->expr()->eq('c.' . $upfield, '0'));
492 1
            $conditions->add($empty_conditions);
493 1
        } else {
494 1
            $conditions->add($qb->expr()->eq('c.' . $upfield, ':' . $upfield));
495 1
            $parameters[$upfield] = $up;
496
        }
497
498 1
        $qb->where($conditions)
499 1
            ->setParameters($parameters);
500
501 1
        return $qb;
502
    }
503
504
    public function parent()
505
    {
506
        return false;
507
    }
508
509 1
    public function has_parameters()
510
    {
511 1
        return $this->get_collection('midgard_parameter')->is_empty($this->guid);
512
    }
513
514 4
    public function list_parameters($domain = false)
515
    {
516 4
        $constraints = array();
517 4
        if ($domain) {
518 1
            $constraints[] = array("domain", "=", $domain);
519 1
        }
520
521 4
        return $this->get_collection('midgard_parameter')->find($this->guid, $constraints);
522
    }
523
524 3
    public function find_parameters(array $constraints = array())
525
    {
526 3
        return $this->get_collection('midgard_parameter')->find($this->guid, $constraints);
527
    }
528
529 1
    public function delete_parameters(array $constraints = array())
530
    {
531 1
        return $this->get_collection('midgard_parameter')->delete($this->guid, $constraints);
532
    }
533
534 1
    public function purge_parameters(array $constraints = array())
535
    {
536 1
        return $this->get_collection('midgard_parameter')->purge($this->guid, $constraints);
537
    }
538
539 2
    public function get_parameter($domain, $name)
540
    {
541 2
        if (!$this->guid) {
542 1
            return false;
543
        }
544 2
        $qb = connection::get_em()->createQueryBuilder();
545
        $qb
546 2
            ->select('c.value')
547 2
            ->from('midgard:midgard_parameter', 'c')
548 2
            ->where('c.domain = :domain AND c.name = :name AND c.parentguid = :parentguid')
549 2
            ->setParameters(array('domain' => $domain, 'name' => $name, 'parentguid' => $this->guid));
550
551
        // workaround for http://www.doctrine-project.org/jira/browse/DDC-2655
552
        try {
553 2
            return $qb->getQuery()->getOneOrNullResult(Query::HYDRATE_SINGLE_SCALAR);
554
        } catch (\Doctrine\ORM\NoResultException $e) {
555
            return null;
556
        }
557
    }
558
559 11
    public function set_parameter($domain, $name, $value)
560
    {
561
        $constraints = array(
562 11
            array('domain', '=', $domain),
563 11
            array('name', '=', $name),
564 11
        );
565 11
        $params = $this->get_collection('midgard_parameter')->find($this->guid, $constraints);
566
567
        // check value
568 11
        if ($value === false || $value === null || $value === "") {
569 2
            if (count($params) == 0) {
570 1
                exception::not_exists();
571 1
                return false;
572
            }
573 2
            foreach ($params as $param) {
574 2
                $stat = $param->delete();
575 2
            }
576 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...
577
        }
578
579 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...
580
        try {
581
            // create new
582 11
            if (count($params) == 0) {
583 11
                $parameter = $om->new_instance(connection::get_em()->getClassMetadata('midgard:midgard_parameter')->getName());
584 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...
585 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...
586 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...
587 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...
588 11
                $om->create($parameter);
589 11
            }
590
            // use existing
591
            else {
592 1
                $parameter = array_shift($params);
593 1
                $parameter->value = $value;
594 1
                $om->update($parameter);
595
            }
596 11
            midgard_connection::get_instance()->set_error(MGD_ERR_OK);
597 11
            return true;
598
        } catch (\Exception $e) {
599
            exception::internal($e);
600
            return false;
601
        }
602
    }
603
604
    /**
605
     * The signature is a little different from original, because Doctrine doesn't support func_get_args() in proxies
606
     */
607 2
    public function parameter($domain, $name, $value = '__UNINITIALIZED__')
608
    {
609 2
        if ($value === '__UNINITIALIZED__') {
610 1
            return $this->get_parameter($domain, $name);
611
        }
612 2
        return $this->set_parameter($domain, $name, $value);
613
    }
614
615 1
    public function has_attachments()
616
    {
617 1
        return $this->get_collection('midgard_attachment')->is_empty($this->guid);
618
    }
619
620 2
    public function list_attachments()
621
    {
622 2
        return $this->get_collection('midgard_attachment')->find($this->guid, array());
623
    }
624
625
    public function find_attachments(array $constraints = array())
626
    {
627
        return $this->get_collection('midgard_attachment')->find($this->guid, $constraints);
628
    }
629
630
    public function delete_attachments(array $constraints = array())
631
    {
632
        return $this->get_collection('midgard_attachment')->delete($this->guid, $constraints);
633
    }
634
635
    /**
636
     *
637
     * @param array $constraints
638
     * @param boolean $delete_blob
639
     * @return boolean False if one or more attachments couldn't be deleted
640
     * @todo Implement delete_blob & return value
641
     */
642
    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...
643
    {
644
        return $this->get_collection('midgard_attachment')->purge($this->guid, $constraints);
645
    }
646
647 3
    public function create_attachment($name, $title = '', $mimetype = '')
648
    {
649 3
        $existing = $this->get_collection('midgard_attachment')->find($this->guid, array('name' => $name));
650 3
        if (count($existing) > 0) {
651 1
            exception::object_name_exists();
652 1
            return null;
653
        }
654 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...
655 3
        $att = $om->new_instance(connection::get_em()->getClassMetadata('midgard:midgard_attachment')->getName());
656
657 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...
658 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...
659 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...
660 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...
661
        try {
662 3
            $om->create($att);
663 3
            midgard_connection::get_instance()->set_error(MGD_ERR_OK);
664 3
            return $att;
665
        } catch (\Exception $e) {
666
            exception::internal($e);
667
            return null;
668
        }
669
    }
670
671
    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...
672
    {
673
        return false;
674
    }
675
676
    /**
677
     * @todo: Tests indicate that $check_dependencies is ignored in the mgd2 extension,
678
     * so we might consider ignoring it, too
679
     */
680 16
    public function purge($check_dependencies = true)
681
    {
682 16
        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...
683
            // This usually means that the object has been purged already
684
            exception::not_exists();
685
            return false;
686
        }
687
        if (   $check_dependencies
688 16
            && $this->has_dependents()) {
689 2
            exception::has_dependants();
690 2
            return false;
691
        }
692
693
        try {
694 16
            $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...
695 16
            $om->purge($this);
696 16
        } catch (\Doctrine\ORM\EntityNotFoundException $e) {
697 1
            exception::not_exists();
698 1
            return false;
699
        } catch (\Exception $e) {
700
            exception::internal($e);
701
            return false;
702
        }
703 16
        midgard_connection::get_instance()->set_error(MGD_ERR_OK);
704
705 16
        return true;
706
    }
707
708 1
    public static function undelete($guid)
709
    {
710 1
        return \midgard_object_class::undelete($guid);
711
    }
712
713
    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...
714
    {
715
        return false;
716
    }
717
718 1
    public static function new_query_builder()
719
    {
720 1
        return new \midgard_query_builder(get_called_class());
721
    }
722
723 1
    public static function new_collector($field, $value)
724
    {
725 1
        return new \midgard_collector(get_called_class(), $field, $value);
726
    }
727
728
    public static function new_reflection_property()
729
    {
730
        return new \midgard_reflection_property(get_called_class());
731
    }
732
733 94
    public function set_guid($guid)
734
    {
735 94
        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...
736 94
    }
737
738
    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...
739
    {
740
        return false;
741
    }
742
743
    /**
744
     * Helper for managing the isapproved and islocked metadata properties
745
     *
746
     * @param string $action the property to manage (either approve or lock)
747
     * @param bool $value
748
     * @return boolean
749
     */
750 4
    private function manage_meta_property($action, $value)
751
    {
752 4
        $user = connection::get_user();
753 4
        if ($user === null) {
754 4
            exception::access_denied();
755 4
            return false;
756
        }
757 4
        if ($action == 'lock') {
758 2
            $flag = 'islocked';
759 4
        } elseif ($action == 'approve') {
760 2
            $flag = 'isapproved';
761 2
        } else {
762
            throw new exception('Unsupported action ' . $action);
763
        }
764
        // same val
765 4
        if ($this->__get('metadata')->$flag === $value) {
766 3
            return false;
767
        }
768 4
        if ($value === false) {
769 2
            $action = 'un' . $action;
770 2
        }
771
772 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...
773
            try {
774 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...
775 4
                $om->{$action}($this);
776 4
            } catch (\Exception $e) {
777
                exception::internal($e);
778
                return false;
779
            }
780 4
        }
781 4
        midgard_connection::get_instance()->set_error(MGD_ERR_OK);
782
783 4
        return true;
784
    }
785
786 2
    public function approve()
787
    {
788 2
        return $this->manage_meta_property("approve", true);
789
    }
790
791 2
    public function is_approved()
792
    {
793 2
        return $this->metadata_isapproved;
0 ignored issues
show
Documentation introduced by
The property metadata_isapproved 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...
794
    }
795
796 1
    public function unapprove()
797
    {
798 1
        return $this->manage_meta_property("approve", false);
799
    }
800
801 2
    public function lock()
802
    {
803 2
        if ($this->is_locked()) {
804 1
            exception::object_is_locked();
805 1
            return false;
806
        }
807 2
        return $this->manage_meta_property("lock", true);
808
    }
809
810 2
    public function is_locked()
811
    {
812 2
        return $this->metadata_islocked;
0 ignored issues
show
Documentation introduced by
The property metadata_islocked 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...
813
    }
814
815 1
    public function unlock()
816
    {
817 1
        return $this->manage_meta_property("lock", false);
818
    }
819
820
    public function get_workspace()
821
    {
822
        return false;
823
    }
824
}
825