1 <?php
2
3 4 5 6 7 8 9 10
11
12 namespace Icybee;
13
14 use ICanBoogie\Debug;
15 use ICanBoogie\Event;
16 use ICanBoogie\Events;
17 use ICanBoogie\Exception;
18 use ICanBoogie\HTTP\Dispatcher;
19 use ICanBoogie\HTTP\Request;
20 use ICanBoogie\HTTP\Response;
21 use ICanBoogie\HTTP\RedirectResponse;
22 use ICanBoogie\HTTP\WeightedDispatcher;
23 use ICanBoogie\Operation;
24 use ICanBoogie\Routes;
25
26 use Brickrouge\Alert;
27
28 use Icybee\Modules\Pages\PageController;
29
30 class Hooks
31 {
32 33 34
35
36 static public function on_http_dispatcher_alter(Dispatcher\AlterEvent $event, Dispatcher $dispatcher)
37 {
38 39 40 41 42 43 44 45
46 $dispatcher['admin:categories'] = new WeightedDispatcher(function(Request $request)
47 {
48 global $core;
49
50 $path = \ICanBoogie\normalize_url_path(\ICanBoogie\Routing\decontextualize($request->path));
51
52 if (strpos($path, '/admin/') !== 0)
53 {
54 return;
55 }
56
57 $category = substr($path, 7, -1);
58
59 if ($category)
60 {
61 $user = $core->user;
62 $routes = $core->routes;
63
64 foreach ($core->modules->descriptors as $module_id => $descriptor)
65 {
66 if (!isset($core->modules[$module_id]) || !$user->has_permission(Module::PERMISSION_ACCESS, $module_id)
67 || $descriptor[Module::T_CATEGORY] != $category)
68 {
69 continue;
70 }
71
72 $route_id = "admin:$module_id";
73
74 if (empty($routes[$route_id]))
75 {
76 $route_id = "admin:$module_id/manage";
77
78 if (empty($routes[$route_id]))
79 {
80 continue;
81 }
82 }
83
84 $route = $routes[$route_id];
85
86 return new RedirectResponse
87 (
88 \ICanBoogie\Routing\contextualize($route->pattern), 302, array
89 (
90 'Icybee-Redirected-By' => __FILE__ . '::' . __LINE__
91 )
92 );
93 }
94 }
95 }, 'before:pages');
96 }
97
98 static public function before_routes_collect(Routes\BeforeCollectEvent $event, Routes $target)
99 {
100 static $magic = array
101 (
102 '!admin:manage' => true,
103 '!admin:new' => true,
104 '!admin:config' => true,
105 '!admin:edit' => true
106 );
107
108 $fragments = array();
109
110 foreach ($event->fragments as $root => $fragment)
111 {
112 $add_delete_route = false;
113
114 foreach ($fragment as $id => $route)
115 {
116 if (empty($magic[$id]))
117 {
118 if (isset($route['block']) && empty($route['controller']))
119 {
120 $route['controller'] = 'Icybee\BlockController';
121 }
122
123 $fragments[$root][$id] = $route;
124
125 continue;
126 }
127
128 $module_id = $route['module'];
129
130 switch ($id)
131 {
132 case '!admin:manage':
133 {
134 $id = "admin:$module_id/manage";
135
136 $route += array
137 (
138 'pattern' => "/admin/$module_id",
139 'controller' => 'Icybee\BlockController',
140 'title' => '.manage',
141 'block' => 'manage',
142 'index' => true
143 );
144 }
145 break;
146
147 case '!admin:new':
148 {
149 $id = "admin:$module_id/new";
150
151 $route += array
152 (
153 'pattern' => "/admin/$module_id/new",
154 'controller' => 'Icybee\BlockController',
155 'title' => '.new',
156 'block' => 'edit',
157 'visibility' => 'visible'
158 );
159 }
160 break;
161
162 case '!admin:edit':
163 {
164 $id = "admin:$module_id/edit";
165
166 $route += array
167 (
168 'pattern' => "/admin/$module_id/<\d+>/edit",
169 'controller' => 'Icybee\EditController',
170 'title' => '.edit',
171 'block' => 'edit',
172 'visibility' => 'auto'
173 );
174
175 $add_delete_route = true;
176 }
177 break;
178
179 case '!admin:config':
180 {
181 $id = "admin:$module_id/config";
182
183 $route += array
184 (
185 'pattern' => "/admin/$module_id/config",
186 'controller' => 'Icybee\BlockController',
187 'title' => '.config',
188 'block' => 'config',
189 'permission' => Module::PERMISSION_ADMINISTER,
190 'visibility' => 'visible'
191 );
192 }
193 break;
194 }
195
196 $fragments[$root][$id] = $route;
197 }
198
199 if ($add_delete_route)
200 {
201 $fragments[$root]["admin:$module_id/delete"] = array
202 (
203 'pattern' => "/admin/$module_id/<\d+>/delete",
204 'controller' => 'Icybee\BlockController',
205 'title' => '.delete',
206 'block' => 'delete',
207 'visibility' => 'auto',
208 'via' => 'ANY',
209 'module' => $module_id
210 );
211 }
212 }
213
214
215
216
217
218 $event->fragments = $fragments;
219 }
220
221 222 223 224 225 226 227
228 static public function dispatch_query_operation(Request $request)
229 {
230 global $core;
231
232 $class = 'Icybee\Operation\Module\QueryOperation';
233 $try_module = $module = $core->modules[$request['module']];
234
235 while ($try_module)
236 {
237 $try = Operation::format_class_name($try_module->descriptor[Module::T_NAMESPACE], 'QueryOperation');
238
239 if (class_exists($try, true))
240 {
241 $class = $try;
242
243 break;
244 }
245
246 $try_module = $try_module->parent;
247 }
248
249 return new $class($module, $request);
250 }
251
252 253 254 255 256
257 static public function before_user_logout(Event $event)
258 {
259 global $core;
260
261 $uid = $core->user_id;
262
263 if (!$uid)
264 {
265 return;
266 }
267
268 try
269 {
270 $registry = $core->registry;
271
272 $names = $registry
273 ->where('name LIKE "activerecord_locks.%" AND value LIKE ?', '{"uid":"' . $uid . '"%')
274 ->delete();
275 }
276 catch (\Exception $e) { };
277 }
278
279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295
296 static public function before_save_operation_control(\ICanBoogie\Operation\BeforeControlEvent $event, \ICanBoogie\SaveOperation $target)
297 {
298 global $core;
299
300 $mode = $event->request[OPERATION_SAVE_MODE];
301
302 if (!$mode)
303 {
304 return;
305 }
306
307 $core->session->operation_save_mode[$target->module->id] = $mode;
308
309 $eh = $core->events->attach(function(\ICanBoogie\Operation\ProcessEvent $event, \ICanBoogie\SaveOperation $operation) use($mode, $target, &$eh) {
310
311 $eh->detach();
312
313 if ($operation != $target || $event->request->uri != $event->response->location)
314 {
315 return;
316 }
317
318 $location = '/admin/' . $target->module->id;
319
320 switch ($mode)
321 {
322 case OPERATION_SAVE_MODE_CONTINUE:
323 {
324 $location .= '/' . $event->rc['key'] . '/edit';
325 }
326 break;
327
328 case OPERATION_SAVE_MODE_NEW:
329 {
330 $location .= '/new';
331 }
332 break;
333
334 case OPERATION_SAVE_MODE_DISPLAY:
335 {
336 try
337 {
338 $url = $target->record->url;
339
340 if ($url && $url{0} != '#')
341 {
342 $location = $url;
343 }
344 }
345 catch (\Exception $e)
346 {
347 return;
348 }
349 }
350 break;
351 }
352
353 if ($mode != OPERATION_SAVE_MODE_DISPLAY)
354 {
355 $location = \ICanBoogie\Routing\contextualize($location);
356 }
357
358 $event->response->location = $location;
359
360 });
361 }
362
363 static private $page_controller_loaded_nodes = [];
364
365 366 367 368
369 static public function before_page_controller_render()
370 {
371 global $core;
372
373 $core->events->attach(function(\BlueTihi\Context\LoadedNodesEvent $event, \BlueTihi\Context $target) {
374
375 $nodes = &self::$page_controller_loaded_nodes;
376
377 foreach ($event->nodes as $node)
378 {
379 if (!$node instanceof \Icybee\Modules\Nodes\Node)
380 {
381 \ICanBoogie\log('Not a node object: {0}', [ $node ]);
382
383 continue;
384 }
385
386 $nodes[$node->nid] = $node;
387 }
388
389 });
390 }
391
392 393 394 395 396 397
398 static public function on_page_controller_render(\Icybee\Modules\Pages\PageController\RenderEvent $event, \Icybee\Modules\Pages\PageController $target)
399 {
400 $admin_menu = (string) new Element\AdminMenu([
401
402 Element\AdminMenu::NODES => self::$page_controller_loaded_nodes
403
404 ]);
405
406 if ($admin_menu)
407 {
408 $event->html = str_replace('</body>', $admin_menu . '</body>', $event->html);
409 }
410 }
411
412 413 414
415
416 static public function get_cldr()
417 {
418 static $cldr;
419
420 if (!$cldr)
421 {
422 $provider = new \ICanBoogie\CLDR\Provider
423 (
424 new \ICanBoogie\CLDR\RunTimeCache(new \ICanBoogie\CLDR\FileCache(\ICanBoogie\REPOSITORY . 'cldr' . DIRECTORY_SEPARATOR)),
425 new \ICanBoogie\CLDR\Retriever
426 );
427
428 $cldr = new \ICanBoogie\CLDR\Repository($provider);
429 }
430
431 return $cldr;
432 }
433
434 435 436
437
438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457
458 static public function markup_alerts(array $args, $engine, $template)
459 {
460 global $core;
461
462 $key = '<!-- alert-markup-placeholder-' . uniqid() . ' -->';
463
464 $core->events->attach
465 (
466 function(PageController\RenderEvent $event, PageController $target) use($engine, $template, $key)
467 {
468 $types = array('success', 'info', 'error');
469
470 if (Debug::$mode == Debug::MODE_DEV)
471 {
472 $types[] = 'debug';
473 }
474
475 $alerts = '';
476
477 foreach ($types as $type)
478 {
479 $alerts .= new Alert(Debug::fetch_messages($type), array(Alert::CONTEXT => $type));
480 }
481
482 if ($template)
483 {
484 $alerts = $engine($template, $alerts);
485 }
486
487 $event->html = str_replace($key, $alerts, $event->html);
488 }
489 );
490
491 return $key;
492 }
493
494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512
513 static public function markup_body(array $args, $engine, $template)
514 {
515 global $core;
516
517 return '<body class="' . trim($args['class'] . ' ' . $core->document->css_class) . '">' . $engine($template) . '</body>';
518 }
519 }