Completed
Push — feature/code-analysis ( 1158f1...5e4834 )
by Jonathan
03:51
created

HookProvider::getInstance()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
c 1
b 1
f 0
dl 0
loc 8
rs 9.4285
cc 2
eloc 4
nc 2
nop 0
1
<?php
2
/**
3
 * webtrees-lib: MyArtJaub library for webtrees
4
 * 
5
 * @package MyArtJaub\Webtrees
6
 * @subpackage Hook
7
 * @author Jonathan Jaubart <[email protected]>
8
 * @copyright Copyright (c) 2011-2016, Jonathan Jaubart
9
 * @license http://www.gnu.org/licenses/gpl.html GNU General Public License, version 3
10
 */
11
namespace MyArtJaub\Webtrees\Hook;
12
13
use \Fisharebest\Webtrees as fw;
14
use \MyArtJaub\Webtrees as mw;
15
use \MyArtJaub\Webtrees\Constants;
16
use Fisharebest\Webtrees\Auth;
17
18
/**
19
 * Provider for hooks. 
20
 * 
21
 * Provide access to hooks.
22
 */
23
class HookProvider implements HookProviderInterface {
24
25
	/**
26
	 * Default priority to be used for hooks without specified priority. 
27
	 * The default 99 is a low priority.
28
	 * @var int DEFAULT_PRIORITY
29
	 */
30
	const DEFAULT_PRIORITY = 99;
31
32
	/**
33
	 * @var HookProviderInterface $instance Singleton pattern instance
34
	 */
35
	private static $instance = null;
36
	
37
38
	/**
39
	 * Returns the *HookProvider* instance of this class.
40
	 *
41
	 * @return HookProviderInterface The *Singleton* instance.
42
	 */
43
	public static function getInstance()
44
	{
45
	    if (null === static::$instance) {
0 ignored issues
show
Bug introduced by
Since $instance is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $instance to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
46
	        static::$instance = new static();
0 ignored issues
show
Bug introduced by
Since $instance is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $instance to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
47
	    }
48
	
49
	    return static::$instance;
0 ignored issues
show
Bug introduced by
Since $instance is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $instance to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
50
	}
51
	
52
	/**
53
	 * {@inheritDoc}
54
	 * @see \MyArtJaub\Webtrees\Hook\HookProviderInterface::get()
55
	 */
56
	public function get($hook_function, $hook_context = null) {
57
	    return new Hook($hook_function, $hook_context);
58
	}
59
	
60
	/**
61
	 * {@inheritDoc}
62
	 * @see \MyArtJaub\Webtrees\Hook\HookProviderInterface::isModuleOperational()
63
	 */
64
	public function isModuleOperational() {
65
		return mw\Module\ModuleManager::getInstance()->isOperational(mw\Constants::MODULE_MAJ_HOOKS_NAME);
66
	}
67
	
68
	/**
69
	 * {@inheritDoc}
70
	 * @see \MyArtJaub\Webtrees\Hook\HookProviderInterface::getPossibleHooks()
71
	 */
72
	public function getPossibleHooks() {
73
		static $hooks=null;
74
		if ($hooks === null) {
75
		    $hooks = array();
76
		    foreach (glob(WT_ROOT . WT_MODULES_DIR . '*/module.php') as $file) {
77
		        try {
78
		            $module = include $file;
79
		            if($module instanceof HookSubscriberInterface){
80
						$subscribedhooks = $module->getSubscribedHooks();
81
						if(is_array($subscribedhooks)){
82
							foreach($subscribedhooks as $key => $value){
83
								if(is_int($key)) {
84
									$hook_item = $value;
85
									$priority = self::DEFAULT_PRIORITY;
86
								}
87
								else{
88
									$hook_item = explode('#', $key, 2);
89
									$priority = $value;
90
								}
91
								if($hook_item && count($hook_item) == 2){
92
									$hook_func = $hook_item[0];
93
									$hook_cont = $hook_item[1];
94
								}
95
								else{
96
									$hook_func = $hook_item[0];
97
									$hook_cont = 'all';
98
								}
99
								if(method_exists($module, $hook_func)){
100
									$hooks[$module->getName().'#'.$hook_func.'#'.$hook_cont]=$priority;
101
								}
102
							}
103
						}
104
					}
105
    			} catch (\Exception $ex) {
106
    				// Old or invalid module?
107
    			}
108
			}
109
		}
110
		return $hooks;
111
	}
112
	
113
	/**
114
	 * {@inheritDoc}
115
	 * @see \MyArtJaub\Webtrees\Hook\HookProviderInterface::getRawInstalledHooks()
116
	 */
117
	public function getRawInstalledHooks(){
118
		if(self::isModuleOperational()){
119
			return fw\Database::prepare(
120
					"SELECT majh_id AS id, majh_module_name AS module, majh_hook_function AS hook, majh_hook_context as context, majh_module_priority AS priority,  majh_status AS status".
121
					" FROM `##maj_hooks`".
122
					" ORDER BY hook ASC, status ASC, priority ASC, module ASC"
123
					)->execute()->fetchAll();
124
		}
125
		return array();
126
	}
127
	
128
	/**
129
	 * {@inheritDoc}
130
	 * @see \MyArtJaub\Webtrees\Hook\HookProviderInterface::getInstalledHooks()
131
	 */
132
	public function getInstalledHooks(){
133
		static $installedhooks =null;
134
		if($installedhooks===null){
135
			$dbhooks=self::getRawInstalledHooks();
136
			foreach($dbhooks as $dbhook){
137
				$installedhooks[($dbhook->module).'#'.($dbhook->hook).'#'.($dbhook->context)] = array('id' => $dbhook->id, 'status' => $dbhook->status, 'priority' => $dbhook->priority);
138
			}
139
		}
140
		return $installedhooks;
141
	}
142
	
143
	/**
144
	 * {@inheritDoc}
145
	 * @see \MyArtJaub\Webtrees\Hook\HookProviderInterface::updateHooks()
146
	 */
147
	public function updateHooks() {
148
	    
149
	    if(Auth::isAdmin()){
150
	        $ihooks = self::getInstalledHooks();
151
	        $phooks = self::getPossibleHooks();
152
	        	
153
	        // Insert hooks not existing yet in the DB
154
	        if($phooks !== null){
155
	            foreach($phooks as $phook => $priority){
156
	                $array_hook = explode('#', $phook);
157
	                if($ihooks === null || !array_key_exists($phook, $ihooks)){
158
	                    $chook = new Hook($array_hook[1], $array_hook[2]);
159
	                    $chook->subscribe($array_hook[0]);
160
	                    $chook->setPriority($array_hook[0], $priority);
161
	                }
162
	            }
163
	        }
164
	        	
165
	        //Remove hooks not existing any more in the file system
166
	        if($ihooks !== null){
167
	            foreach($ihooks as $ihook => $status){
168
	                $array_hook = explode('#', $ihook);
169
	                if($phooks === null || !array_key_exists($ihook, $phooks)){
170
	                    $chook = new Hook($array_hook[1], $array_hook[2]);
171
	                    $chook->remove($array_hook[0]);
172
	                }
173
	            }
174
	        }
175
	    }
176
	}
177
	
178
}