1 <?php
2 /**
3 * Add extension that can be added to an object with {@link Object::add_extension()}.
4 * For {@link DataObject} extensions, use {@link DataObjectDecorator}.
5 * Each extension instance has an "owner" instance, accessible through
6 * {@link getOwner()}.
7 * Every object instance gets its own set of extension instances,
8 * meaning you can set parameters specific to the "owner instance"
9 * in new Extension instances.
10 *
11 * @package sapphire
12 * @subpackage core
13 */
14 abstract class Extension {
15 /**
16 * This is used by extensions designed to be applied to controllers.
17 * It works the same way as {@link Controller::$allowed_actions}.
18 */
19 public static $allowed_actions = null;
20
21 /**
22 * The DataObject that owns this decorator.
23 * @var DataObject
24 */
25 protected $owner;
26
27 /**
28 * The base class that this extension was applied to; $this->owner must be one of these
29 * @var DataObject
30 */
31 protected $ownerBaseClass;
32
33 /**
34 * Reference counter to ensure that the owner isn't cleared until clearOwner() has
35 * been called as many times as setOwner()
36 */
37 private $ownerRefs = 0;
38
39 public $class;
40
41 function __construct() {
42 $this->class = get_class($this);
43 }
44
45 /**
46 * Set the owner of this decorator.
47 * @param Object $owner The owner object,
48 * @param string $ownerBaseClass The base class that the extension is applied to; this may be
49 * the class of owner, or it may be a parent. For example, if Versioned was applied to SiteTree,
50 * and then a Page object was instantiated, $owner would be a Page object, but $ownerBaseClass
51 * would be 'SiteTree'.
52 */
53 function setOwner($owner, $ownerBaseClass = null) {
54 if($owner) $this->ownerRefs++;
55 $this->owner = $owner;
56
57 if($ownerBaseClass) $this->ownerBaseClass = $ownerBaseClass;
58 else if(!$this->ownerBaseClass && $owner) $this->ownerBaseClass = $owner->class;
59 }
60
61 function clearOwner() {
62 if($this->ownerRefs <= 0) user_error("clearOwner() called more than setOwner()", E_USER_WARNING);
63 $this->ownerRefs--;
64 if($this->ownerRefs == 0) $this->owner = null;
65 }
66
67 /**
68 * Returns the owner of this decorator
69 *
70 * @return Object
71 */
72 public function getOwner() {
73 return $this->owner;
74 }
75
76 /**
77 * Helper method to strip eval'ed arguments from a string
78 * thats passed to {@link DataObject::$extensions} or
79 * {@link Object::add_extension()}.
80 *
81 * @param string $extensionStr E.g. "Versioned('Stage','Live')"
82 * @return string Extension classname, e.g. "Versioned"
83 */
84 public static function get_classname_without_arguments($extensionStr) {
85 return (($p = strpos($extensionStr, '(')) !== false) ? substr($extensionStr, 0, $p) : $extensionStr;
86 }
87
88 }
89
90 ?>