Completed
Push — master ( 954878...4f4902 )
by Joschi
03:36
created

ObjectProxyTrait::getAbsoluteUrl()   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

Importance

Changes 0
Metric Value
cc 1
eloc 2
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 4
ccs 0
cts 2
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\Traits;
38
39
use Apparat\Kernel\Ports\Kernel;
40
use Apparat\Object\Domain\Model\Object\Id;
41
use Apparat\Object\Domain\Model\Object\InvalidArgumentException;
42
use Apparat\Object\Domain\Model\Object\ObjectInterface;
43
use Apparat\Object\Domain\Model\Object\Revision;
44
use Apparat\Object\Domain\Model\Object\Type;
45
use Apparat\Object\Domain\Model\Relation\RelationInterface;
46
use Apparat\Object\Domain\Model\Uri\ApparatUrl;
47
use Apparat\Object\Domain\Model\Uri\RepositoryLocatorInterface;
48
use Apparat\Object\Domain\Repository\Service;
49
50
/**
51
 * Object proxy (lazy loading)
52
 *
53
 * @package Apparat\Object
54
 * @subpackage Apparat\Object\Domain
55
 */
56
trait ObjectProxyTrait
57
{
58
    /**
59
     * Use traits
60
     */
61
    use IterableProxyTrait;
62
    /**
63
     * Object
64
     *
65
     * @var ObjectInterface
66
     */
67
    protected $object = null;
68
69
    /**
70
     * Return the object repository locator
71
     *
72
     * @return RepositoryLocatorInterface Object repository locator
73
     */
74
    public function getRepositoryLocator()
75
    {
76
        // If the object has already been instantiated
77
        if ($this->object instanceof ObjectInterface) {
78
            return $this->object->getRepositoryLocator();
79
        }
80
81
        return $this->getUrl()->getLocator();
0 ignored issues
show
Bug introduced by
The method getLocator does only exist in Apparat\Object\Domain\Model\Uri\ApparatUrl, but not in Apparat\Object\Domain\Mo...ositoryLocatorInterface.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
82
    }
83
84
    /**
85
     * Return the object property data
86
     *
87
     * @param bool $serialize Serialize property objects
88
     * @return array Object property data
89
     */
90
    public function getPropertyData($serialize = true)
91
    {
92
        return $this->object()->getPropertyData($serialize);
93
    }
94
95
    /**
96
     * Return the enclosed remote object
97
     *
98
     * @return ObjectInterface Remote object
99
     */
100 1
    protected function object()
101
    {
102
        // Lazy-load the remote object if necessary
103 1
        if (!$this->object instanceof ObjectInterface) {
104
            // Instantiate the local object repository, load and return the object
105 1
            $this->object = Kernel::create(Service::class)->get($this->getUrl())->loadObject($this->getUrl()->getLocator());
0 ignored issues
show
Bug introduced by
The method getLocator does only exist in Apparat\Object\Domain\Model\Uri\ApparatUrl, but not in Apparat\Object\Domain\Mo...ositoryLocatorInterface.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
106 1
        }
107
108 1
        return $this->object;
109
    }
110
111
    /**
112
     * Return the object payload
113
     *
114
     * @return string Object payload
115
     */
116
    public function getPayload()
117
    {
118
        return $this->object()->getPayload();
119
    }
120
121
    /**
122
     * Set the payload
123
     *
124
     * @param string $payload Payload
125
     * @return ObjectInterface Self reference
126
     */
127
    public function setPayload($payload)
128
    {
129
        return $this->object()->setPayload($payload);
130
    }
131
132
    /**
133
     * Return the object ID
134
     *
135
     * @return Id Object ID
136
     */
137
    public function getId()
138
    {
139
        return $this->object()->getId();
140
    }
141
142
    /**
143
     * Return the object type
144
     *
145
     * @return Type Object type
146
     */
147
    public function getObjectType()
148
    {
149
        return $this->object()->getObjectType();
150
    }
151
152
    /**
153
     * Return the object revision
154
     *
155
     * @return Revision Object revision
156
     */
157
    public function getRevision()
158
    {
159
        return $this->object()->getRevision();
160
    }
161
162
    /**
163
     * Return the latitude
164
     *
165
     * @return float Latitude
166
     */
167
    public function getLatitude()
168
    {
169
        return $this->object()->getLatitude();
170
    }
171
172
    /**
173
     * Set the latitude
174
     *
175
     * @param float $latitude Latitude
176
     * @return ObjectInterface Self reference
177
     */
178
    public function setLatitude($latitude)
179
    {
180
        return $this->object()->setLatitude($latitude);
181
    }
182
183
    /**
184
     * Return the longitude
185
     *
186
     * @return float Longitude
187
     */
188
    public function getLongitude()
189
    {
190
        return $this->object()->getLongitude();
191
    }
192
193
    /**
194
     * Set the longitude
195
     *
196
     * @param float $longitude Longitude
197
     * @return ObjectInterface Self reference
198
     */
199
    public function setLongitude($longitude)
200
    {
201
        return $this->object()->setLongitude($longitude);
202
    }
203
204
    /**
205
     * Return the elevation
206
     *
207
     * @return float Elevation
208
     */
209
    public function getElevation()
210
    {
211
        return $this->object()->getElevation();
212
    }
213
214
    /**
215
     * Set the elevation
216
     *
217
     * @param float $elevation
218
     * @return ObjectInterface Self reference
219
     */
220
    public function setElevation($elevation)
221
    {
222
        return $this->object()->setElevation($elevation);
223
    }
224
225
226
    /**
227
     * Return the object draft mode
228
     *
229
     * @return boolean Object draft mode
230
     */
231
    public function isDraft()
232
    {
233
        return $this->object()->isDraft();
234
    }
235
236
    /**
237
     * Return whether the object is in modified state
238
     *
239
     * @return boolean Modified state
240
     */
241
    public function hasBeenModified()
242
    {
243
        return $this->object()->hasBeenModified();
244
    }
245
246
    /**
247
     * Return whether the object is in mutated state
248
     *
249
     * @return boolean Mutated state
250
     */
251
    public function hasBeenMutated()
252
    {
253
        return $this->object()->hasBeenMutated();
254
    }
255
256
    /**
257
     * Return the creation date & time
258
     *
259
     * @return \DateTimeInterface Creation date & time
260
     */
261
    public function getCreated()
262
    {
263
        return $this->object()->getCreated();
264
    }
265
266
    /**
267
     * Return the deletion date & time
268
     *
269
     * @return \DateTimeInterface Deletion date & time
270
     */
271
    public function getDeleted()
272
    {
273
        return $this->object()->getDeleted();
274
    }
275
276
    /**
277
     * Return the modification date & time
278
     *
279
     * @return \DateTimeInterface Modification date & time
280
     */
281
    public function getModified()
282
    {
283
        return $this->object()->getModified();
284
    }
285
286
    /**
287
     * Return the publication date & time
288
     *
289
     * @return \DateTimeInterface Publication date & time
290
     */
291
    public function getPublished()
292
    {
293
        return $this->object()->getPublished();
294
    }
295
296
    /**
297
     * Return the object title
298
     *
299
     * @return string Object title
300
     */
301 1
    public function getTitle()
302
    {
303 1
        return $this->object()->getTitle();
304
    }
305
306
    /**
307
     * Set the title
308
     *
309
     * @param string $title Title
310
     * @return ObjectInterface Self reference
311
     */
312
    public function setTitle($title)
313
    {
314
        return $this->object()->setTitle($title);
315
    }
316
317
    /**
318
     * Return the object slug
319
     *
320
     * @return string Object slug
321
     */
322
    public function getSlug()
323
    {
324
        return $this->object()->getSlug();
325
    }
326
327
    /**
328
     * Set the slug
329
     *
330
     * @param string $slug Slug
331
     * @return ObjectInterface Self reference
332
     */
333
    public function setSlug($slug)
334
    {
335
        return $this->object()->setSlug($slug);
336
    }
337
338
339
    /**
340
     * Return the object description
341
     *
342
     * @return string Object description
343
     */
344
    public function getDescription()
345
    {
346
        return $this->object()->getDescription();
347
    }
348
349
    /**
350
     * Set the description
351
     *
352
     * @param string $description Description
353
     * @return ObjectInterface Self reference
354
     */
355
    public function setDescription($description)
356
    {
357
        return $this->object()->setDescription($description);
358
    }
359
360
    /**
361
     * Return the object abstract
362
     *
363
     * @return string Object abstract
364
     */
365
    public function getAbstract()
366
    {
367
        return $this->object()->getAbstract();
368
    }
369
370
    /**
371
     * Set the abstract
372
     *
373
     * @param string $abstract Abstract
374
     * @return ObjectInterface Self reference
375
     */
376
    public function setAbstract($abstract)
377
    {
378
        return $this->object()->setAbstract($abstract);
379
    }
380
381
    /**
382
     * Return all object keywords
383
     *
384
     * @return array Object keywords
385
     */
386
    public function getKeywords()
387
    {
388
        return $this->object()->getKeywords();
389
    }
390
391
    /**
392
     * Set the keywords
393
     *
394
     * @param array $keywords Keywords
395
     * @return ObjectInterface Self reference
396
     */
397
    public function setKeywords(array $keywords)
398
    {
399
        return $this->object()->setKeywords($keywords);
400
    }
401
402
    /**
403
     * Return the license
404
     *
405
     * @return string License
406
     */
407
    public function getLicense()
408
    {
409
        return $this->object()->getLicense();
410
    }
411
412
    /**
413
     * Set the license
414
     *
415
     * @param string $license License
416
     * @return ObjectInterface Self reference
417
     */
418
    public function setLicense($license)
419
    {
420
        return $this->object()->setLicense($license);
421
    }
422
423
    /**
424
     * Return the language
425
     *
426
     * @return string Language
427
     */
428
    public function getLanguage()
429
    {
430
        return $this->object()->getLanguage();
431
    }
432
433
    /**
434
     * Return the privacy
435
     *
436
     * @return string Privacy
437
     */
438
    public function getPrivacy()
439
    {
440
        return $this->object()->getPrivacy();
441
    }
442
443
    /**
444
     * Set the privacy
445
     *
446
     * @param string $privacy Privacy
447
     * @return ObjectInterface Self reference
448
     */
449
    public function setPrivacy($privacy)
450
    {
451
        return $this->object()->setPrivacy($privacy);
452
    }
453
454
    /**
455
     * Return all object categories
456
     *
457
     * @return array Object categories
458
     */
459
    public function getCategories()
460
    {
461
        return $this->object()->getCategories();
462
    }
463
464
    /**
465
     * Set the categories
466
     *
467
     * @param array $categories Categories
468
     * @return ObjectInterface Self reference
469
     */
470
    public function setCategories(array $categories)
471
    {
472
        return $this->object()->setCategories($categories);
473
    }
474
475
    /**
476
     * Get a domain property value
477
     *
478
     * Multi-level properties might be traversed by property name locators separated with colons (":").
479
     *
480
     * @param string $property Property name
481
     * @return mixed Property value
482
     */
483
    public function getDomain($property)
484
    {
485
        return $this->object()->getDomain($property);
486
    }
487
488
    /**
489
     * Set a domain property value
490
     *
491
     * @param string $property Property name
492
     * @param mixed $value Property value
493
     * @return ObjectInterface Self reference
494
     */
495
    public function setDomain($property, $value)
496
    {
497
        return $this->object()->setDomain($property, $value);
498
    }
499
500
    /**
501
     * Get a processing instruction
502
     *
503
     * @param string $procInst Processing instruction name
504
     * @return mixed Processing instruction
505
     */
506
    public function getProcessingInstruction($procInst)
507
    {
508
        return $this->object()->getProcessingInstruction($procInst);
509
    }
510
511
    /**
512
     * Set a processing instruction
513
     *
514
     * @param string $procInst Processing instruction name
515
     * @param mixed $value Processing instruction
516
     * @return ObjectInterface Self reference
517
     */
518
    public function setProcessingInstruction($procInst, $value)
519
    {
520
        return $this->object()->setProcessingInstruction($procInst, $value);
521
    }
522
523
    /**
524
     * Return the canonical object URL
525
     *
526
     * @return string
527
     */
528
    public function getCanonicalUrl()
529
    {
530
        return $this->getAbsoluteUrl();
531
    }
532
533
    /**
534
     * Return the absolute object URL
535
     *
536
     * @return string
537
     */
538
    public function getAbsoluteUrl()
539
    {
540
        return strval($this->getUrl());
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
    /**
710
     * Return the URL
711
     *
712
     * @return RepositoryLocatorInterface|ApparatUrl URL
713
     */
714
    abstract public function getUrl();
715
}
716