midcom_core_dbaobject::__construct()   B
last analyzed

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 558
    public function __construct($id = null)
67
    {
68 558
        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 515
            if (   is_int($id)
75 515
                && $id < 1) {
76
                throw new midcom_error($id . ' is not a valid database ID');
77
            }
78
79
            try {
80 515
                $mgdschemaclass = $this->__mgdschema_class_name__;
81 515
                $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 515
            if (   midcom::get()->config->get('log_level') >= MIDCOM_LOG_DEBUG
89 515
                && $this->__object->guid) {
90 274
                static $guids = [];
91 274
                static $total = 0;
92
93 274
                $total++;
94
95
                //If the GUID was loaded already, write the appropriate log entry
96 274
                if (array_key_exists($this->__object->guid, $guids)) {
97 150
                    $guids[$this->__object->guid]++;
98 150
                    $message = $this->__mgdschema_class_name__ . ' ' . $this->__object->guid;
99 150
                    $message .= ' loaded from db ' . $guids[$this->__object->guid] . ' times.';
100 150
                    $stats = 'Objects loaded (Total/Unique): ' . $total . '/' . count($guids);
101
102 150
                    debug_add($message);
103 150
                    debug_add($stats);
104
                } else {
105 220
                    $guids[$this->__object->guid] = 1;
106
                }
107
            }
108
        }
109
110 558
        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 570
    public function __get($property)
121
    {
122 570
        if ($property === 'metadata') {
123 428
            $this->__metadata ??= new midcom_helper_metadata($this);
124 428
            return $this->__metadata;
125
        }
126
127 562
        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 405
    public function __set($property, $value)
137
    {
138 405
        $this->__object->$property = $value;
139
    }
140
141
    /**
142
     * Shortcut for accessing MidCOM Query Builder
143
     */
144 485
    public static function new_query_builder() : midcom_core_querybuilder
145
    {
146 485
        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 127
    public static function new_collector(?string $domain = null, $value = null) : midcom_core_collector
156
    {
157 127
        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 493
    public function __isset($property)
182
    {
183 493
        return isset($this->__object->$property);
184
    }
185
186
    /**
187
     * API for creating a new object
188
     */
189 313
    public function create() : bool
190
    {
191 313
        return midcom_baseclasses_core_dbobject::create($this);
192
    }
193
194
    /**
195
     * Delete the current object
196
     */
197 209
    public function delete() : bool
198
    {
199 209
        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 179
    public function purge() : bool
216
    {
217 179
        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 212
    public function get_by_id(int $id) : bool
234
    {
235 212
        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 337
    public function get_parent() : ?self
244
    {
245 337
        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 212
    public function refresh() : bool
284
    {
285 212
        return midcom_baseclasses_core_dbobject::refresh($this);
286
    }
287 130
    public function update() : bool
288
    {
289 130
        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 239
    public function is_approved() : bool
304
    {
305 239
        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 470
    public function can_do(string $privilege, $user = null) : bool
338
    {
339 470
        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 122
    public function require_do(string $privilege, ?string $message = null)
346
    {
347 122
        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 210
    private function _delete_dependents() : bool
365
    {
366 210
        foreach ($this->autodelete_dependents as $classname => $link_property) {
367 82
            if (!class_exists($classname)) {
368
                continue;
369
            }
370 82
            $qb = midcom::get()->dbfactory->new_query_builder($classname);
371 82
            $qb->add_constraint($link_property, '=', $this->id);
372 82
            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 210
        return true;
380
    }
381
382
    // Event handlers
383 225
    public function _on_created()
384
    {
385 225
    }
386 247
    public function _on_creating() : bool
387
    {
388 247
        return true;
389
    }
390 166
    public function _on_deleted()
391
    {
392 166
    }
393 210
    public function _on_deleting() : bool
394
    {
395 210
        return $this->_delete_dependents();
396
    }
397 173
    public function _on_loaded()
398
    {
399 173
    }
400 491
    public static function _on_execute(midcom_core_query $query) : bool
401
    {
402 491
        return true;
403
    }
404 486
    public static function _on_process_query_result(array &$result)
405
    {
406 486
    }
407 139
    public static function _on_process_collector_result(array &$result)
408
    {
409 139
    }
410 83
    public function _on_updated()
411
    {
412 83
    }
413 85
    public function _on_updating() : bool
414
    {
415 85
        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 245
    public function get_rcs_message() : string
439
    {
440 245
        return $this->_rcs_message;
441
    }
442
}
443