Completed
Push — master ( 51b910...e719dd )
by Joschi
03:23
created

ObjectProxy::isDeleted()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 4
ccs 0
cts 4
cp 0
crap 2
rs 10
1
<?php
2
3
/**
4
 * apparat-object
5
 *
6
 * @category    Apparat
7
 * @package     Apparat\Object
8
 * @subpackage  Apparat\Object\Domain
9
 * @author      Joschi Kuphal <[email protected]> / @jkphl
10
 * @copyright   Copyright © 2016 Joschi Kuphal <[email protected]> / @jkphl
11
 * @license     http://opensource.org/licenses/MIT The MIT License (MIT)
12
 */
13
14
/***********************************************************************************
15
 *  The MIT License (MIT)
16
 *
17
 *  Copyright © 2016 Joschi Kuphal <[email protected]> / @jkphl
18
 *
19
 *  Permission is hereby granted, free of charge, to any person obtaining a copy of
20
 *  this software and associated documentation files (the "Software"), to deal in
21
 *  the Software without restriction, including without limitation the rights to
22
 *  use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
23
 *  the Software, and to permit persons to whom the Software is furnished to do so,
24
 *  subject to the following conditions:
25
 *
26
 *  The above copyright notice and this permission notice shall be included in all
27
 *  copies or substantial portions of the Software.
28
 *
29
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
30
 *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
31
 *  FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
32
 *  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
33
 *  IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
34
 *  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35
 ***********************************************************************************/
36
37
namespace Apparat\Object\Domain\Model\Object;
38
39
use Apparat\Kernel\Ports\Kernel;
40
use Apparat\Object\Domain\Model\Path\ApparatUrl;
41
use Apparat\Object\Domain\Model\Path\RepositoryPathInterface;
42
use Apparat\Object\Domain\Model\Relation\RelationInterface;
43
use Apparat\Object\Domain\Repository\Service;
44
45
/**
46
 * Object proxy (lazy loading)
47
 *
48
 * @package Apparat\Object
49
 * @subpackage Apparat\Object\Domain
50
 */
51
class ObjectProxy implements ObjectInterface
52
{
53
    /**
54
     * Apparat object URL
55
     *
56
     * @var ApparatUrl
57
     */
58
    protected $url = null;
59
    /**
60
     * Object
61
     *
62
     * @var ObjectInterface
63
     */
64
    protected $object = null;
65
66
    /*******************************************************************************
67
     * PUBLIC METHODS
68
     *******************************************************************************/
69
70
    /**
71
     * Object proxy constructor
72
     *
73
     * @param ApparatUrl $url Apparat object URL
74
     */
75
    public function __construct(ApparatUrl $url)
76
    {
77
        $this->url = $url;
78
    }
79
80
    /**
81
     * Return the object repository path
82
     *
83
     * @return RepositoryPathInterface Object repository path
84
     */
85
    public function getRepositoryPath()
86
    {
87
        // If the object has already been instantiated
88
        if ($this->object instanceof ObjectInterface) {
89
            return $this->object->getRepositoryPath();
90
        }
91
92
        return $this->url->getLocalPath();
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->url->getLocalPath(); (Apparat\Object\Domain\Model\Path\LocalPath) is incompatible with the return type declared by the interface Apparat\Object\Domain\Mo...face::getRepositoryPath of type Apparat\Object\Domain\Mo...RepositoryPathInterface.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
93
    }
94
95
    /**
96
     * Return the object property data
97
     *
98
     * @return array Object property data
99
     */
100
    public function getPropertyData()
101
    {
102
        return $this->object()->getPropertyData();
103
    }
104
105
    /**
106
     * Return the enclosed remote object
107
     *
108
     * @return ObjectInterface Remote object
109
     */
110
    protected function object()
111
    {
112
        // Lazy-load the remote object if necessary
113
        if (!$this->object instanceof ObjectInterface) {
114
            // Instantiate the local object repository, load and return the object
115
            $this->object = Kernel::create(Service::class)->get($this->url)->loadObject($this->url->getLocalPath());
116
        }
117
118
        return $this->object;
119
    }
120
121
    /**
122
     * Return the object payload
123
     *
124
     * @return string Object payload
125
     */
126
    public function getPayload()
127
    {
128
        return $this->object()->getPayload();
129
    }
130
131
    /**
132
     * Set the payload
133
     *
134
     * @param string $payload Payload
135
     * @return ObjectInterface Self reference
136
     */
137
    public function setPayload($payload)
138
    {
139
        return $this->object()->setPayload($payload);
140
    }
141
142
    /**
143
     * Return the object ID
144
     *
145
     * @return Id Object ID
146
     */
147
    public function getId()
148
    {
149
        return $this->object()->getId();
150
    }
151
152
    /**
153
     * Return the object type
154
     *
155
     * @return Type Object type
156
     */
157
    public function getType()
158
    {
159
        return $this->object()->getType();
160
    }
161
162
    /**
163
     * Return the object revision
164
     *
165
     * @return Revision Object revision
166
     */
167
    public function getRevision()
168
    {
169
        return $this->object()->getRevision();
170
    }
171
172
    /**
173
     * Return the latitude
174
     *
175
     * @return float Latitude
176
     */
177
    public function getLatitude()
178
    {
179
        return $this->object()->getLatitude();
180
    }
181
182
    /**
183
     * Set the latitude
184
     *
185
     * @param float $latitude Latitude
186
     * @return ObjectInterface Self reference
187
     */
188
    public function setLatitude($latitude)
189
    {
190
        return $this->object()->setLatitude($latitude);
191
    }
192
193
    /**
194
     * Return the longitude
195
     *
196
     * @return float Longitude
197
     */
198
    public function getLongitude()
199
    {
200
        return $this->object()->getLongitude();
201
    }
202
203
    /**
204
     * Set the longitude
205
     *
206
     * @param float $longitude Longitude
207
     * @return ObjectInterface Self reference
208
     */
209
    public function setLongitude($longitude)
210
    {
211
        return $this->object()->setLongitude($longitude);
212
    }
213
214
    /**
215
     * Return the elevation
216
     *
217
     * @return float Elevation
218
     */
219
    public function getElevation()
220
    {
221
        return $this->object()->getElevation();
222
    }
223
224
    /**
225
     * Set the elevation
226
     *
227
     * @param float $elevation
228
     * @return ObjectInterface Self reference
229
     */
230
    public function setElevation($elevation)
231
    {
232
        return $this->object()->setElevation($elevation);
233
    }
234
235
236
    /**
237
     * Return the object draft mode
238
     *
239
     * @return boolean Object draft mode
240
     */
241
    public function isDraft()
242
    {
243
        return $this->object()->isDraft();
244
    }
245
246
    /**
247
     * Return whether the object is in dirty state
248
     *
249
     * @return boolean Dirty state
250
     */
251
    public function isDirty()
252
    {
253
        return $this->object()->isDirty();
254
    }
255
256
    /**
257
     * Return whether the object is in mutated state
258
     *
259
     * @return boolean Mutated state
260
     */
261
    public function isMutated()
262
    {
263
        return $this->object()->isMutated();
264
    }
265
266
    /**
267
     * Return the creation date & time
268
     *
269
     * @return \DateTimeImmutable Creation date & time
270
     */
271
    public function getCreated()
272
    {
273
        return $this->object()->getCreated();
274
    }
275
276
    /**
277
     * Return the deletion date & time
278
     *
279
     * @return \DateTimeImmutable Deletion date & time
280
     */
281
    public function getDeleted()
282
    {
283
        return $this->object()->getDeleted();
284
    }
285
286
    /**
287
     * Return the modification date & time
288
     *
289
     * @return \DateTimeImmutable Modification date & time
290
     */
291
    public function getModified()
292
    {
293
        return $this->object()->getModified();
294
    }
295
296
    /**
297
     * Return the publication date & time
298
     *
299
     * @return \DateTimeImmutable Publication date & time
300
     */
301
    public function getPublished()
302
    {
303
        return $this->object()->getPublished();
304
    }
305
306
    /**
307
     * Return the object title
308
     *
309
     * @return string Object title
310
     */
311
    public function getTitle()
312
    {
313
        return $this->object()->getTitle();
314
    }
315
316
    /**
317
     * Set the title
318
     *
319
     * @param string $title Title
320
     * @return ObjectInterface Self reference
321
     */
322
    public function setTitle($title)
323
    {
324
        return $this->object()->setTitle($title);
325
    }
326
327
    /**
328
     * Return the object slug
329
     *
330
     * @return string Object slug
331
     */
332
    public function getSlug()
333
    {
334
        return $this->object()->getSlug();
335
    }
336
337
    /**
338
     * Set the slug
339
     *
340
     * @param string $slug Slug
341
     * @return ObjectInterface Self reference
342
     */
343
    public function setSlug($slug)
344
    {
345
        return $this->object()->setSlug($slug);
346
    }
347
348
349
    /**
350
     * Return the object description
351
     *
352
     * @return string Object description
353
     */
354
    public function getDescription()
355
    {
356
        return $this->object()->getDescription();
357
    }
358
359
    /**
360
     * Set the description
361
     *
362
     * @param string $description Description
363
     * @return ObjectInterface Self reference
364
     */
365
    public function setDescription($description)
366
    {
367
        return $this->object()->setDescription($description);
368
    }
369
370
    /**
371
     * Return the object abstract
372
     *
373
     * @return string Object abstract
374
     */
375
    public function getAbstract()
376
    {
377
        return $this->object()->getAbstract();
378
    }
379
380
    /**
381
     * Set the abstract
382
     *
383
     * @param string $abstract Abstract
384
     * @return ObjectInterface Self reference
385
     */
386
    public function setAbstract($abstract)
387
    {
388
        return $this->object()->setAbstract($abstract);
389
    }
390
391
    /**
392
     * Return all object keywords
393
     *
394
     * @return array Object keywords
395
     */
396
    public function getKeywords()
397
    {
398
        return $this->object()->getKeywords();
399
    }
400
401
    /**
402
     * Set the keywords
403
     *
404
     * @param array $keywords Keywords
405
     * @return ObjectInterface Self reference
406
     */
407
    public function setKeywords(array $keywords)
408
    {
409
        return $this->object()->setKeywords($keywords);
410
    }
411
412
    /**
413
     * Return the license
414
     *
415
     * @return string License
416
     */
417
    public function getLicense()
418
    {
419
        return $this->object()->getLicense();
420
    }
421
422
    /**
423
     * Set the license
424
     *
425
     * @param string $license License
426
     * @return ObjectInterface Self reference
427
     */
428
    public function setLicense($license)
429
    {
430
        return $this->object()->setLicense($license);
431
    }
432
433
    /**
434
     * Return the language
435
     *
436
     * @return string Language
437
     */
438
    public function getLanguage()
439
    {
440
        return $this->object()->getLanguage();
441
    }
442
443
    /**
444
     * Return the privacy
445
     *
446
     * @return string Privacy
447
     */
448
    public function getPrivacy()
449
    {
450
        return $this->object()->getPrivacy();
451
    }
452
453
    /**
454
     * Set the privacy
455
     *
456
     * @param string $privacy Privacy
457
     * @return ObjectInterface Self reference
458
     */
459
    public function setPrivacy($privacy)
460
    {
461
        return $this->object()->setPrivacy($privacy);
462
    }
463
464
    /**
465
     * Return all object categories
466
     *
467
     * @return array Object categories
468
     */
469
    public function getCategories()
470
    {
471
        return $this->object()->getCategories();
472
    }
473
474
    /**
475
     * Set the categories
476
     *
477
     * @param array $categories Categories
478
     * @return ObjectInterface Self reference
479
     */
480
    public function setCategories(array $categories)
481
    {
482
        return $this->object()->setCategories($categories);
483
    }
484
485
    /**
486
     * Get a domain property value
487
     *
488
     * Multi-level properties might be traversed by property name paths separated with colons (":").
489
     *
490
     * @param string $property Property name
491
     * @return mixed Property value
492
     */
493
    public function getDomainProperty($property)
494
    {
495
        return $this->object()->getDomainProperty($property);
496
    }
497
498
    /**
499
     * Set a domain property value
500
     *
501
     * @param string $property Property name
502
     * @param mixed $value Property value
503
     * @return ObjectInterface Self reference
504
     */
505
    public function setDomainProperty($property, $value)
506
    {
507
        return $this->object()->setDomainProperty($property, $value);
508
    }
509
510
    /**
511
     * Get a processing instruction
512
     *
513
     * @param string $procInst Processing instruction name
514
     * @return mixed Processing instruction
515
     */
516
    public function getProcessingInstruction($procInst)
517
    {
518
        return $this->object()->getProcessingInstruction($procInst);
519
    }
520
521
    /**
522
     * Set a processing instruction
523
     *
524
     * @param string $procInst Processing instruction name
525
     * @param mixed $value Processing instruction
526
     * @return ObjectInterface Self reference
527
     */
528
    public function setProcessingInstruction($procInst, $value)
529
    {
530
        return $this->object()->setProcessingInstruction($procInst, $value);
531
    }
532
533
    /**
534
     * Return the absolute object URL
535
     *
536
     * @return string
537
     */
538
    public function getAbsoluteUrl()
539
    {
540
        return strval($this->url);
541
    }
542
543
    /**
544
     * Generic caller
545
     *
546
     * @param string $name Method name
547
     * @param array $arguments Method arguments
548
     */
549
    public function __call($name, $arguments)
550
    {
551
        $object = $this->object();
552
        if (is_callable(array($object, $name))) {
553
            return $object->$name(...$arguments);
554
        }
555
556
        throw new InvalidArgumentException(
557
            sprintf('Invalid object proxy method "%s"', $name),
558
            InvalidArgumentException::INVALID_OBJECT_PROXY_METHOD
559
        );
560
    }
561
562
    /**
563
     * Use a specific object revision
564
     *
565
     * @param Revision $revision Revision to be used
566
     * @return ObjectInterface Object
567
     */
568
    public function useRevision(Revision $revision)
569
    {
570
        return $this->object()->useRevision($revision);
571
    }
572
573
    /**
574
     * Persist the current object revision
575
     *
576
     * @return ObjectInterface Object
577
     */
578
    public function persist()
579
    {
580
        return $this->object()->persist();
581
    }
582
583
    /**
584
     * Return whether the object is in published state
585
     *
586
     * @return boolean Published state
587
     */
588
    public function isPublished()
589
    {
590
        return $this->object()->isPublished();
591
    }
592
593
    /**
594
     * Return whether the object has just been published
595
     *
596
     * @return boolean Object has just been published
597
     */
598
    public function hasBeenPublished()
599
    {
600
        return $this->object()->hasBeenPublished();
601
    }
602
603
    /**
604
     * Return whether the object has been deleted
605
     *
606
     * @return boolean Object is deleted
607
     */
608
    public function isDeleted()
609
    {
610
        return $this->object()->isDeleted();
611
    }
612
613
    /**
614
     * Return whether the object has just been deleted
615
     *
616
     * @return boolean Object has just been deleted
617
     */
618
    public function hasBeenDeleted()
619
    {
620
        return $this->object()->hasBeenDeleted();
621
    }
622
623
    /**
624
     * Return whether the object has just been undeleted
625
     *
626
     * @return boolean Object has just been undeleted
627
     */
628
    public function hasBeenUndeleted()
629
    {
630
        return $this->object()->hasBeenUndeleted();
631
    }
632
633
634
    /**
635
     * Publish the current object revision
636
     *
637
     * @return ObjectInterface Object
638
     */
639
    public function publish()
640
    {
641
        return $this->object()->publish();
642
    }
643
644
    /**
645
     * Delete the object and all its revisions
646
     *
647
     * @return ObjectInterface Object
648
     */
649
    public function delete()
650
    {
651
        return $this->object()->delete();
652
    }
653
654
    /**
655
     * Undelete the object and all its revisions
656
     *
657
     * @return ObjectInterface Object
658
     */
659
    public function undelete()
660
    {
661
        return $this->object()->undelete();
662
    }
663
664
    /**
665
     * Add an object relation
666
     *
667
     * @param string|RelationInterface $relation Serialized or instantiated object relation
668
     * @param string|null $relationType Relation type
669
     * @return ObjectInterface
670
     */
671
    public function addRelation($relation, $relationType = null)
672
    {
673
        return $this->object()->addRelation($relation, $relationType);
674
    }
675
676
    /**
677
     * Delete an object relation
678
     *
679
     * @param RelationInterface $relation Object relation
680
     * @return ObjectInterface
681
     */
682
    public function deleteRelation(RelationInterface $relation)
683
    {
684
        return $this->object()->deleteRelation($relation);
685
    }
686
687
    /**
688
     * Get all relations (optional: Of a particular type)
689
     *
690
     * @param string|null $relationType Optional: Relation type
691
     * @return array Object relations
692
     */
693
    public function getRelations($relationType = null)
694
    {
695
        return $this->object()->getRelations($relationType);
696
    }
697
698
    /**
699
     * Find and return particular relations
700
     *
701
     * @param array $criteria Relation criteria
702
     * @return RelationInterface[] Relations
703
     */
704
    public function findRelations(array $criteria)
705
    {
706
        return $this->object()->findRelations($criteria);
707
    }
708
}
709