Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 34
0.00% covered (danger)
0.00%
0 / 8
CRAP
0.00% covered (danger)
0.00%
0 / 1
MixinController
0.00% covered (danger)
0.00%
0 / 34
0.00% covered (danger)
0.00%
0 / 8
342
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getContext
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getMagicWords
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 loadPhp
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
20
 getPreloadJsSnippets
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
20
 getResourceLoaderModules
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
12
 registerMagicWord
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 renderMagicWord
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
12
1<?php
2
3use MediaWiki\Context\IContextSource;
4
5class MixinController {
6
7    /** @var array */
8    private $magicWords = [];
9
10    /**
11     * @param IContextSource $uiContext
12     * @param array<string,array> $mixins
13     */
14    public function __construct(
15        private readonly IContextSource $uiContext,
16        private readonly array $mixins,
17    ) {
18        $this->loadPhp();
19    }
20
21    public function getContext(): IContextSource {
22        return $this->uiContext;
23    }
24
25    /**
26     * @return string[]
27     */
28    public function getMagicWords() {
29        $words = array_keys( $this->magicWords );
30        sort( $words );
31        return $words;
32    }
33
34    /**
35     * Initialize php modules.
36     *
37     * @throws MixinNotFoundException
38     */
39    public function loadPhp() {
40        foreach ( $this->mixins as $name => $info ) {
41            if ( !empty( $info['php'] ) ) {
42                // The module must register itself with this controller.
43                $php_module_path = $info['localBasePath'] . DIRECTORY_SEPARATOR . $info['php'];
44                // Strip the file extension and assume the mixin class is eponymous.
45                // TODO: maybe they should be registered using hooks instead...
46                $php_module_name = preg_replace( "/[.].+$/", "", $info['php'] );
47                require_once $php_module_path;
48                $mod = new $php_module_name();
49                if ( !( $mod instanceof IBannerMixin ) ) {
50                    throw new MixinNotFoundException( $name );
51                }
52                $mod->register( $this );
53            }
54        }
55    }
56
57    /**
58     * @throws MixinNotFoundException
59     */
60    public function getPreloadJsSnippets(): array {
61        $snippets = [];
62        foreach ( $this->mixins as $name => $info ) {
63            if ( !empty( $info['preloadJs'] ) ) {
64                $filename = $info['localBasePath'] . DIRECTORY_SEPARATOR . $info['preloadJs'];
65                $snippet = file_get_contents( $filename );
66                if ( !$snippet ) {
67                    throw new MixinNotFoundException( $name );
68                }
69                $snippets[$name] = $snippet;
70            }
71        }
72        return $snippets;
73    }
74
75    public function getResourceLoaderModules(): array {
76        $modules = [];
77        foreach ( $this->mixins as $name => $info ) {
78            if ( !empty( $info['resourceLoader'] ) ) {
79                $modules[$name] = $info['resourceLoader'];
80            }
81        }
82        return $modules;
83    }
84
85    /**
86     * @param string $word
87     * @param callable $callback
88     */
89    public function registerMagicWord( $word, $callback ) {
90        $this->magicWords[$word] = $callback;
91    }
92
93    /**
94     * @param string $word
95     * @param array $params
96     * @return mixed
97     */
98    public function renderMagicWord( $word, $params = [] ) {
99        if ( array_key_exists( $word, $this->magicWords ) ) {
100            $callback = $this->magicWords[$word];
101            if ( is_callable( $callback ) ) {
102                return $callback( ...$params );
103            }
104        }
105    }
106}