1: <?php
2: /**
3: * This file is part of the PHPLucidFrame library.
4: * Core utility for pagination
5: *
6: * @package PHPLucidFrame\Core
7: * @since PHPLucidFrame v 2.0.0
8: * @copyright Copyright (c), PHPLucidFrame.
9: * @link http://phplucidframe.com
10: * @license http://www.opensource.org/licenses/mit-license.php MIT License
11: *
12: * This source file is subject to the MIT license that is bundled
13: * with this source code in the file LICENSE
14: */
15:
16: namespace LucidFrame\Core;
17:
18: /**
19: * Middleware Class
20: */
21: class Middleware
22: {
23: private static $instance = null;
24:
25: const BEFORE = 'before';
26: const AFTER = 'after';
27:
28: const FILTER_START_WITH = 'startWith';
29: const FILTER_CONTAIN = 'contain';
30: const FILTER_EQUAL = 'equal';
31: const FILTER_EXCEPT = 'except';
32:
33: /** @var array Array of registered middlewares (before) */
34: private static $before = array();
35: /** @var array Array of registered middlewares (after) */
36: private static $after = array();
37: /** @var string Unique id */
38: private static $id;
39: /** @var array Array of route filters by each middleware */
40: private static $routeFilters = array();
41: /** @var array Array of order by each middleware */
42: private static $orders = array();
43:
44: /**
45: * # Make the constructor private to prevent instantiation from outside
46: */
47: private function __construct() { }
48:
49: /**
50: * Prevent cloning of the instance
51: */
52: private function __clone() { }
53:
54: /**
55: * Prevent unserialization of the instance
56: */
57: private function __wakeup() { }
58:
59: /**
60: * Static method to provide access to the single instance
61: */
62: public static function getInstance()
63: {
64: if (!self::$instance) {
65: self::$instance = new Middleware();
66: }
67:
68: return self::$instance;
69: }
70:
71: /**
72: * Register a middleware
73: * @param \Closure $closure Anonymous function
74: * @param string $event before or after
75: * @return $this
76: */
77: public function register(\Closure $closure, $event = self::BEFORE)
78: {
79: self::$id = uniqid();
80:
81: if (in_array($event, array(self::BEFORE, self::AFTER))) {
82: self::${$event}[self::$id] = $closure;
83: $this->order(count(self::${$event}), $event);
84: }
85:
86: return $this;
87: }
88:
89: /**
90: * Register route filter for the middleware
91: * @param string $key One of the values - startWith, contain, equal, except
92: * @param string $value URI or a part of URI
93: * @return $this
94: */
95: public function on($key, $value)
96: {
97: if (self::$id) {
98: self::$routeFilters[self::$id][$key][] = $value;
99: }
100:
101: return $this;
102: }
103:
104: /**
105: * Register precedence of the middleware
106: * @param int $sort Ascending order (smaller value runs first)
107: * @param string $event before (default) or after
108: * @return $this
109: */
110: public function order($sort, $event = self::BEFORE)
111: {
112: if (self::$id) {
113: self::$orders[$event][self::$id] = $sort;
114: }
115:
116: return $this;
117: }
118:
119: /**
120: * Run all registered middlewares (before)
121: */
122: public static function runBefore()
123: {
124: asort(self::$orders[self::BEFORE]);
125: self::invoke(self::BEFORE);
126: }
127:
128: /**
129: * Run all registered middlewares (after)
130: */
131: public static function runAfter()
132: {
133: asort(self::$orders[self::AFTER]);
134: self::invoke(self::AFTER);
135: }
136:
137: /**
138: * Run the registered middlewares
139: * @param string $event before or after
140: */
141: private static function invoke($event)
142: {
143: $middlewares = $event == self::AFTER ? self::$after : self::$before;
144:
145: foreach (self::$orders[$event] as $id => $order) {
146: $closure = $middlewares[$id];
147:
148: if (isset(self::$routeFilters[$id])) {
149: $except = array();
150: if (isset(self::$routeFilters[$id][self::FILTER_EXCEPT])) {
151: foreach (self::$routeFilters[$id][self::FILTER_EXCEPT] as $exp) {
152: $exp = is_array($exp) ? $exp : array($exp);
153: $except = array_merge($except, $exp);
154: }
155: unset(self::$routeFilters[$id][self::FILTER_EXCEPT]);
156: }
157:
158: if (count(self::$routeFilters[$id])) {
159: foreach (self::$routeFilters[$id] as $filter => $value) {
160: foreach ($value as $val) {
161: switch($filter) {
162: case self::FILTER_START_WITH:
163: if (route_start($val, $except)) {
164: $closure();
165: }
166: break;
167:
168: case self::FILTER_CONTAIN:
169: $val = is_array($val) ? $val : array($val);
170: if (route_contain($val, $except)) {
171: $closure();
172: }
173: break;
174:
175: case self::FILTER_EQUAL:
176: if (route_equal($val)) {
177: $closure();
178: }
179: break;
180: }
181: }
182: }
183: } else {
184: if (count($except) && call_user_func_array('route_except', $except)) {
185: $closure();
186: }
187: }
188: } else {
189: $closure();
190: }
191: }
192: }
193: }
194: