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: const BEFORE = 'before';
24: const AFTER = 'after';
25:
26: const FILTER_START_WITH = 'startWith';
27: const FILTER_CONTAIN = 'contain';
28: const FILTER_EQUAL = 'equal';
29: const FILTER_EXCEPT = 'except';
30:
31: /** @var array Array of registered middlewares (before) */
32: private static $before = array();
33: /** @var array Array of registered middlewares (after) */
34: private static $after = array();
35: /** @var string Unique id */
36: private static $id;
37: /** @var array Array of route filters by each middleware */
38: private static $routeFilters = array();
39: /** @var array Array of order by each middleware */
40: private static $orders = array();
41:
42: /**
43: * Register a middleware
44: * @param \Closure $closure Anonymous function
45: * @param string $event before or after
46: * @return $this
47: */
48: public function register(\Closure $closure, $event = self::BEFORE)
49: {
50: self::$id = uniqid();
51:
52: if (in_array($event, array(self::BEFORE, self::AFTER))) {
53: self::${$event}[self::$id] = $closure;
54: $this->order(count(self::${$event}), $event);
55: }
56:
57: return $this;
58: }
59:
60: /**
61: * Register route filter for the middleware
62: * @param string $key One of the values - startWith, contain, equal, except
63: * @param string $value URI or a part of URI
64: * @return $this
65: */
66: public function on($key, $value)
67: {
68: if (self::$id) {
69: self::$routeFilters[self::$id][$key][] = $value;
70: }
71:
72: return $this;
73: }
74:
75: /**
76: * Register precedence of the middleware
77: * @param int $sort Ascending order (smaller value runs first)
78: * @param string $event before (default) or after
79: * @return $this
80: */
81: public function order($sort, $event = self::BEFORE)
82: {
83: if (self::$id) {
84: self::$orders[$event][self::$id] = $sort;
85: }
86:
87: return $this;
88: }
89:
90: /**
91: * Run all registered middlewares (before)
92: */
93: public static function runBefore()
94: {
95: asort(self::$orders[self::BEFORE]);
96: self::invoke(self::BEFORE);
97: }
98:
99: /**
100: * Run all registered middlewares (after)
101: */
102: public static function runAfter()
103: {
104: asort(self::$orders[self::AFTER]);
105: self::invoke(self::AFTER);
106: }
107:
108: /**
109: * Run the registered middlewares
110: * @param string $event before or after
111: */
112: private static function invoke($event)
113: {
114: $middlewares = $event == self::AFTER ? self::$after : self::$before;
115:
116: foreach (self::$orders[$event] as $id => $order) {
117: $closure = $middlewares[$id];
118:
119: if (isset(self::$routeFilters[$id])) {
120: $except = array();
121: if (isset(self::$routeFilters[$id][self::FILTER_EXCEPT])) {
122: foreach (self::$routeFilters[$id][self::FILTER_EXCEPT] as $exp) {
123: $exp = is_array($exp) ? $exp : array($exp);
124: $except = array_merge($except, $exp);
125: }
126: unset(self::$routeFilters[$id][self::FILTER_EXCEPT]);
127: }
128:
129: if (count(self::$routeFilters[$id])) {
130: foreach (self::$routeFilters[$id] as $filter => $value) {
131: foreach ($value as $val) {
132: switch($filter) {
133: case self::FILTER_START_WITH:
134: if (route_start($val, $except)) {
135: $closure();
136: }
137: break;
138:
139: case self::FILTER_CONTAIN:
140: $val = is_array($val) ? $val : array($val);
141: if (route_contain($val, $except)) {
142: $closure();
143: }
144: break;
145:
146: case self::FILTER_EQUAL:
147: if (route_equal($val)) {
148: $closure();
149: }
150: break;
151: }
152: }
153: }
154: } else {
155: if (count($except) && call_user_func_array('route_except', $except)) {
156: $closure();
157: }
158: }
159: } else {
160: $closure();
161: }
162: }
163: }
164: }
165: