1 | <?php |
||
50 | class Service |
||
51 | { |
||
52 | /** |
||
53 | * Registered repositories |
||
54 | * |
||
55 | * @var array |
||
56 | */ |
||
57 | protected $registry = []; |
||
58 | /** |
||
59 | * Repository auto-connector service |
||
60 | * |
||
61 | * @var AutoConnectorInterface |
||
62 | */ |
||
63 | protected $autoConnector = null; |
||
64 | /** |
||
65 | * Adapter strategy factory |
||
66 | * |
||
67 | * @var AdapterStrategyFactoryInterface |
||
68 | */ |
||
69 | protected $adptStrategyFactory = null; |
||
70 | /** |
||
71 | * Object manager |
||
72 | * |
||
73 | * @var ManagerInterface |
||
74 | */ |
||
75 | protected $objectManager = null; |
||
76 | /** |
||
77 | * Auto-connect to repositories |
||
78 | * |
||
79 | * @var bool |
||
80 | */ |
||
81 | protected $autoConnectEnabled = true; |
||
82 | |||
83 | /******************************************************************************* |
||
84 | * PUBLIC METHODS |
||
85 | *******************************************************************************/ |
||
86 | |||
87 | /** |
||
88 | * Repository service constructor |
||
89 | * |
||
90 | * @param AutoConnectorInterface $autoConnector Auto-connector |
||
91 | * @param AdapterStrategyFactoryInterface $adptStrategyFactory Adapter strategy factory |
||
92 | * @param ManagerInterface $objectManager Object manager |
||
93 | */ |
||
94 | public function __construct( |
||
95 | AutoConnectorInterface $autoConnector, |
||
96 | AdapterStrategyFactoryInterface $adptStrategyFactory, |
||
97 | ManagerInterface $objectManager |
||
98 | ) { |
||
99 | $this->autoConnector = $autoConnector; |
||
100 | $this->adptStrategyFactory = $adptStrategyFactory; |
||
101 | $this->objectManager = $objectManager; |
||
102 | } |
||
103 | |||
104 | /** |
||
105 | * Reset the repository service |
||
106 | * |
||
107 | * @return Service Self reference |
||
108 | */ |
||
109 | 3 | public function reset() |
|
114 | |||
115 | /** |
||
116 | * Pre-register a repository |
||
117 | * |
||
118 | * The purpose of repository pre-registration is to provide custom arguments (like a base |
||
119 | * directory or basic authentication credentials. |
||
120 | * The repository URL may be local or remote, relative or absolute, with Apparat or HTTP scheme. |
||
121 | * |
||
122 | * @param string|ObjectUrl $url Repository URL |
||
123 | * @param RepositoryInterface $repository Repository |
||
124 | */ |
||
125 | 18 | public function register($url, RepositoryInterface $repository) |
|
131 | |||
132 | /** |
||
133 | * Normalize a repository URL |
||
134 | * |
||
135 | * @param string|ObjectUrl $url Repository URL |
||
136 | * @return string Normalized repository URL |
||
137 | * @throws InvalidArgumentException If the repository URL is invalid |
||
138 | */ |
||
139 | 69 | public static function normalizeRepositoryUrl($url) |
|
140 | { |
||
141 | // If it's an apparat URL |
||
142 | 69 | if ($url instanceof ApparatUrl) { |
|
143 | 3 | $url = $url->getNormalizedRepositoryUrl(); |
|
144 | |||
145 | // Else: If it's an object URL |
||
146 | } elseif ($url instanceof ObjectUrl) { |
||
147 | 1 | $url = $url->getRepositoryUrl(); |
|
148 | |||
149 | // Else: If it's an empty URL |
||
150 | 67 | } elseif ($url === null) { |
|
151 | 3 | return ''; |
|
152 | } |
||
153 | |||
154 | // If the URL is a string |
||
155 | 68 | if (is_string($url)) { |
|
156 | // Strip the leading apparat base URL |
||
157 | 67 | $apparatBaseUrl = getenv('APPARAT_BASE_URL'); |
|
158 | 67 | if (strpos($url, $apparatBaseUrl) === 0) { |
|
159 | 1 | $url = strval(substr($url, strlen($apparatBaseUrl))); |
|
160 | } |
||
161 | |||
162 | // Ensure this is a bare URL (without query and fragment) |
||
163 | 67 | if (Module::isAbsoluteBareUrl($apparatBaseUrl.$url)) { |
|
164 | 66 | return $url; |
|
165 | } |
||
166 | } |
||
167 | |||
168 | // The URL is invalid, throw an error |
||
169 | 1 | throw new InvalidArgumentException( |
|
170 | 1 | sprintf('Invalid repository URL "%s"', $url), |
|
171 | 1 | InvalidArgumentException::INVALID_REPOSITORY_URL |
|
172 | ); |
||
173 | } |
||
174 | |||
175 | /** |
||
176 | * Return an object repository by URL |
||
177 | * |
||
178 | * If a repository URL has not been pre-registered, the method tries to perform an ad-hoc registration |
||
179 | * based on the URL given. |
||
180 | * The repository URL may be local or remote, relative or absolute, with Apparat or HTTP scheme. |
||
181 | * |
||
182 | * @param string|ObjectUrl $url Repository URL |
||
183 | * @return \Apparat\Object\Domain\Repository\Repository Object repository |
||
184 | * @throws InvalidArgumentException If the repository URL is invalid |
||
185 | * @throws InvalidArgumentException If the repository URL is unknown |
||
186 | */ |
||
187 | 36 | public function get($url) |
|
188 | { |
||
189 | 36 | $url = ltrim(self::normalizeRepositoryUrl($url), '/'); |
|
190 | |||
191 | // If the repository URL is unknown |
||
192 | 35 | if (!self::connected($url)) { |
|
193 | 2 | throw new InvalidArgumentException( |
|
194 | 2 | sprintf('Unknown repository URL "%s"', $url), |
|
195 | 2 | InvalidArgumentException::UNKNOWN_REPOSITORY_URL |
|
196 | ); |
||
197 | } |
||
198 | |||
199 | // Return the repository instance |
||
200 | 33 | return $this->registry[$url]; |
|
201 | } |
||
202 | |||
203 | /** |
||
204 | * Test whether a repository URL registered or can be auto-connected |
||
205 | * |
||
206 | * @param string $url Repository URL |
||
207 | * @return bool Repository is connected |
||
208 | */ |
||
209 | 36 | protected function connected($url) |
|
210 | { |
||
211 | // If the given repository URL is already registered: Success |
||
212 | 36 | if (!empty($this->registry[$url])) { |
|
213 | 31 | return true; |
|
214 | } |
||
215 | |||
216 | // If auto-connect is enabled: Try to auto-connect the requested repository |
||
217 | 5 | return $this->autoConnectEnabled && $this->autoConnector->connect($url); |
|
218 | } |
||
219 | |||
220 | /** |
||
221 | * Test whether a repository URL is registered |
||
222 | * |
||
223 | * @param string|ObjectUrl $url Repository URL |
||
224 | * @return bool Repository URL is registered |
||
225 | */ |
||
226 | 37 | public function isRegistered($url) |
|
227 | { |
||
228 | 37 | $url = ltrim(self::normalizeRepositoryUrl($url), '/'); |
|
229 | 37 | return array_key_exists($url, $this->registry) || self::connected($url); |
|
230 | } |
||
231 | |||
232 | /** |
||
233 | * Return the adapter strategy factory |
||
234 | * |
||
235 | * @return AdapterStrategyFactoryInterface Adapter strategy factory |
||
236 | */ |
||
237 | 24 | public function getAdapterStrategyFactory() |
|
241 | |||
242 | /** |
||
243 | * Return the object manager |
||
244 | * |
||
245 | * @return ManagerInterface Object manager |
||
246 | */ |
||
247 | 49 | public function getObjectManager() |
|
251 | |||
252 | /******************************************************************************* |
||
253 | * PRIVATE METHODS |
||
254 | *******************************************************************************/ |
||
255 | |||
256 | /** |
||
257 | * Enable repository auto-connections |
||
258 | * |
||
259 | * If the method is called without any arguments it will just return the current auto-connection state. |
||
260 | * |
||
261 | * @param null|boolean $autoConnect Enable / disable auto-connections |
||
262 | * @return bool Status of repository auto-connection |
||
263 | */ |
||
264 | 23 | public function useAutoConnect($autoConnect = null) |
|
271 | } |
||
272 |