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 559
    public function __construct($id = null)
67
    {
68 559
        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 516
            if (   is_int($id)
75 516
                && $id < 1) {
76
                throw new midcom_error($id . ' is not a valid database ID');
77
            }
78
79
            try {
80 516
                $mgdschemaclass = $this->__mgdschema_class_name__;
81 516
                $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 516
            if (   midcom::get()->config->get('log_level') >= MIDCOM_LOG_DEBUG
89 516
                && $this->__object->guid) {
90 275
                static $guids = [];
91 275
                static $total = 0;
92
93 275
                $total++;
94
95
                //If the GUID was loaded already, write the appropriate log entry
96 275
                if (array_key_exists($this->__object->guid, $guids)) {
97 151
                    $guids[$this->__object->guid]++;
98 151
                    $message = $this->__mgdschema_class_name__ . ' ' . $this->__object->guid;
99 151
                    $message .= ' loaded from db ' . $guids[$this->__object->guid] . ' times.';
100 151
                    $stats = 'Objects loaded (Total/Unique): ' . $total . '/' . count($guids);
101
102 151
                    debug_add($message);
103 151
                    debug_add($stats);
104
                } else {
105 221
                    $guids[$this->__object->guid] = 1;
106
                }
107
            }
108
        }
109
110 559
        if ($this->__object->guid) {
111 403
            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 571
    public function __get($property)
121
    {
122 571
        if ($property === 'metadata') {
123 429
            $this->__metadata ??= new midcom_helper_metadata($this);
124 429
            return $this->__metadata;
125
        }
126
127 563
        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 406
    public function __set($property, $value)
137
    {
138 406
        $this->__object->$property = $value;
139
    }
140
141
    /**
142
     * Shortcut for accessing MidCOM Query Builder
143
     */
144 486
    public static function new_query_builder() : midcom_core_querybuilder
145
    {
146 486
        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 234
    public static function get_cached($src) : self
167
    {
168 234
        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 494
    public function __isset($property)
182
    {
183 494
        return isset($this->__object->$property);
184
    }
185
186
    /**
187
     * API for creating a new object
188
     */
189 314
    public function create() : bool
190
    {
191 314
        return midcom_baseclasses_core_dbobject::create($this);
192
    }
193
194
    /**
195
     * Delete the current object
196
     */
197 210
    public function delete() : bool
198
    {
199 210
        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 180
    public function purge() : bool
216
    {
217 180
        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 213
    public function get_by_id(int $id) : bool
234
    {
235 213
        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 338
    public function get_parent() : ?self
244
    {
245 338
        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 213
    public function refresh() : bool
284
    {
285 213
        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 240
    public function is_approved() : bool
304
    {
305 240
        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 471
    public function can_do(string $privilege, $user = null) : bool
338
    {
339 471
        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 123
    public function require_do(string $privilege, ?string $message = null)
346
    {
347 123
        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 211
    private function _delete_dependents() : bool
365
    {
366 211
        foreach ($this->autodelete_dependents as $classname => $link_property) {
367 83
            if (!class_exists($classname)) {
368
                continue;
369
            }
370 83
            $qb = midcom::get()->dbfactory->new_query_builder($classname);
371 83
            $qb->add_constraint($link_property, '=', $this->id);
372 83
            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 211
        return true;
380
    }
381
382
    // Event handlers
383 226
    public function _on_created()
384
    {
385 226
    }
386 247
    public function _on_creating() : bool
387
    {
388 247
        return true;
389
    }
390 167
    public function _on_deleted()
391
    {
392 167
    }
393 211
    public function _on_deleting() : bool
394
    {
395 211
        return $this->_delete_dependents();
396
    }
397 174
    public function _on_loaded()
398
    {
399 174
    }
400 492
    public static function _on_execute(midcom_core_query $query) : bool
401
    {
402 492
        return true;
403
    }
404 487
    public static function _on_process_query_result(array &$result)
405
    {
406 487
    }
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 246
    public function get_rcs_message() : string
439
    {
440 246
        return $this->_rcs_message;
441
    }
442
}
443