Completed
Push — master ( 22f3d5...17c8e9 )
by Damian
35s
created

Extension::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace SilverStripe\Core;
4
5
use BadMethodCallException;
6
use SilverStripe\ORM\DataObject;
7
8
/**
9
 * Add extension that can be added to an object with {@link Object::add_extension()}.
10
 * For {@link DataObject} extensions, use {@link DataExtension}.
11
 * Each extension instance has an "owner" instance, accessible through
12
 * {@link getOwner()}.
13
 * Every object instance gets its own set of extension instances,
14
 * meaning you can set parameters specific to the "owner instance"
15
 * in new Extension instances.
16
 */
17
abstract class Extension
18
{
19
    /**
20
     * This is used by extensions designed to be applied to controllers.
21
     * It works the same way as {@link Controller::$allowed_actions}.
22
     */
23
    private static $allowed_actions = [];
24
25
    /**
26
     * The object this extension is applied to.
27
     *
28
     * @var Object
29
     */
30
    protected $owner;
31
32
    /**
33
     * The base class that this extension was applied to; $this->owner must be one of these
34
     *
35
     * @var DataObject
36
     */
37
    protected $ownerBaseClass;
38
39
    /**
40
     * Ownership stack for recursive methods.
41
     * Last item is current owner.
42
     *
43
     * @var array
44
     */
45
    private $ownerStack = [];
46
47
    public function __construct()
48
    {
49
    }
50
51
    /**
52
     * Called when this extension is added to a particular class
53
     *
54
     * @param string $class
55
     * @param string $extensionClass
56
     * @param mixed $args
57
     */
58
    public static function add_to_class($class, $extensionClass, $args = null)
0 ignored issues
show
Unused Code introduced by
The parameter $class is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $extensionClass is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $args is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
59
    {
60
        // NOP
61
    }
62
63
    /**
64
     * Set the owner of this extension.
65
     *
66
     * @param object $owner The owner object,
67
     * @param string $ownerBaseClass The base class that the extension is applied to; this may be
68
     * the class of owner, or it may be a parent.  For example, if Versioned was applied to SiteTree,
69
     * and then a Page object was instantiated, $owner would be a Page object, but $ownerBaseClass
70
     * would be 'SiteTree'.
71
     */
72
    public function setOwner($owner, $ownerBaseClass = null)
73
    {
74
        if ($owner) {
75
            $this->ownerStack[] = $owner;
76
        }
77
        $this->owner = $owner;
78
79
        // Set ownerBaseClass
80
        if ($ownerBaseClass) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $ownerBaseClass of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
81
            $this->ownerBaseClass = $ownerBaseClass;
0 ignored issues
show
Documentation Bug introduced by
It seems like $ownerBaseClass of type string is incompatible with the declared type object<SilverStripe\ORM\DataObject> of property $ownerBaseClass.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
82
        } elseif (!$this->ownerBaseClass && $owner) {
83
            $this->ownerBaseClass = get_class($owner);
0 ignored issues
show
Documentation Bug introduced by
It seems like get_class($owner) of type string is incompatible with the declared type object<SilverStripe\ORM\DataObject> of property $ownerBaseClass.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
84
        }
85
    }
86
87
    /**
88
     * Clear the current owner, and restore extension to the state prior to the last setOwner()
89
     */
90
    public function clearOwner()
91
    {
92
        if (empty($this->ownerStack)) {
93
            throw new BadMethodCallException("clearOwner() called more than setOwner()");
94
        }
95
        array_pop($this->ownerStack);
96
        if ($this->ownerStack) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->ownerStack of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
97
            $this->owner = end($this->ownerStack);
98
        } else {
99
            $this->owner = null;
100
        }
101
    }
102
103
    /**
104
     * Returns the owner of this extension.
105
     *
106
     * @return Object
107
     */
108
    public function getOwner()
109
    {
110
        return $this->owner;
111
    }
112
113
    /**
114
     * Helper method to strip eval'ed arguments from a string
115
     * that's passed to {@link DataObject::$extensions} or
116
     * {@link Object::add_extension()}.
117
     *
118
     * @param string $extensionStr E.g. "Versioned('Stage','Live')"
119
     * @return string Extension classname, e.g. "Versioned"
120
     */
121
    public static function get_classname_without_arguments($extensionStr)
122
    {
123
        $parts = explode('(', $extensionStr);
124
        return $parts[0];
125
    }
126
}
127