Passed
Branch master (b2f909)
by Andreas
04:01
created

midgard_object_class   A

Complexity

Total Complexity 21

Size/Duplication

Total Lines 105
Duplicated Lines 0 %

Test Coverage

Coverage 88.52%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 58
c 1
b 0
f 0
dl 0
loc 105
ccs 54
cts 61
cp 0.8852
rs 10
wmc 21

7 Methods

Rating   Name   Duplication   Size   Complexity  
B resolve_classname() 0 25 7
A get_property_parent() 0 4 1
A has_metadata() 0 9 3
A factory() 0 7 2
A undelete() 0 34 5
A get_object_by_guid() 0 8 2
A get_property_up() 0 4 1
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
8
use midgard\portable\storage\connection;
9
use midgard\portable\storage\subscriber;
10
use midgard\portable\api\error\exception;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, exception. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
11
use midgard\portable\storage\objectmanager;
12
use midgard\portable\storage\interfaces\metadata;
13
use midgard\portable\api\dbobject;
14
15
class midgard_object_class
16
{
17 10
    private static function resolve_classname(string $guid, bool $include_deleted = false) : string
18
    {
19 10
        $qb = connection::get_em()->createQueryBuilder();
20 10
        $qb->from(connection::get_fqcn('midgard_repligard'), 'r')
21 10
            ->select('r.typename, r.object_action')
22 10
            ->where('r.guid = ?1')
23 10
            ->setParameter(1, $guid);
24
25
        try {
26 10
            $result = $qb->getQuery()->getSingleResult();
27 3
        } catch (\Doctrine\ORM\NoResultException $e) {
28 3
            throw exception::not_exists();
29
        }
30
31 10
        if ($result["object_action"] == subscriber::ACTION_PURGE) {
32 2
            throw exception::object_purged();
33
        }
34 9
        if (!$include_deleted && $result["object_action"] == subscriber::ACTION_DELETE) {
35 1
            throw exception::object_deleted();
36
        }
37 8
        if ($include_deleted && !self::has_metadata($result["typename"])) {
38 1
            throw exception::invalid_property_value();
39
        }
40
41 7
        return $result["typename"];
42
    }
43
44 5
    public static function factory(?string $classname, $id = null) : ?dbobject
45
    {
46 5
        if ($classname === null) {
47
            return null;
48
        }
49 5
        $classname = connection::get_fqcn($classname);
50 5
        return new $classname($id);
51
    }
52
53 4
    public static function undelete(string $guid) : bool
54
    {
55
        try {
56 4
            $classname = self::resolve_classname($guid, true);
57 2
        } catch (exception $e) {
58 2
            return false;
59
        }
60 3
        $classname = connection::get_fqcn($classname);
61
62 3
        $qb = new \midgard_query_builder($classname);
63 3
        $qb->include_deleted();
64 3
        $qb->add_constraint('guid', '=', $guid);
65 3
        $results = $qb->execute();
66 3
        if (empty($results)) {
67
            exception::not_exists();
68
            return false;
69
        }
70 3
        $entity = $results[0];
71
72 3
        if (!$entity->metadata_deleted) {
0 ignored issues
show
Bug Best Practice introduced by
The property metadata_deleted does not exist on midgard\portable\api\mgdobject. Since you implemented __get, consider adding a @property annotation.
Loading history...
73 1
            exception::internal(new \Exception("Object is not deleted."));
74 1
            return false;
75
        }
76
77
        try {
78 3
            $om = new objectmanager(connection::get_em());
79 3
            $om->undelete($entity);
80
        } catch (\Exception $e) {
81
            exception::internal($e);
82
            return false;
83
        }
84
85 3
        midgard_connection::get_instance()->set_error(MGD_ERR_OK);
86 3
        return true;
87
    }
88
89 7
    public static function get_object_by_guid(string $guid) : dbobject
90
    {
91 7
        if (!mgd_is_guid($guid)) {
92 1
            throw exception::not_exists();
93
        }
94
95 6
        $type = self::resolve_classname($guid);
96 4
        return self::factory($type, $guid);
97
    }
98
99 2
    public static function get_property_up(string $classname) : ?string
100
    {
101 2
        $cm = connection::get_em()->getClassMetadata($classname);
102 2
        return $cm->midgard['upfield'];
103
    }
104
105 2
    public static function get_property_parent(string $classname) : ?string
106
    {
107 2
        $cm = connection::get_em()->getClassMetadata($classname);
108 2
        return $cm->midgard['parentfield'];
109
    }
110
111 7
    public static function has_metadata($classname) : bool
112
    {
113 7
        if (is_string($classname)) {
114 7
            return in_array(metadata::class, class_implements($classname));
115
        }
116 1
        if (is_object($classname)) {
117 1
            return $classname instanceof metadata;
118
        }
119
        return false;
120
    }
121
}
122