1 <?php
 2 
 3 /**
 4  * Klasse die Einsprungpunkte zur Erweiterung der Kernfunktionalitaetet bietet.
 5  *
 6  * @author Markus Staab
 7  *
 8  * @package redaxo\core
 9  */
10 abstract class rex_extension
11 {
12     use rex_factory_trait;
13 
14     const EARLY = -1;
15     const NORMAL = 0;
16     const LATE = 1;
17 
18     /**
19      * Array of registered extensions.
20      *
21      * @var array
22      */
23     private static $extensions = [];
24 
25     /**
26      * Registers an extension point.
27      *
28      * @param rex_extension_point $extensionPoint Extension point
29      *
30      * @return mixed Subject, maybe adjusted by the extensions
31      */
32     public static function registerPoint(rex_extension_point $extensionPoint)
33     {
34         if (static::hasFactoryClass()) {
35             return static::callFactoryClass(__FUNCTION__, func_get_args());
36         }
37 
38         $name = $extensionPoint->getName();
39 
40         foreach ([self::EARLY, self::NORMAL, self::LATE] as $level) {
41             if (isset(self::$extensions[$name][$level]) && is_array(self::$extensions[$name][$level])) {
42                 foreach (self::$extensions[$name][$level] as $extensionAndParams) {
43                     list($extension, $params) = $extensionAndParams;
44                     $extensionPoint->setExtensionParams($params);
45                     $subject = call_user_func($extension, $extensionPoint);
46                     // Update subject only if the EP is not readonly and the extension has returned something
47                     if (!$extensionPoint->isReadonly() && null !== $subject) {
48                         $extensionPoint->setSubject($subject);
49                     }
50                 }
51             }
52         }
53 
54         return $extensionPoint->getSubject();
55     }
56 
57     /**
58      * Registers an extension for an extension point.
59      *
60      * @param string|string[] $extensionPoint Name(s) of extension point(s)
61      * @param callable        $extension      Callback extension
62      * @param int             $level          Runlevel (`rex_extension::EARLY`, `rex_extension::NORMAL` or `rex_extension::LATE`)
63      * @param array           $params         Additional params
64      */
65     public static function register($extensionPoint, callable $extension, $level = self::NORMAL, array $params = [])
66     {
67         if (static::hasFactoryClass()) {
68             static::callFactoryClass(__FUNCTION__, func_get_args());
69             return;
70         }
71         foreach ((array) $extensionPoint as $ep) {
72             self::$extensions[$ep][(int) $level][] = [$extension, $params];
73         }
74     }
75 
76     /**
77      * Checks whether an extension is registered for the given extension point.
78      *
79      * @param string $extensionPoint Name of extension point
80      *
81      * @return bool
82      */
83     public static function isRegistered($extensionPoint)
84     {
85         if (static::hasFactoryClass()) {
86             return static::callFactoryClass(__FUNCTION__, func_get_args());
87         }
88         return !empty(self::$extensions[$extensionPoint]);
89     }
90 }
91