1: <?php
2: /**
3: * This code is licensed under AGPLv3 license or Afterlogic Software License
4: * if commercial version of the product was purchased.
5: * For full statements of the licenses see LICENSE-AFTERLOGIC and LICENSE-AGPL3 files.
6: */
7:
8: namespace Aurora\System;
9:
10: /**
11: * @license https://www.gnu.org/licenses/agpl-3.0.html AGPL-3.0
12: * @license https://afterlogic.com/products/common-licensing Afterlogic Software License
13: * @copyright Copyright (c) 2019, Afterlogic Corp.
14: *
15: * @package Api
16: */
17: class Router
18: {
19: /**
20: * @var array
21: */
22: protected $aRoutes;
23:
24: protected static $self = null;
25:
26: public function __construct()
27: {
28: $this->aRoutes = [];
29: }
30:
31: /**
32: * @return \Aurora\System\Router
33: */
34: public static function getInstance()
35: {
36: if (is_null(self::$self)) {
37: self::$self = new self();
38: }
39:
40: return self::$self;
41: }
42:
43: public function register($sModule, $sName, $mCallbak)
44: {
45: if (!isset($this->aRoutes[$sName][$sModule])) {
46: $this->aRoutes[$sName][$sModule] = $mCallbak;
47: }
48: }
49:
50: public function registerArray($sModule, $aRoutes)
51: {
52: foreach ($aRoutes as $sName => $mCallbak) {
53: $this->register($sModule, $sName, $mCallbak);
54: }
55: }
56:
57: /**
58: *
59: * @param string $sName
60: * @return mixed
61: */
62: public function getCallback($sName)
63: {
64: $mResult = false;
65: if (isset($this->aRoutes[$sName])) {
66: $mResult = $this->aRoutes[$sName];
67: }
68:
69: return $mResult;
70: }
71:
72: public function hasCallback($mCallbak)
73: {
74: $aCallbacks = [];
75: foreach ($this->aRoutes as $sRoute => $aRoutes) {
76: foreach ($aRoutes as $sModule => $aRoute) {
77: if (!in_array($aRoute[1], $aCallbacks)) {
78: $aCallbacks[] = $aRoute[1];
79: }
80: }
81: }
82:
83: return in_array($mCallbak, $aCallbacks);
84: }
85:
86: public function hasRoute($sName)
87: {
88: return isset($this->aRoutes[$sName]);
89: }
90:
91: public function route($sName)
92: {
93: $mResult = [];
94: $oHttp = \MailSo\Base\Http::SingletonInstance();
95:
96: $mMethod = $this->getCallback($sName);
97: if ($mMethod) {
98: foreach ($mMethod as $sModule => $mCallbak) {
99: if (\Aurora\System\Api::GetModuleManager()->IsAllowedModule($sModule)) {
100: \Aurora\System\Api::Log(" ");
101: \Aurora\System\Api::Log(" ===== ENTRY: " . $sModule . '::' . $sName);
102: \Aurora\System\Api::Log(" URL: " . $oHttp->GetUrl());
103: $mResult[] = call_user_func_array(
104: $mCallbak,
105: []
106: );
107: }
108: }
109: }
110:
111: // This is an unsupported case. Work with multiple callbacks of one an entry point was kept for backward compatibility.
112: if (count($mResult) > 1) {
113: \Aurora\System\Api::Log(" WARNING: More than one entry result returned");
114: }
115:
116: return $mResult[0] ?? false;
117: }
118:
119: public function removeRoute($sName)
120: {
121: unset($this->aRoutes[$sName]);
122: }
123:
124: /**
125: * @return array
126: */
127: public static function getItems()
128: {
129: static $aResult = null;
130: if ($aResult === null) {
131: $aResult = array();
132:
133: $oHttp = \MailSo\Base\Http::SingletonInstance();
134:
135: $sQuery = \trim(\trim(urldecode($oHttp->GetQueryString())), ' /');
136:
137: $iPos = \strpos($sQuery, '&');
138: if (0 < $iPos) {
139: $sQuery = \substr($sQuery, 0, $iPos);
140: }
141: $aQuery = \explode('/', $sQuery);
142: foreach ($aQuery as $sQueryItem) {
143: $iPos = \strpos($sQueryItem, '=');
144: $aResult[] = (!$iPos) ? $sQueryItem : \substr($sQueryItem, 0, $iPos);
145: }
146: }
147:
148: return $aResult;
149: }
150:
151: /**
152: *
153: * @param int $iIndex
154: */
155: public static function getItemByIndex($iIndex, $mDefaultValue = null)
156: {
157: $aPath = self::getItems();
158:
159: return !empty($aPath[$iIndex]) ? $aPath[$iIndex] : $mDefaultValue;
160: }
161: }
162: