Completed
Push — master ( 61d134...dd913b )
by Andreas
05:15
created

midgard_object_class::resolve_fqcn()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 2
c 0
b 0
f 0
nc 1
nop 1
dl 0
loc 4
ccs 3
cts 3
cp 1
crap 1
rs 10
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('midgard: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 8
    private static function resolve_fqcn(string $classname) : string
45
    {
46 8
        $cm = connection::get_em()->getClassMetadata('midgard:' . $classname);
47 8
        return $cm->name;
48
    }
49
50 5
    public static function factory(?string $classname, $id = null) : ?dbobject
51
    {
52 5
        if ($classname === null) {
53
            return null;
54
        }
55 5
        $classname = self::resolve_fqcn($classname);
56 5
        return new $classname($id);
57
    }
58
59 4
    public static function undelete(string $guid) : bool
60
    {
61
        try {
62 4
            $classname = self::resolve_classname($guid, true);
63 2
        } catch (exception $e) {
64 2
            return false;
65
        }
66 3
        $classname = self::resolve_fqcn($classname);
67
68 3
        $qb = new \midgard_query_builder($classname);
69 3
        $qb->include_deleted();
70 3
        $qb->add_constraint('guid', '=', $guid);
71 3
        $results = $qb->execute();
72 3
        if (empty($results)) {
73
            exception::not_exists();
74
            return false;
75
        }
76 3
        $entity = $results[0];
77
78 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...
79 1
            exception::internal(new \Exception("Object is not deleted."));
80 1
            return false;
81
        }
82
83
        try {
84 3
            $om = new objectmanager(connection::get_em());
85 3
            $om->undelete($entity);
86
        } catch (\Exception $e) {
87
            exception::internal($e);
88
            return false;
89
        }
90
91 3
        midgard_connection::get_instance()->set_error(MGD_ERR_OK);
92 3
        return true;
93
    }
94
95 7
    public static function get_object_by_guid(string $guid) : dbobject
96
    {
97 7
        if (!mgd_is_guid($guid)) {
98 1
            throw exception::not_exists();
99
        }
100
101 6
        $type = self::resolve_classname($guid);
102 4
        return self::factory($type, $guid);
103
    }
104
105 2
    public static function get_property_up(string $classname) : ?string
106
    {
107 2
        $cm = connection::get_em()->getClassMetadata($classname);
108 2
        return $cm->midgard['upfield'];
109
    }
110
111 2
    public static function get_property_parent(string $classname) : ?string
112
    {
113 2
        $cm = connection::get_em()->getClassMetadata($classname);
114 2
        return $cm->midgard['parentfield'];
115
    }
116
117 7
    public static function has_metadata($classname) : bool
118
    {
119 7
        if (is_string($classname)) {
120 7
            return in_array(metadata::class, class_implements($classname));
121
        }
122 1
        if (is_object($classname)) {
123 1
            return $classname instanceof metadata;
124
        }
125
        return false;
126
    }
127
}
128