Completed
Push — master ( 5ddc8c...aac2ef )
by Andreas
03:31
created

object::get_workspace()   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 0
dl 0
loc 4
ccs 0
cts 2
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * @author CONTENT CONTROL http://www.contentcontrol-berlin.de/
4
 * @copyright CONTENT CONTROL http://www.contentcontrol-berlin.de/
5
 * @license http://www.gnu.org/licenses/gpl.html GNU General Public License
6
 */
7
namespace midgard\portable\api;
8
9
use midgard\portable\storage\connection;
10
use midgard\portable\storage\objectmanager;
11
use midgard\portable\storage\collection;
12
use midgard\portable\storage\interfaces\metadata as metadata_interface;
13
use midgard\portable\mgdschema\translator;
14
use midgard\portable\api\error\exception;
15
use Doctrine\ORM\Query;
16
use midgard_connection;
17
use Doctrine\Common\Persistence\Proxy;
18
19
abstract class object extends dbobject
20
{
21
    protected $metadata; // compat with mgd behavior: If the schema has no metadata, the property is present anyway
22
23
    public $action = ''; // <== does this need to do anything?
24
25
    private $collections = array();
26
27
    /**
28
     *
29
     * @param mixed $id ID or GUID
30
     */
31 133
    public function __construct($id = null)
32
    {
33 133
        if ($id !== null) {
34 49
            if (is_int($id)) {
35 40
                $this->get_by_id($id);
36 48
            } elseif (is_string($id)) {
37 14
                $this->get_by_guid($id);
38 13
            }
39 47
        }
40 131
    }
41
42
    /**
43
     *
44
     * @param string $classname
45
     * @return collection
46
     */
47 16
    private function get_collection($classname)
48
    {
49 16
        if (!array_key_exists($classname, $this->collections)) {
50 16
            $this->collections[$classname] = new collection($classname);
51 16
        }
52 16
        return $this->collections[$classname];
53
    }
54
55 1
    public function __debugInfo()
56
    {
57 1
        $ret = parent::__debugInfo();
58 1
        if (property_exists($this, 'metadata')) {
59 1
            $metadata = new \stdClass;
60 1
            foreach ($this->cm->getFieldNames() as $name) {
61 1
                if (strpos($name, 'metadata_') !== false) {
62 1
                    $fieldname = str_replace('metadata_', '', $name);
63 1
                    $metadata->$fieldname = $this->__get($name);
64 1
                }
65 1
            }
66 1
            $ret['metadata'] = $metadata;
67 1
        }
68
69 1
        return $ret;
70
    }
71
72 108
    public function __set($field, $value)
73
    {
74 108
        if ($field == 'guid') {
75 6
            return;
76
        }
77 108
        parent::__set($field, $value);
78 108
    }
79
80 123
    public function __get($field)
81
    {
82
        if (   $field === 'metadata'
83 123
            && $this->metadata === null
84 123
            && $this instanceof metadata_interface) {
85 100
            $this->metadata = new metadata($this);
86 100
        }
87
88 123
        return parent::__get($field);
89
    }
90
91 1
    public function __call($method, $args)
92
    {
93 1
        if ($method === 'list') {
94 1
            return $this->_list();
95
        }
96
        throw new \BadMethodCallException("Unknown method " . $method . " on " . get_class($this));
97
    }
98
99 27
    protected function load_parent(array $candidates)
100
    {
101 27
        foreach ($candidates as $candidate) {
102 4
            if ($this->$candidate !== null) {
103
                //Proxies become stale if the object itself is detached, so we have to re-fetch
104 4
                if (   $this->$candidate instanceof \Doctrine\ORM\Proxy\Proxy
105 4
                    && $this->$candidate->__isInitialized()) {
106
                    try {
107 1
                        $this->$candidate->get_by_id($this->$candidate->id);
108 1
                    } catch (exception $e) {
109
                        connection::log()->error('Failed to refresh parent from proxy: ' . $e->getMessage());
110
                        return null;
111
                    }
112 26
                }
113 4
                return $this->$candidate;
114
            }
115 2
        }
116 2
        return null;
117
    }
118
119 42
    public function get_by_id($id)
120
    {
121 42
        $entity = connection::get_em()->find(get_class($this), $id);
122
123 42
        if ($entity === null) {
124 3
            throw exception::not_exists();
125
        }
126
        // According to Doctrine documentation, proxies should be transparent, but in practice,
127
        // there will be problems if we don't force-load
128
        if (   $entity instanceof \Doctrine\ORM\Proxy\Proxy
129 41
            && !$entity->__isInitialized()) {
130
            try {
131 7
                $entity->__load();
132 7
            } catch (\Doctrine\ORM\EntityNotFoundException $e) {
133 1
                throw exception::object_purged();
134
            }
135 6
        }
136 41
        if ($entity instanceof metadata_interface && $entity->{metadata_interface::DELETED_FIELD}) {
137
            // This can happen when the "deleted" entity is still in EM's identity map
138
            throw exception::object_deleted();
139
        }
140 41
        if (empty($entity->guid)) {
141
            // This can happen when a reference proxy to a purged entity is still in EM's identity map
142
            throw exception::object_purged();
143
        }
144
145 41
        $this->populate_from_entity($entity);
146
147 41
        connection::get_em()->detach($entity);
148 41
        midgard_connection::get_instance()->set_error(MGD_ERR_OK);
149 41
        return true;
150
    }
151
152 18
    public function get_by_guid($guid)
153 2
    {
154 18
        if (!mgd_is_guid($guid)) {
155 3
            throw new \InvalidArgumentException("'$guid' is not a valid guid");
156 2
        }
157 15
        $entity = connection::get_em()->getRepository(get_class($this))->findOneBy(array('guid' => $guid));
158 15
        if ($entity === null) {
159
            throw exception::not_exists();
160
        }
161 15
        $this->populate_from_entity($entity);
162
163 15
        connection::get_em()->detach($entity);
164 15
        midgard_connection::get_instance()->set_error(MGD_ERR_OK);
165 15
        return true;
166
    }
167
168 106
    public function create()
169 1
    {
170 106
        if (!empty($this->id)) {
0 ignored issues
show
Documentation introduced by
The property id does not exist on object<midgard\portable\api\object>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
171 2
            exception::duplicate();
172 2
            return false;
173
        }
174 106
        if (   !$this->is_unique()
175 106
            || !$this->check_parent()) {
176 2
            return false;
177
        }
178 106
        if (!$this->check_fields()) {
179 1
            return false;
180
        }
181 2
        try {
182 105
            $om = new objectmanager(connection::get_em());
0 ignored issues
show
Compatibility introduced by
\midgard\portable\storage\connection::get_em() of type object<Doctrine\ORM\EntityManagerInterface> is not a sub-type of object<Doctrine\ORM\EntityManager>. It seems like you assume a concrete implementation of the interface Doctrine\ORM\EntityManagerInterface to be always present.

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

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

Loading history...
183 105
            $om->create($this);
184 105
        } catch (\Exception $e) {
185
            exception::internal($e);
186
            return false;
187
        }
188
189 105
        midgard_connection::get_instance()->set_error(MGD_ERR_OK);
190
191 105
        return ($this->id != 0);
0 ignored issues
show
Documentation introduced by
The property id does not exist on object<midgard\portable\api\object>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
192
    }
193
194 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...
195 1
    {
196 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...
197 1
            midgard_connection::get_instance()->set_error(MGD_ERR_INTERNAL);
198 1
            return false;
199
        }
200 14
        if (!$this->check_fields()) {
201 1
            return false;
202
        }
203
        try {
204 13
            $om = new objectmanager(connection::get_em());
0 ignored issues
show
Compatibility introduced by
\midgard\portable\storage\connection::get_em() of type object<Doctrine\ORM\EntityManagerInterface> is not a sub-type of object<Doctrine\ORM\EntityManager>. It seems like you assume a concrete implementation of the interface Doctrine\ORM\EntityManagerInterface to be always present.

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

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

Loading history...
205 13
            $om->update($this);
206 13
        } catch (\Exception $e) {
207
            exception::internal($e);
208
            return false;
209
        }
210 13
        midgard_connection::get_instance()->set_error(MGD_ERR_OK);
211
212 13
        return true;
213
    }
214
215
    /**
216
     * @todo: Tests indicate that $check_dependencies is ignored in the mgd2 extension,
217
     * so we might consider ignoring it, too
218
     */
219 28
    public function delete($check_dependencies = true)
220
    {
221 28
        if (empty($this->id)) {
0 ignored issues
show
Documentation introduced by
The property id does not exist on object<midgard\portable\api\object>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
222 1
            midgard_connection::get_instance()->set_error(MGD_ERR_INVALID_PROPERTY_VALUE);
223 1
            return false;
224
        }
225
        if (   $check_dependencies
226 27
            && $this->has_dependents()) {
227 4
            exception::has_dependants();
228 4
            return false;
229
        }
230 27
        if (!($this instanceof metadata_interface)) {
231 1
            exception::invalid_property_value();
232 1
            return false;
233
        }
234 26
        if ($this->{metadata_interface::DELETED_FIELD}) {
235 1
            return true;
236
        }
237
238
        try {
239 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...
240 26
            $om->delete($this);
241 26
        } catch (\Exception $e) {
242
            exception::internal($e);
243
            return false;
244
        }
245
246 26
        midgard_connection::get_instance()->set_error(MGD_ERR_OK);
247 26
        return true;
248
    }
249
250 106
    private function is_unique()
251
    {
252 106
        $this->initialize();
253
254 106
        if (empty($this->cm->midgard['unique_fields'])) {
0 ignored issues
show
Bug introduced by
Accessing midgard on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?

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

Available Fixes

  1. Adding an additional type check:

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

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
255 100
            return true;
256
        }
257
258 8
        $qb = connection::get_em()->createQueryBuilder();
259 8
        $qb->from(get_class($this), 'c');
260 8
        $conditions = $qb->expr()->andX();
261 8 View Code Duplication
        if ($this->id) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
Documentation introduced by
The property id does not exist on object<midgard\portable\api\object>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
262
            $parameters = array(
263
                '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...
264
            );
265
            $conditions->add($qb->expr()->neq('c.id', ':id'));
266
        }
267 8
        $found = false;
268 8
        foreach ($this->cm->midgard['unique_fields'] as $field) {
0 ignored issues
show
Bug introduced by
Accessing midgard on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?

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

Available Fixes

  1. Adding an additional type check:

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

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

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

Let’s take a look at an example:

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

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

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

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

Available Fixes

  1. Check for existence of the variable explicitly:

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

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

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

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

Available Fixes

  1. Adding an additional type check:

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

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

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

Available Fixes

  1. Adding an additional type check:

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

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
285 6
                $conditions->add($qb->expr()->isNull('c.' . $this->cm->midgard['upfield']));
0 ignored issues
show
Bug introduced by
Accessing midgard on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?

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

Available Fixes

  1. Adding an additional type check:

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

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

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

Available Fixes

  1. Adding an additional type check:

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

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

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

Available Fixes

  1. Adding an additional type check:

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

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
293
                $conditions->add($qb->expr()->isNull('c.' . $this->cm->midgard['parentfield']));
0 ignored issues
show
Bug introduced by
Accessing midgard on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?

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

Available Fixes

  1. Adding an additional type check:

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

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

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

Available Fixes

  1. Adding an additional type check:

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

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

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

Available Fixes

  1. Adding an additional type check:

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

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
297
            }
298 4
        }
299 7
        $qb->where($conditions)
300 7
            ->setParameters($parameters);
301
302 7
        $qb->select("count(c)");
303 7
        $count = intval($qb->getQuery()->getSingleScalarResult());
304
305 7
        if ($count !== 0) {
306 1
            exception::object_name_exists();
307 1
            return false;
308
        }
309 7
        return true;
310
    }
311
312 106
    private function check_parent()
313
    {
314 106
        $this->initialize();
315
316 106
        if (   empty($this->cm->midgard['parentfield'])
0 ignored issues
show
Bug introduced by
Accessing midgard on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?

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

Available Fixes

  1. Adding an additional type check:

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

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

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

Available Fixes

  1. Adding an additional type check:

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

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

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

Available Fixes

  1. Adding an additional type check:

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

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
322 1
            exception::object_no_parent();
323 1
            return false;
324
        }
325 8
        return true;
326
    }
327
328 106
    private function check_fields()
329
    {
330 106
        $this->initialize();
331
332 106
        foreach ($this->cm->fieldMappings as $name => $field) {
0 ignored issues
show
Bug introduced by
Accessing fieldMappings on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?

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

Available Fixes

  1. Adding an additional type check:

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

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
333 106
            if (   $field['midgard:midgard_type'] == translator::TYPE_GUID
334 106
                && !empty($this->$name)
335 106
                && !mgd_is_guid($this->$name)) {
336 2
                exception::invalid_property_value("'" . $name . "' property's value is not a guid.");
337 2
                return false;
338
            }
339 106
        }
340 105
        return true;
341
    }
342
343
    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...
344
    {
345
        return false;
346
    }
347
348
    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...
349
    {
350
        return false;
351
    }
352
353 34
    public function has_dependents()
354
    {
355 34
        $this->initialize();
356
357 34
        $stat = false;
358
359 34
        if (!empty($this->cm->midgard['upfield'])) {
0 ignored issues
show
Bug introduced by
Accessing midgard on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?

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

Available Fixes

  1. Adding an additional type check:

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

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

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

Available Fixes

  1. Adding an additional type check:

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

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
363 29
                ->setParameter(0, $this->id)
0 ignored issues
show
Documentation introduced by
The property id does not exist on object<midgard\portable\api\object>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
364 29
                ->select("COUNT(c)");
365 29
            $results = intval($qb->getQuery()->getSingleScalarResult());
366 29
            $stat = ($results > 0);
367 29
        }
368
369
        if (   !$stat
370 34
            && !empty($this->cm->midgard['childtypes'])) {
0 ignored issues
show
Bug introduced by
Accessing midgard on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?

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

Available Fixes

  1. Adding an additional type check:

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

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
371 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...
372 27
                $qb = connection::get_em()->createQueryBuilder();
373 27
                $qb->from('midgard:' . $typename, 'c')
374 27
                    ->where('c.' . $parentfield . ' = ?0')
375 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...
376 27
                    ->select("COUNT(c)");
377
378 27
                $results = intval($qb->getQuery()->getSingleScalarResult());
379 27
                $stat = ($results > 0);
380 27
                if ($stat) {
381 3
                    break;
382
                }
383 27
            }
384 27
        }
385
386 34
        return $stat;
387
    }
388
389
    public function get_parent()
390
    {
391
        return null;
392
    }
393
394
    /**
395
     * This function is called list() in Midgard, but that doesn't work in plain PHP
396
     *
397
     * @return array
398
     */
399 1
    private function _list()
400
    {
401 1
        $this->initialize();
402
403 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...
404 1
            $qb = connection::get_em()->createQueryBuilder();
405 1
            $qb->from(get_class($this), 'c')
406 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...
407 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...
408 1
                ->select("c");
409 1
            return $qb->getQuery()->getResult();
410
        }
411
412
        return array();
413
    }
414
415
    /**
416
     * This should return child objects, but only if they are of a different type
417
     * For all other input, an empty array is returned
418
     * (not implemented yet)
419
     *
420
     * @param string $classname
421
     * @return array
422
     */
423
    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...
424
    {
425
        return array();
426
    }
427
428 1
    public function get_by_path($path)
429
    {
430 1
        $parts = explode('/', trim($path, '/'));
431 1
        if (empty($parts)) {
432
            return false;
433
        }
434 1
        $this->initialize();
435
436 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...
437
            return false;
438
        }
439
440 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...
441
442 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...
443 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...
444 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...
445 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...
446 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...
447 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...
448 1
            $parentclass = get_class($this);
449 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...
450 1
            $parentfield = $upfield;
451 1
        } else {
452
            return false;
453
        }
454
455 1
        $name = array_pop($parts);
456 1
        $up = 0;
457 1
        foreach ($parts as $part) {
458 1
            $qb = $this->get_uniquefield_query($parentclass, $field, $part, $parentfield, $up);
459 1
            $qb->select("c.id");
460 1
            $up = intval($qb->getQuery()->getOneOrNullResult(Query::HYDRATE_SINGLE_SCALAR));
461 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...
462
                exception::not_exists();
463
                $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...
464
                $this->set_guid('');
465
                return false;
466
            }
467 1
        }
468
469 1
        $qb = $this->get_uniquefield_query(get_class($this), $field, $name, $upfield, $up);
470 1
        $qb->select("c");
471
472 1
        $entity = $qb->getQuery()->getOneOrNullResult();
473
474 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...
475 1
            exception::not_exists();
476 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...
477 1
            $this->set_guid('');
478 1
            return false;
479
        }
480 1
        $this->populate_from_entity($entity);
481
482 1
        return true;
483
    }
484
485
    /**
486
     * @return int
487
     */
488 1
    protected function get_uniquefield_query($classname, $field, $part, $upfield, $up)
489
    {
490 1
        $qb = connection::get_em()->createQueryBuilder();
491 1
        $qb->from($classname, 'c');
492 1
        $conditions = $qb->expr()->andX();
493 1
        $conditions->add($qb->expr()->eq('c.' . $field, ':' . $field));
494
        $parameters = array(
495
            $field => $part
496 1
        );
497
498 1
        if (empty($up)) {
499
            // If the database was created by Midgard, it might contain 0 instead of NULL, so...
500 1
            $empty_conditions = $qb->expr()->orX()
501 1
                ->add($qb->expr()->isNull('c.' . $upfield))
502 1
                ->add($qb->expr()->eq('c.' . $upfield, '0'));
503 1
            $conditions->add($empty_conditions);
504 1
        } else {
505 1
            $conditions->add($qb->expr()->eq('c.' . $upfield, ':' . $upfield));
506 1
            $parameters[$upfield] = $up;
507
        }
508
509 1
        $qb->where($conditions)
510 1
            ->setParameters($parameters);
511
512 1
        return $qb;
513
    }
514
515
    public function parent()
516
    {
517
        return false;
518
    }
519
520 1
    public function has_parameters()
521
    {
522 1
        return $this->get_collection('midgard_parameter')->is_empty($this->guid);
523
    }
524
525 4
    public function list_parameters($domain = false)
526
    {
527 4
        $constraints = array();
528 4
        if ($domain) {
529 1
            $constraints[] = array("domain", "=", $domain);
530 1
        }
531
532 4
        return $this->get_collection('midgard_parameter')->find($this->guid, $constraints);
533
    }
534
535 3
    public function find_parameters(array $constraints = array())
536
    {
537 3
        return $this->get_collection('midgard_parameter')->find($this->guid, $constraints);
538
    }
539
540 1
    public function delete_parameters(array $constraints = array())
541
    {
542 1
        return $this->get_collection('midgard_parameter')->delete($this->guid, $constraints);
543
    }
544
545 1
    public function purge_parameters(array $constraints = array())
546
    {
547 1
        return $this->get_collection('midgard_parameter')->purge($this->guid, $constraints);
548
    }
549
550 2
    public function get_parameter($domain, $name)
551
    {
552 2
        if (!$this->guid) {
553 1
            return false;
554
        }
555 2
        $qb = connection::get_em()->createQueryBuilder();
556
        $qb
557 2
            ->select('c.value')
558 2
            ->from('midgard:midgard_parameter', 'c')
559 2
            ->where('c.domain = :domain AND c.name = :name AND c.parentguid = :parentguid')
560 2
            ->setParameters(array('domain' => $domain, 'name' => $name, 'parentguid' => $this->guid));
561
562
        // workaround for http://www.doctrine-project.org/jira/browse/DDC-2655
563
        try {
564 2
            return $qb->getQuery()->getOneOrNullResult(Query::HYDRATE_SINGLE_SCALAR);
565
        } catch (\Doctrine\ORM\NoResultException $e) {
566
            return null;
567
        }
568
    }
569
570 11
    public function set_parameter($domain, $name, $value)
571
    {
572
        $constraints = array(
573 11
            array('domain', '=', $domain),
574 11
            array('name', '=', $name),
575 11
        );
576 11
        $params = $this->get_collection('midgard_parameter')->find($this->guid, $constraints);
577
578
        // check value
579 11
        if ($value === false || $value === null || $value === "") {
580 2
            if (count($params) == 0) {
581 1
                exception::not_exists();
582 1
                return false;
583
            }
584 2
            foreach ($params as $param) {
585 2
                $stat = $param->delete();
586 2
            }
587 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...
588
        }
589
590 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...
591
        try {
592
            // create new
593 11
            if (count($params) == 0) {
594 11
                $parameter = $om->new_instance(connection::get_em()->getClassMetadata('midgard:midgard_parameter')->getName());
595 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...
596 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...
597 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...
598 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...
599 11
                $om->create($parameter);
600 11
            }
601
            // use existing
602
            else {
603 1
                $parameter = array_shift($params);
604 1
                $parameter->value = $value;
605 1
                $om->update($parameter);
606
            }
607 11
            midgard_connection::get_instance()->set_error(MGD_ERR_OK);
608 11
            return true;
609
        } catch (\Exception $e) {
610
            exception::internal($e);
611
            return false;
612
        }
613
    }
614
615
    /**
616
     * The signature is a little different from original, because Doctrine doesn't support func_get_args() in proxies
617
     */
618 2
    public function parameter($domain, $name, $value = '__UNINITIALIZED__')
619
    {
620 2
        if ($value === '__UNINITIALIZED__') {
621 1
            return $this->get_parameter($domain, $name);
622
        }
623 2
        return $this->set_parameter($domain, $name, $value);
624
    }
625
626 1
    public function has_attachments()
627
    {
628 1
        return $this->get_collection('midgard_attachment')->is_empty($this->guid);
629
    }
630
631 2
    public function list_attachments()
632
    {
633 2
        return $this->get_collection('midgard_attachment')->find($this->guid, array());
634
    }
635
636
    public function find_attachments(array $constraints = array())
637
    {
638
        return $this->get_collection('midgard_attachment')->find($this->guid, $constraints);
639
    }
640
641
    public function delete_attachments(array $constraints = array())
642
    {
643
        return $this->get_collection('midgard_attachment')->delete($this->guid, $constraints);
644
    }
645
646
    /**
647
     *
648
     * @param array $constraints
649
     * @param boolean $delete_blob
650
     * @return boolean False if one or more attachments couldn't be deleted
651
     * @todo Implement delete_blob & return value
652
     */
653
    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...
654
    {
655
        return $this->get_collection('midgard_attachment')->purge($this->guid, $constraints);
656
    }
657
658 3
    public function create_attachment($name, $title = '', $mimetype = '')
659
    {
660 3
        $existing = $this->get_collection('midgard_attachment')->find($this->guid, array('name' => $name));
661 3
        if (count($existing) > 0) {
662 1
            exception::object_name_exists();
663 1
            return null;
664
        }
665 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...
666 3
        $att = $om->new_instance(connection::get_em()->getClassMetadata('midgard:midgard_attachment')->getName());
667
668 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...
669 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...
670 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...
671 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...
672
        try {
673 3
            $om->create($att);
674 3
            midgard_connection::get_instance()->set_error(MGD_ERR_OK);
675 3
            return $att;
676
        } catch (\Exception $e) {
677
            exception::internal($e);
678
            return null;
679
        }
680
    }
681
682
    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...
683
    {
684
        return false;
685
    }
686
687
    /**
688
     * @todo: Tests indicate that $check_dependencies is ignored in the mgd2 extension,
689
     * so we might consider ignoring it, too
690
     */
691 17
    public function purge($check_dependencies = true)
692
    {
693 17
        if (empty($this->id)) {
0 ignored issues
show
Documentation introduced by
The property id does not exist on object<midgard\portable\api\object>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
694
            // This usually means that the object has been purged already
695
            exception::not_exists();
696
            return false;
697
        }
698
        if (   $check_dependencies
699 17
            && $this->has_dependents()) {
700 2
            exception::has_dependants();
701 2
            return false;
702
        }
703
704
        try {
705 17
            $om = new objectmanager(connection::get_em());
0 ignored issues
show
Compatibility introduced by
\midgard\portable\storage\connection::get_em() of type object<Doctrine\ORM\EntityManagerInterface> is not a sub-type of object<Doctrine\ORM\EntityManager>. It seems like you assume a concrete implementation of the interface Doctrine\ORM\EntityManagerInterface to be always present.

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

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

Loading history...
706 17
            $om->purge($this);
707 17
        } catch (\Doctrine\ORM\EntityNotFoundException $e) {
708 2
            exception::not_exists();
709 2
            return false;
710
        } catch (\Exception $e) {
711
            exception::internal($e);
712
            return false;
713
        }
714 17
        midgard_connection::get_instance()->set_error(MGD_ERR_OK);
715
716 17
        return true;
717
    }
718
719 2
    public static function undelete($guid)
720
    {
721 2
        return \midgard_object_class::undelete($guid);
722
    }
723
724
    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...
725
    {
726
        return false;
727
    }
728
729 1
    public static function new_query_builder()
730
    {
731 1
        return new \midgard_query_builder(get_called_class());
732
    }
733
734 1
    public static function new_collector($field, $value)
735
    {
736 1
        return new \midgard_collector(get_called_class(), $field, $value);
737
    }
738
739
    public static function new_reflection_property()
740
    {
741
        return new \midgard_reflection_property(get_called_class());
742
    }
743
744 106
    public function set_guid($guid)
745
    {
746 106
        parent::__set('guid', $guid);
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (__set() instead of set_guid()). Are you sure this is correct? If so, you might want to change this to $this->__set().

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

Consider the following code:

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

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

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

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

Loading history...
747 106
    }
748
749
    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...
750
    {
751
        return false;
752
    }
753
754
    /**
755
     * Helper for managing the isapproved and islocked metadata properties
756
     *
757
     * @param string $action the property to manage (either approve or lock)
758
     * @param bool $value
759
     * @return boolean
760
     */
761 8
    private function manage_meta_property($action, $value)
762
    {
763 8
        if (!($this instanceof metadata_interface)) {
764 4
            exception::no_metadata();
765 4
            return false;
766
        }
767 4
        $user = connection::get_user();
768 4
        if ($user === null) {
769 4
            exception::access_denied();
770 4
            return false;
771
        }
772 4
        if ($action == 'lock') {
773 2
            $flag = 'islocked';
774 4
        } elseif ($action == 'approve') {
775 2
            $flag = 'isapproved';
776 2
        } else {
777
            throw new exception('Unsupported action ' . $action);
778
        }
779
        // same val
780 4
        if ($this->__get('metadata')->$flag === $value) {
781 3
            return false;
782
        }
783 4
        if ($value === false) {
784 2
            $action = 'un' . $action;
785 2
        }
786
787 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...
788
            try {
789 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...
790 4
                $om->{$action}($this);
791 4
            } catch (\Exception $e) {
792
                exception::internal($e);
793
                return false;
794
            }
795 4
        }
796 4
        midgard_connection::get_instance()->set_error(MGD_ERR_OK);
797
798 4
        return true;
799
    }
800
801 3
    public function approve()
802
    {
803 3
        return $this->manage_meta_property("approve", true);
804
    }
805
806 2
    public function is_approved()
807
    {
808 2
        if (!($this instanceof metadata_interface)) {
809
            exception::no_metadata();
810
            return false;
811
        }
812 2
        return $this->metadata_isapproved;
0 ignored issues
show
Bug introduced by
The property metadata_isapproved does not seem to exist. Did you mean metadata?

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

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

Loading history...
813
    }
814
815 2
    public function unapprove()
816
    {
817 2
        return $this->manage_meta_property("approve", false);
818
    }
819
820 3
    public function lock()
821
    {
822 3
        if ($this->is_locked()) {
823 1
            exception::object_is_locked();
824 1
            return false;
825
        }
826 3
        return $this->manage_meta_property("lock", true);
827
    }
828
829 3
    public function is_locked()
830
    {
831 3
        if (!($this instanceof metadata_interface)) {
832 1
            exception::no_metadata();
833 1
            return false;
834
        }
835 2
        return $this->metadata_islocked;
0 ignored issues
show
Bug introduced by
The property metadata_islocked does not seem to exist. Did you mean metadata?

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

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

Loading history...
836
    }
837
838 2
    public function unlock()
839
    {
840 2
        return $this->manage_meta_property("lock", false);
841
    }
842
843
    public function get_workspace()
844
    {
845
        return false;
846
    }
847
}
848