Passed
Push — master ( 9e7def...40aec1 )
by Andreas
09:29
created

midcom_core_dbaobject::__construct()   B

Complexity

Conditions 10
Paths 12

Size

Total Lines 46
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 27
CRAP Score 10.0045

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 10
eloc 30
c 1
b 0
f 0
nc 12
nop 1
dl 0
loc 46
ccs 27
cts 28
cp 0.9643
crap 10.0045
rs 7.6666

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * @package midcom
4
 * @author The Midgard Project, http://www.midgard-project.org
5
 * @copyright The Midgard Project, http://www.midgard-project.org
6
 * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License
7
 */
8
9
use midcom\events\dbaevent;
10
use midgard\portable\api\error\exception as mgd_exception;
11
use midcom\dba\parameters;
12
use midcom\dba\attachments;
13
use midcom\dba\privileges;
14
use midgard\portable\api\mgdobject;
15
use midcom\dba\softdelete;
16
17
/**
18
 * MidCOM DBA baseclass for MgdSchema object decorators.
19
 *
20
 * @property integer $id Local non-replication-safe database identifier
21
 * @property string $guid
22
 * @property midcom_helper_metadata $metadata the object's metadata
23
 * @package midcom
24
 */
25
abstract class midcom_core_dbaobject
26
{
27
    use parameters, attachments, privileges;
0 ignored issues
show
introduced by
The trait midcom\dba\privileges requires some properties which are not provided by midcom_core_dbaobject: $auth, $user
Loading history...
Bug introduced by
The trait midcom\dba\attachments requires the property $dbfactory which is not provided by midcom_core_dbaobject.
Loading history...
Bug introduced by
The trait midcom\dba\parameters requires the property $dispatcher which is not provided by midcom_core_dbaobject.
Loading history...
28
29
    public string $__midcom_class_name__;
30
31
    public string $__mgdschema_class_name__;
32
33
    /**
34
     * MgdSchema object
35
     */
36
    public mgdobject $__object;
37
38
    private ?midcom_helper_metadata $__metadata = null;
39
40
    /**
41
     * Should the revision control system be enabled for object updates
42
     */
43
    public bool $_use_rcs = true;
44
45
    /**
46
     * Change message used for RCS and the Activity Log summary
47
     */
48
    private string $_rcs_message = '';
49
50
    /**
51
     * Should it be allowed to automatically generate unique name in case of clash
52
     *
53
     * @see http://trac.midgard-project.org/ticket/809
54
     */
55
    public bool $allow_name_catenate = false;
56
57
    /**
58
     * May contain a list of dbaclass => field entries. When deleting an object,
59
     * these dependent objects are automatically deleted beforehand
60
     */
61
    public array $autodelete_dependents = [];
62
63
    /**
64
     * Creates an abstraction layer for an MgdSchema object.
65
     */
66 556
    public function __construct($id = null)
67
    {
68 556
        if (is_object($id)) {
69 299
            if (midcom::get()->dbclassloader->is_midcom_db_object($id)) {
70 13
                $id = $id->__object;
71
            }
72 299
            $this->__object = $id;
73
        } else {
74 513
            if (   is_int($id)
75 513
                && $id < 1) {
76
                throw new midcom_error($id . ' is not a valid database ID');
77
            }
78
79
            try {
80 513
                $mgdschemaclass = $this->__mgdschema_class_name__;
81 513
                $this->__object = new $mgdschemaclass($id);
82 32
            } catch (mgd_exception $e) {
83 32
                debug_add('Constructing ' . $this->__mgdschema_class_name__ . ' object ' . $id . ' failed, reason: ' . $e->getMessage(), MIDCOM_LOG_WARN);
84 32
                throw new midcom_error_midgard($e, $id);
85
            }
86
87
            //Some useful information for performance tuning
88 513
            if (   midcom::get()->config->get('log_level') >= MIDCOM_LOG_DEBUG
89 513
                && $this->__object->guid) {
90 273
                static $guids = [];
91 273
                static $total = 0;
92
93 273
                $total++;
94
95
                //If the GUID was loaded already, write the appropriate log entry
96 273
                if (array_key_exists($this->__object->guid, $guids)) {
97 149
                    $guids[$this->__object->guid]++;
98 149
                    $message = $this->__mgdschema_class_name__ . ' ' . $this->__object->guid;
99 149
                    $message .= ' loaded from db ' . $guids[$this->__object->guid] . ' times.';
100 149
                    $stats = 'Objects loaded (Total/Unique): ' . $total . '/' . count($guids);
101
102 149
                    debug_add($message);
103 149
                    debug_add($stats);
104
                } else {
105 220
                    $guids[$this->__object->guid] = 1;
106
                }
107
            }
108
        }
109
110 556
        if ($this->__object->guid) {
111 402
            midcom_baseclasses_core_dbobject::post_db_load_checks($this);
112
        }
113
    }
114
115
    /**
116
     * Magic getter for object property mapping
117
     *
118
     * @param string $property Name of the property
119
     */
120 568
    public function __get($property)
121
    {
122 568
        if ($property === 'metadata') {
123 427
            $this->__metadata ??= new midcom_helper_metadata($this);
124 427
            return $this->__metadata;
125
        }
126
127 560
        return $this->__object->$property;
128
    }
129
130
    /**
131
     * Magic setter for object property mapping
132
     *
133
     * @param string $property  Name of the property
134
     * @param mixed $value      Property value
135
     */
136 403
    public function __set($property, $value)
137
    {
138 403
        $this->__object->$property = $value;
139
    }
140
141
    /**
142
     * Shortcut for accessing MidCOM Query Builder
143
     */
144 484
    public static function new_query_builder() : midcom_core_querybuilder
145
    {
146 484
        return midcom::get()->dbfactory->new_query_builder(static::class);
147
    }
148
149
    /**
150
     * Shortcut for accessing MidCOM Collector
151
     *
152
     * @param string $domain The domain property of the collector instance
153
     * @param mixed $value Value match for the collector instance
154
     */
155 130
    public static function new_collector(?string $domain = null, $value = null) : midcom_core_collector
156
    {
157 130
        return midcom::get()->dbfactory->new_collector(static::class, $domain, $value);
158
    }
159
160
    /**
161
     * Shortcut for accessing MidCOM object cache.
162
     *
163
     * @param mixed $src GUID of object (ids work but are discouraged)
164
     * @return static Reference to the object
165
     */
166 233
    public static function get_cached($src) : self
167
    {
168 233
        return midcom::get()->dbfactory->get_cached(static::class, $src);
169
    }
170
171
    public function set_guid(string $guid)
172
    {
173
        $this->__object->set_guid($guid);
174
    }
175
176
    /**
177
     * Magic isset test for object property mapping
178
     *
179
     * @param string $property  Name of the property
180
     */
181 492
    public function __isset($property)
182
    {
183 492
        return isset($this->__object->$property);
184
    }
185
186
    /**
187
     * API for creating a new object
188
     */
189 312
    public function create() : bool
190
    {
191 312
        return midcom_baseclasses_core_dbobject::create($this);
192
    }
193
194
    /**
195
     * Delete the current object
196
     */
197 208
    public function delete() : bool
198
    {
199 208
        return midcom_baseclasses_core_dbobject::delete($this);
200
    }
201
202
    /**
203
     * Undelete object defined by a GUID
204
     *
205
     * @return int Size of undeleted objects
206
     */
207
    public static function undelete(string $guid) : int
208
    {
209
        return softdelete::undelete([$guid]);
210
    }
211
212
    /**
213
     * Purge the current object from database
214
     */
215 178
    public function purge() : bool
216
    {
217 178
        return $this->__object->purge();
218
    }
219
220
    /**
221
     * Delete the current object tree, starting from this object
222
     */
223 1
    public function delete_tree() : bool
224
    {
225 1
        return midcom_baseclasses_core_dbobject::delete_tree($this);
226
    }
227
228
    public function get_by_guid(string $guid) : bool
229
    {
230
        return midcom_baseclasses_core_dbobject::get_by_guid($this, $guid);
231
    }
232
233 211
    public function get_by_id(int $id) : bool
234
    {
235 211
        return midcom_baseclasses_core_dbobject::get_by_id($this, $id);
236
    }
237
238 1
    public function get_by_path(string $path) : bool
239
    {
240 1
        return midcom_baseclasses_core_dbobject::get_by_path($this, $path);
241
    }
242
243 335
    public function get_parent() : ?self
244
    {
245 335
        return midcom::get()->dbfactory->get_parent($this);
246
    }
247
    public function has_dependents() : bool
248
    {
249
        return $this->__object->has_dependents();
250
    }
251
    public function has_attachments() : bool
252
    {
253
        return $this->__object->has_attachments();
254
    }
255
    public function find_attachments(array $constraints)
256
    {
257
        return $this->__object->find_attachments($constraints);
258
    }
259
    public function delete_attachments(array $constraints)
260
    {
261
        return $this->__object->delete_attachments($constraints);
262
    }
263
    public function purge_attachments(array $constraints)
264
    {
265
        return $this->__object->purge_attachments($constraints);
266
    }
267
    public function has_parameters() : bool
268
    {
269
        return $this->__object->has_parameters();
270
    }
271
    public function find_parameters(array $constraints)
272
    {
273
        return $this->__object->find_parameters($constraints);
274
    }
275
    public function delete_parameters(array $constraints)
276
    {
277
        return $this->__object->delete_parameters($constraints);
278
    }
279
    public function purge_parameters(array $constraints)
280
    {
281
        return $this->__object->purge_parameters($constraints);
282
    }
283 211
    public function refresh() : bool
284
    {
285 211
        return midcom_baseclasses_core_dbobject::refresh($this);
286
    }
287 129
    public function update() : bool
288
    {
289 129
        return midcom_baseclasses_core_dbobject::update($this);
290
    }
291 1
    public function is_locked() : bool
292
    {
293 1
        return $this->__object->is_locked();
294
    }
295 45
    public function lock() : bool
296
    {
297 45
        return $this->__object->is_locked() || $this->__object->lock();
298
    }
299 13
    public function unlock() : bool
300
    {
301 13
        return !$this->__object->is_locked() || $this->__object->unlock();
302
    }
303 238
    public function is_approved() : bool
304
    {
305 238
        return $this->__object->is_approved();
306
    }
307 1
    public function approve() : bool
308
    {
309 1
        if ($this->__object->is_approved()) {
310
            return true;
311
        }
312 1
        if ($this->__object->approve()) {
313
            midcom::get()->dispatcher->dispatch(new dbaevent($this), dbaevent::APPROVE);
314
            return true;
315
        }
316 1
        return false;
317
    }
318
319 1
    public function unapprove() : bool
320
    {
321 1
        if (!$this->__object->is_approved()) {
322 1
            return true;
323
        }
324
        if ($this->__object->unapprove()) {
325
            midcom::get()->dispatcher->dispatch(new dbaevent($this), dbaevent::UNAPPROVE);
326
            return true;
327
        }
328
        return false;
329
    }
330
331 28
    public function get_properties() : array
332
    {
333 28
        return midcom_helper_reflector::get_object_fieldnames($this);
334
    }
335
336
    // ACL Shortcuts
337 469
    public function can_do(string $privilege, $user = null) : bool
338
    {
339 469
        return midcom::get()->auth->can_do($privilege, $this, $user);
340
    }
341 11
    public function can_user_do(string $privilege, $user = null) : bool
342
    {
343 11
        return midcom::get()->auth->can_user_do($privilege, $user, $this->__midcom_class_name__);
344
    }
345 124
    public function require_do(string $privilege, ?string $message = null)
346
    {
347 124
        midcom::get()->auth->require_do($privilege, $this, $message);
348
    }
349
    public function require_user_do(string $privilege, ?string $message = null)
350
    {
351
        midcom::get()->auth->require_user_do($privilege, $message, $this->__midcom_class_name__);
352
    }
353
354
    // DBA API
355 14
    public function get_class_magic_default_privileges() : array
356
    {
357 14
        return [
358 14
            'EVERYONE' => [],
359 14
            'ANONYMOUS' => [],
360 14
            'USERS' => []
361 14
        ];
362
    }
363
364 209
    private function _delete_dependents() : bool
365
    {
366 209
        foreach ($this->autodelete_dependents as $classname => $link_property) {
367 81
            if (!class_exists($classname)) {
368
                continue;
369
            }
370 81
            $qb = midcom::get()->dbfactory->new_query_builder($classname);
371 81
            $qb->add_constraint($link_property, '=', $this->id);
372 81
            foreach ($qb->execute() as $result) {
373 24
                if (!$result->delete()) {
374
                    debug_add('Could not delete dependent ' . $classname . ' #' . $result->id . ', aborting', MIDCOM_LOG_WARN);
375
                    return false;
376
                }
377
            }
378
        }
379 209
        return true;
380
    }
381
382
    // Event handlers
383 224
    public function _on_created()
384
    {
385 224
    }
386 223
    public function _on_creating() : bool
387
    {
388 223
        return true;
389
    }
390 165
    public function _on_deleted()
391
    {
392 165
    }
393 209
    public function _on_deleting() : bool
394
    {
395 209
        return $this->_delete_dependents();
396
    }
397 173
    public function _on_loaded()
398
    {
399 173
    }
400 490
    public static function _on_execute(midcom_core_query $query) : bool
401
    {
402 490
        return true;
403
    }
404 485
    public static function _on_process_query_result(array &$result)
405
    {
406 485
    }
407 143
    public static function _on_process_collector_result(array &$result)
408
    {
409 143
    }
410 83
    public function _on_updated()
411
    {
412 83
    }
413 80
    public function _on_updating() : bool
414
    {
415 80
        return true;
416
    }
417
    public function _on_imported()
418
    {
419
    }
420
    public function _on_importing() : bool
421
    {
422
        return true;
423
    }
424
425
    // functions related to the RCS service.
426
    public function disable_rcs()
427
    {
428
        $this->_use_rcs = false;
429
    }
430
    public function enable_rcs()
431
    {
432
        $this->_use_rcs = true;
433
    }
434 1
    public function set_rcs_message(string $msg)
435
    {
436 1
        $this->_rcs_message = $msg;
437
    }
438 244
    public function get_rcs_message() : string
439
    {
440 244
        return $this->_rcs_message;
441
    }
442
}
443