]> BookStack Code Mirror - bookstack/blob - app/Theming/ThemeService.php
0c252653699dfa48e8d34deab8423f4c67775a8d
[bookstack] / app / Theming / ThemeService.php
1 <?php
2
3 namespace BookStack\Theming;
4
5 use BookStack\Access\SocialAuthService;
6 use BookStack\Exceptions\ThemeException;
7 use Illuminate\Console\Application;
8 use Illuminate\Console\Application as Artisan;
9 use Symfony\Component\Console\Command\Command;
10
11 class ThemeService
12 {
13     /**
14      * @var array<string, callable[]>
15      */
16     protected array $listeners = [];
17
18     /**
19      * Listen to a given custom theme event,
20      * setting up the action to be ran when the event occurs.
21      */
22     public function listen(string $event, callable $action): void
23     {
24         if (!isset($this->listeners[$event])) {
25             $this->listeners[$event] = [];
26         }
27
28         $this->listeners[$event][] = $action;
29     }
30
31     /**
32      * Dispatch the given event name.
33      * Runs any registered listeners for that event name,
34      * passing all additional variables to the listener action.
35      *
36      * If a callback returns a non-null value, this method will
37      * stop and return that value itself.
38      */
39     public function dispatch(string $event, ...$args): mixed
40     {
41         foreach ($this->listeners[$event] ?? [] as $action) {
42             $result = call_user_func_array($action, $args);
43             if (!is_null($result)) {
44                 return $result;
45             }
46         }
47
48         return null;
49     }
50
51     /**
52      * Check if there are listeners registered for the given event name.
53      */
54     public function hasListeners(string $event): bool
55     {
56         return count($this->listeners[$event] ?? []) > 0;
57     }
58
59     /**
60      * Register a new custom artisan command to be available.
61      */
62     public function registerCommand(Command $command): void
63     {
64         Artisan::starting(function (Application $application) use ($command) {
65             $application->addCommands([$command]);
66         });
67     }
68
69     /**
70      * Read any actions from the set theme path if the 'functions.php' file exists.
71      */
72     public function readThemeActions(): void
73     {
74         $themeActionsFile = theme_path('functions.php');
75         if ($themeActionsFile && file_exists($themeActionsFile)) {
76             try {
77                 require $themeActionsFile;
78             } catch (\Error $exception) {
79                 throw new ThemeException("Failed loading theme functions file at \"{$themeActionsFile}\" with error: {$exception->getMessage()}");
80             }
81         }
82     }
83
84     /**
85      * @see SocialAuthService::addSocialDriver
86      */
87     public function addSocialDriver(string $driverName, array $config, string $socialiteHandler, callable $configureForRedirect = null): void
88     {
89         $socialAuthService = app()->make(SocialAuthService::class);
90         $socialAuthService->addSocialDriver($driverName, $config, $socialiteHandler, $configureForRedirect);
91     }
92 }