Completed
Push — authenticator-refactor ( 0a18bb...b9e528 )
by Simon
08:12
created

Extension::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 4
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
    /**
48
     * Called when this extension is added to a particular class
49
     *
50
     * @param string $class
51
     * @param string $extensionClass
52
     * @param mixed $args
53
     */
54
    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...
55
    {
56
        // NOP
57
    }
58
59
    /**
60
     * Set the owner of this extension.
61
     *
62
     * @param object $owner The owner object,
63
     * @param string $ownerBaseClass The base class that the extension is applied to; this may be
64
     * the class of owner, or it may be a parent.  For example, if Versioned was applied to SiteTree,
65
     * and then a Page object was instantiated, $owner would be a Page object, but $ownerBaseClass
66
     * would be 'SiteTree'.
67
     */
68
    public function setOwner($owner, $ownerBaseClass = null)
69
    {
70
        if ($owner) {
71
            $this->ownerStack[] = $owner;
72
        }
73
        $this->owner = $owner;
74
75
        // Set ownerBaseClass
76
        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...
77
            $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...
78
        } elseif (!$this->ownerBaseClass && $owner) {
79
            $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...
80
        }
81
    }
82
83
    /**
84
     * Clear the current owner, and restore extension to the state prior to the last setOwner()
85
     */
86
    public function clearOwner()
87
    {
88
        if (empty($this->ownerStack)) {
89
            throw new BadMethodCallException("clearOwner() called more than setOwner()");
90
        }
91
        array_pop($this->ownerStack);
92
        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...
93
            $this->owner = end($this->ownerStack);
94
        } else {
95
            $this->owner = null;
96
        }
97
    }
98
99
    /**
100
     * Returns the owner of this extension.
101
     *
102
     * @return Object
103
     */
104
    public function getOwner()
105
    {
106
        return $this->owner;
107
    }
108
109
    /**
110
     * Helper method to strip eval'ed arguments from a string
111
     * that's passed to {@link DataObject::$extensions} or
112
     * {@link Object::add_extension()}.
113
     *
114
     * @param string $extensionStr E.g. "Versioned('Stage','Live')"
115
     * @return string Extension classname, e.g. "Versioned"
116
     */
117
    public static function get_classname_without_arguments($extensionStr)
118
    {
119
        $parts = explode('(', $extensionStr);
120
        return $parts[0];
121
    }
122
}
123