Passed
Pull Request — master (#17)
by Anton
03:14
created

Entity::selectBasic()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 2
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * @package Cadmium\System\Modules\Entitizer
5
 * @author Anton Romanov
6
 * @copyright Copyright (c) 2015-2017, Anton Romanov
7
 * @link http://cadmium-cms.com
8
 */
9
10
namespace Modules\Entitizer\Utils {
11
12
	use Modules\Entitizer, DB;
13
14
	abstract class Entity extends Cache {
15
16
		use Entity\Collection, Entity\Modify;
17
18
		protected $definition = null, $dataset = null;
19
20
		/**
21
		 * Select a basic entity from DB
22
		 *
23
		 * @return DB\Result|false : the selection result object or false on failure
24
		 */
25
26
		private function selectBasic(string $name, string $value) {
27
28
			$selection = array_keys($this->definition->getParams());
29
30
			return DB::select(static::$table, $selection, [$name => $value], null, 1);
31
		}
32
33
		/**
34
		 * Select a nesting entity from DB
35
		 *
36
		 * @return DB\Result|false : the selection result object or false on failure
37
		 */
38
39
		private function selectNesting(string $name, string $value) {
40
41
			# Process selection
42
43
			$selection = array_keys($this->definition->getParams());
44
45
			foreach ($selection as $key => $field) $selection[$key] = ('ent.' . $field);
46
47
			# Process query
48
49
			$query = ("SELECT " . implode(', ', $selection) . ", rel.ancestor as parent_id ") .
50
51
			         ("FROM " . static::$table . " ent ") .
52
53
			         ("LEFT JOIN " . static::$table_relations . " rel ON rel.descendant = ent.id AND rel.depth = 1 ") .
54
55
			         ("WHERE ent." . $name . " = '" . addslashes($value) . "' LIMIT 1");
56
57
			# ------------------------
58
59
			return DB::send($query);
60
		}
61
62
		/**
63
		 * Update the entity dataset with a selected data. Also updates every entity object having an identical id
64
		 *
65
		 * @return true : always true ;)
66
		 */
67
68
		protected function setData(array $data) : bool {
69
70
			$id = $this->definition->getParam('id')->cast($data['id']);
71
72
			# Import data
73
74
			if (isset(self::$cache[static::$table][$id])) {
75
76
				$this->dataset = self::$cache[static::$table][$id]->dataset;
77
			}
78
79
			# Update data
80
81
			$this->dataset->update($data);
82
83
			# Cache entity
84
85
			self::$cache[static::$table][$this->id] = $this;
0 ignored issues
show
Documentation introduced by
The property id does not exist on object<Modules\Entitizer\Utils\Entity>. 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...
86
87
			# ------------------------
88
89
			return true;
90
		}
91
92
		/**
93
		 * Constructor
94
		 */
95
96
		public function __construct() {
97
98
			# Get definition
99
100
			$this->definition = Entitizer::getDefinition(static::$table);
101
102
			# Preset data
103
104
			$this->dataset = Entitizer::getDataset(static::$table);
105
		}
106
107
		/**
108
		 * Initialize the entity by a unique param (default: id)
109
		 *
110
		 * @return bool : true on success or false on failure
111
		 */
112
113
		public function init($value, string $name = 'id') : bool {
114
115
			if (0 !== $this->id) return false;
0 ignored issues
show
Documentation introduced by
The property id does not exist on object<Modules\Entitizer\Utils\Entity>. 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...
116
117
			# Get initiation index
118
119
			if (false === ($index = $this->definition->getIndex($name))) return false;
120
121
			if (($index->type !== 'PRIMARY') && ($index->type !== 'UNIQUE')) return false;
122
123
			# Process name & value
124
125
			$name = $index->name; $value = $this->definition->getParam($name)->cast($value);
126
127
			# Select entity from DB
128
129
			if (!static::$nesting) $this->selectBasic($name, $value); else $this->selectNesting($name, $value);
130
131
			# ------------------------
132
133
			return ((DB::getLast() && (DB::getLast()->rows === 1)) ? $this->setData(DB::getLast()->getRow()) : false);
134
		}
135
136
		/**
137
		 * Check whether another entity with a given unique param value exists.
138
		 * The method helps you to find out the possibility of changing the entity's unique param value to the given one
139
		 *
140
		 * @return int|false : the number of entities found (0 or 1) or false on error
141
		 */
142
143
		public function check($value, string $name) {
144
145
			# Get initiation index
146
147
			if (false === ($index = $this->definition->getIndex($name))) return false;
148
149
			if ($index->type !== 'UNIQUE') return false;
150
151
			# Process name & value
152
153
			$name = $index->name; $value = $this->definition->getParam($name)->cast($value);
154
155
			# Select entity from DB
156
157
			$condition = ($name . " = '" . addslashes($value) . "' AND id != " . $this->id);
0 ignored issues
show
Documentation introduced by
The property id does not exist on object<Modules\Entitizer\Utils\Entity>. 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...
158
159
			DB::select(static::$table, 'id', $condition, null, 1);
160
161
			# ------------------------
162
163
			return ((DB::getLast() && DB::getLast()->status) ? DB::getLast()->rows : false);
164
		}
165
166
		/**
167
		 * Get the entity definition
168
		 */
169
170
		public function getDefinition() : Entitizer\Utils\Definition {
171
172
			return $this->definition;
173
		}
174
175
		/**
176
		 * Get a param value
177
		 *
178
		 * @return mixed|null : the value or null if the param does not exist
179
		 */
180
181
		public function get(string $name) {
182
183
			return $this->dataset->get($name);
184
		}
185
186
		/**
187
		 * Get the array of params and their values
188
		 */
189
190
		public function getData() : array {
191
192
			return $this->dataset->getData();
193
		}
194
195
		/**
196
		 * An alias for the get method
197
		 */
198
199
		public function __get(string $name) {
200
201
			return $this->dataset->__get($name);
202
		}
203
204
		/**
205
		 * Check if a param exists
206
		 */
207
208
		 public function __isset(string $name) : bool {
209
210
 			return $this->dataset->__isset($name);
211
 		}
212
	}
213
}
214