├── tests └── .gitkeep ├── .gitignore ├── src ├── helpers │ └── hook.php └── Hook.php ├── composer.json ├── Example └── index.php └── readme.md /tests/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | vendor 2 | .DS_Store 3 | readme 4 | Example 5 | -------------------------------------------------------------------------------- /src/helpers/hook.php: -------------------------------------------------------------------------------- 1 | =5.6" 7 | }, 8 | "license": "MIT", 9 | "authors": [ 10 | { 11 | "name": "Nahid Bin Azhar", 12 | "email": "nahid.dns@gmail.com" 13 | } 14 | ], 15 | "minimum-stability": "dev", 16 | "autoload": { 17 | "psr-4": { 18 | "Nahid\\Hookr\\": "src/" 19 | }, 20 | "files": [ 21 | "src/helpers/hook.php" 22 | ] 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Example/index.php: -------------------------------------------------------------------------------- 1 | 1, 'username'=>'nahid', 'name'=>'Mehedi Hasan Nahid', 'workfor'=>'Pathao' 8 | ], 9 | [ 10 | 'id'=>2, 'username'=>'sumi', 'name'=>'Anjani Sumi', 'workfor'=>'Housewife' 11 | ], 12 | [ 13 | 'id'=>3, 'username'=>'nazat', 'name'=>'Meherunessa Nazat', 'workfor'=>'Baper Hotel' 14 | ], 15 | ]; 16 | 17 | $hookr = new \Nahid\Hookr\Hook(); 18 | 19 | $hookr->bindAction('button', function($user) { 20 | echo 'delete'; 21 | echo ' profile'; 22 | }, 1); 23 | 24 | ?> 25 | 26 |
| ID | 29 |Name | 30 |Work For | 31 |Action | 32 |
|---|---|---|---|
| = $user['id']; ?> | 39 |= $user['name']; ?> | 40 |= $user['workfor']; ?> | 41 |42 | Edit 43 | $user]); ?> 44 | 45 | | 46 |
90 | {{hook_filter('posts', $blog->content)}} 91 |
92 | ``` 93 | 94 | So we register a filter as 'posts'. Now another developer wants to support markdown for blog posts. so he can bind a filter for parse markdown. 95 | 96 | 97 | ```php 98 | use Nahid\Hookr\Facades\Hook; 99 | 100 | class BlogController extends Controller 101 | { 102 | public function getPosts() 103 | { 104 | Hook::bindFilter('posts', function($data) { 105 | return parse_markdown($data); 106 | }, 2); 107 | 108 | return view('post'); 109 | } 110 | } 111 | ``` 112 | 113 | Note: In filter, every callback function must have at least one param which is represent current data 114 | 115 | so if you want to bind multiple data then 116 | 117 | ```php 118 | use Nahid\Hookr\Facades\Hook; 119 | 120 | class BlogController extends Controller 121 | { 122 | public function getPosts() 123 | { 124 | Hook::bindFilter('posts', function($data) { 125 | return parse_markdown($data); 126 | }, 2); 127 | 128 | Hook::bindFilter('posts', function($data) { 129 | return parse_bbcode($data); 130 | }, 3); 131 | 132 | return view('post'); 133 | } 134 | } 135 | ``` 136 | 137 | Now then given data is parse by markdown and bbcode. See, here is second param for `bindFilter()` is a priority for binding. Both `bindAction()` and `bindFilter()` has this feature. 138 | -------------------------------------------------------------------------------- /src/Hook.php: -------------------------------------------------------------------------------- 1 | $callback, 53 | 'priority' => $priority, 54 | ]; 55 | } else { 56 | array_push(static::$hookActions[$name], [ 57 | 'action' => $callback, 58 | 'priority' => $priority, 59 | ]); 60 | } 61 | 62 | } 63 | 64 | /** 65 | * declare filter hook 66 | * 67 | * @param string $name 68 | * @param mixed $data 69 | * @param array $params 70 | * @return mixed 71 | */ 72 | public static function filter($name, $data, $params = []) 73 | { 74 | if (isset(static::$hookFilters[$name])) { 75 | $filters = static::makePriority($name, 'filter'); 76 | foreach ($filters as $callback) { 77 | $data = static::executeFilter($callback['action'], $data, $params); 78 | } 79 | } 80 | 81 | return $data; 82 | } 83 | 84 | /** 85 | * bind filter with hook 86 | * 87 | * @param string $name 88 | * @param callable $callback 89 | * @param int $priority 90 | */ 91 | public static function bindFilter($name, $callback, $priority = 0) 92 | { 93 | if (!isset(static::$hookFilters[$name])) { 94 | static::$hookFilters[$name][] = [ 95 | 'action' => $callback, 96 | 'priority' => $priority, 97 | ]; 98 | } else { 99 | array_push(static::$hookFilters[$name], [ 100 | 'action' => $callback, 101 | 'priority' => $priority, 102 | ]); 103 | } 104 | } 105 | 106 | /** 107 | * make class from string with array param 108 | * 109 | * @param string $class 110 | * @param array $params 111 | * @return object 112 | */ 113 | protected static function newClassInstance($class, $params = []) 114 | { 115 | $reflection = new \ReflectionClass($class); 116 | 117 | return $reflection->newInstanceArgs($params); 118 | } 119 | 120 | /** 121 | * apply action from hook 122 | * 123 | * @param callable $action 124 | * @param array $params 125 | * @return mixed 126 | */ 127 | protected static function executeAction($action, $params) 128 | { 129 | if (is_callable($action)) { 130 | return call_user_func_array($action, $params); 131 | } 132 | 133 | if (is_string($action)) { 134 | $action = explode('@', $action); 135 | $func = static::makeMethodParam($action[1]); 136 | $class = static::makeMethodParam($action[0]); 137 | $instance = static::newClassInstance($class['method'], $class['params']); 138 | if (count($action) > 1) { 139 | return call_user_func_array([$instance, $func['method']], $params); 140 | } 141 | } 142 | } 143 | 144 | /** 145 | * @param callable $action 146 | * @param mixed $data 147 | * @param array $params 148 | * @return mixed 149 | */ 150 | protected static function executeFilter($action, $data, $params = []) 151 | { 152 | if (is_callable($action)) { 153 | array_unshift($params, $data); 154 | 155 | return call_user_func_array($action, $params); 156 | } 157 | 158 | if (is_string($action)) { 159 | $action = explode('@', $action); 160 | $func = static::makeMethodParam($action[1]); 161 | array_unshift($params, $data); 162 | $class = static::makeMethodParam($action[0]); 163 | $instance = static::newClassInstance($class['method'], $class['params']); 164 | if (count($action) > 1) { 165 | return call_user_func_array([$instance, $func['method']], $params); 166 | } 167 | } 168 | } 169 | 170 | /** 171 | * make param from input string 172 | * 173 | * @param string $method 174 | * @return array 175 | */ 176 | protected static function makeMethodParam($method) 177 | { 178 | $methods = explode(':', $method); 179 | $param = []; 180 | $method = $methods[0]; 181 | if (isset($methods[1])) { 182 | $param = explode(',', $methods[1]); 183 | } 184 | 185 | return [ 186 | 'method' => $method, 187 | 'params' => $param, 188 | ]; 189 | } 190 | 191 | /** 192 | * compare two input 193 | * 194 | * @param int $value1 195 | * @param int $value2 196 | * @return int 197 | */ 198 | protected static function compare($value1, $value2) 199 | { 200 | if ($value1['priority'] == $value2['priority']) { 201 | return -1; 202 | } 203 | 204 | return ($value1['priority'] < $value2['priority']) ? -1 : 1; 205 | } 206 | 207 | /** 208 | * make action/filter priority 209 | * 210 | * @param string $name 211 | * @param string $type 212 | * @return mixed 213 | */ 214 | protected static function makePriority($name, $type = 'action') 215 | { 216 | if ($type == 'action') { 217 | usort(static::$hookActions[$name], [new self, 'compare']); 218 | 219 | return static::$hookActions[$name]; 220 | } 221 | 222 | if ($type == 'filter') { 223 | usort(static::$hookFilters[$name], [new self, 'compare']); 224 | 225 | return static::$hookFilters[$name]; 226 | } 227 | } 228 | } 229 | --------------------------------------------------------------------------------