Completed
Push — master ( 2264f7...ee6db1 )
by Basil
02:53
created

Module::fileToName()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 5
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 2
1
<?php
2
3
namespace luya\base;
4
5
use Yii;
6
use yii\base\InvalidConfigException;
7
use luya\console\interfaces\ImportControllerInterface;
8
use luya\helpers\ObjectHelper;
9
10
/**
11
 * LUYA Module base class.
12
 *
13
 * The module class provides url rule defintions and other helper methods.
14
 *
15
 * In order to use a module within the CMS context it must extend from this base module class.
16
 *
17
 * @property array $urlRules Contains all urlRules for this module. You can either provide a full {{luya\web\UrlRule}} object configuration as array like this:
18
 * ```php
19
 * 'urlRules' => [
20
 *     ['pattern' => 'mymodule/detail/<id:\d+>', 'route' => 'mymodule/detail/user'],
21
 * ],
22
 * ```
23
 *
24
 * Or you can provide a key value pairing where key is the pattern and the value is the route:
25
 *
26
 * ```php
27
 * 'urlRules' => [
28
 *     'mymodule/detail/<id:\d+>' => 'mymodule/detail/user',
29
 * ],
30
 * ```
31
 *
32
 * @author Basil Suter <[email protected]>
33
 * @since 1.0.0
34
 */
35
abstract class Module extends \yii\base\Module
36
{
37
    /**
38
     * @var array Contains the apis for each module to provided them in the admin module. They represents
39
     * the name of the api and the value represents the class. Example value:
40
     *
41
     * ```php
42
     * [
43
     *     'api-admin-user' => 'admin\apis\UserController',
44
     *     'api-cms-navcontainer' => 'admin\apis\NavContainerController'
45
     * ]
46
     * ```
47
     */
48
    public $apis = [];
49
    
50
    /**
51
     * @var array An array with additional rules for a given api name. This allows you to extend and customize the {{yii\rest\UrlRule}} for
52
     * a given API. Example:
53
     *
54
     * ```php
55
     * 'apiRules' => [
56
     *     'api-admin-user' => ['extraPattern' => ['GET {id}/login-list' => 'logins']],
57
     *     'api-admin-group' => ['exception' => ['this-action']],
58
     * ],
59
     * ```
60
     *
61
     * You can define all properties from {{yii\rest\UrlRule}}.
62
     *
63
     * @since 1.0.10
64
     */
65
    public $apiRules = [];
66
67
    /**
68
     * @var array An array with Tag class names to inject into the tag parser on luya boot, where key is the identifier and value the create object conifg:
69
     *
70
     * ```php
71
     * [
72
     *     'link' => 'luya\cms\tags\LinkTag',
73
     *     'file' => ['class' => 'luya\admin\tags\FileTag'],
74
     * ]
75
     * ```
76
     *
77
     * As by default the yii2 configurable object you can also pass properties to your tag object in order to configure them.
78
     */
79
    public $tags = [];
80
    
81
    private $_urlRules = [];
82
    
83
    /**
84
     * UrlRules for this module. You can either provide a full {{luya\web\UrlRule}}
85
     * object configuration as array like this:
86
     *
87
     * ```php
88
     * 'urlRules' => [
89
     *     ['pattern' => 'mymodule/detail/<id:\d+>', 'route' => 'mymodule/detail/user'],
90
     * ],
91
     * ```
92
     *
93
     * Or you can provide a key value pairing where key is the pattern and the value is the route:
94
     *
95
     * ```php
96
     * 'urlRules' => [
97
     *     'mymodule/detail/<id:\d+>' => 'mymodule/detail/user',
98
     * ],
99
     * ```
100
     *
101
     * @var array $rules Contains all urlRules for this module. You can either provide a full {{luya\web\UrlRule}}
102
     * object configuration as array
103
     * @since 1.0.1
104
     */
105
    public function setUrlRules(array $rules)
106
    {
107
        $this->_urlRules = $rules;
108
    }
109
110
    /**
111
     * Getter method for urlRules.
112
     *
113
     * > Never use the getter method, use the $urlRules virtual property as it provides backwards compatibility.
114
     *
115
     * @return array
116
     * @since 1.0.1
117
     */
118
    public function getUrlRules()
119
    {
120
        return $this->_urlRules;
121
    }
122
123
    /**
124
     * @var array An array containing all components which should be registered for the current module. If
125
     * the component does not exists an Exception will be thrown.
126
     */
127
    public $requiredComponents = [];
128
129
    /**
130
     * @var bool Defines the location of the layout file whether in the @app namespace or a module:
131
     *
132
     * - true = looking for layout file in `@app/views/<ID>/layouts`.
133
     * - false = looking for layout file in `@module/views/layouts/`.
134
     *
135
     * This variable is only available if your not in a context call. A context call would be if the cms renders the module.
136
     */
137
    public $useAppLayoutPath = true;
138
    
139
    /**
140
     * @var bool Define the location of the view files inside the controller actions
141
     *
142
     * - true = the view path of the @app/views
143
     * - false = the view path of the @modulename/views
144
     *
145
     */
146
    public $useAppViewPath = false;
147
148
    /**
149
     * @var array mapping from action ID to view configurations.
150
     * Each name-value pair specifies the configuration of a specifed oder wildcard action to a single view folder.
151
     * The first match
152
     * For example,
153
     *
154
     * ```php
155
     * [
156
     *   'default/index' => '@app/views/mymodule/default',
157
     *   'login/info' => '@app/views/mymodule/login',
158
     *   'default/*' => '@app/views/mymodule/default',
159
     *   '*' => '@app/views/mymodule',
160
     * ]
161
     * ```
162
     *
163
     * @since 1.0.11
164
     */
165
    public $viewMap = [];
166
167
    /**
168
     * @var string if this/the module is included via another module (parent module), the parent module will write its
169
     * name inside the child modules $context variable. For example the cms includes the news module, the context variable
170
     * of news would have the value "cms".
171
     */
172
    public $context;
173
174
    /**
175
     * @var string The default name of the moduleLayout
176
     */
177
    public $moduleLayout = 'layout';
178
179
    /**
180
     * @inheritdoc
181
     */
182
    public function init()
183
    {
184
        parent::init();
185
        // verify all the components
186
        foreach ($this->requiredComponents as $component) {
187
            if (!Yii::$app->has($component)) {
188
                throw new InvalidConfigException(sprintf('The required component "%s" is not registered in the configuration file', $component));
189
            }
190
        }
191
        
192
        static::onLoad();
193
    }
194
195
    /**
196
     * Override the default implementation of Yii's getLayoutPath(). If the property `$useAppLayoutPath` is true,.
197
     *
198
     * the *@app* namespace views will be looked up for view files
199
     *
200
     * @return string
201
     * @see \yii\base\Module::getLayoutPath()
202
     */
203
    public function getLayoutPath()
204
    {
205
        if ($this->useAppLayoutPath) {
206
            $this->setLayoutPath('@app/views/'.$this->id.'/layouts');
207
        }
208
209
        return parent::getLayoutPath();
210
    }
211
212
    /**
213
     * Extract the current module from the route and return the new resolved route.
214
     *
215
     * @param string $route Route to resolve, e.g. `admin/default/index`
216
     * @return string The resolved route without the module id `default/index` when input was `admin/default/index`
217
     * and the current module id is `admin`.
218
     */
219
    public function resolveRoute($route)
220
    {
221
        $routeParts = explode('/', $route);
222
        foreach ($routeParts as $k => $v) {
223
            if (($k == 0 && $v == $this->id) || (empty($v))) {
224
                unset($routeParts[$k]);
225
            }
226
        }
227
        if (count($routeParts) == 0) {
228
            return $this->defaultRoute;
229
        }
230
231
        return implode('/', $routeParts);
232
    }
233
234
    /**
235
     * register a component to the application. id => definition. All components will be registered during bootstrap process.
236
     *
237
     * @return array
238
     */
239
    public function registerComponents()
240
    {
241
        return [];
242
    }
243
244
    /**
245
     * Define a last of importer class with an array or run code directily with the import() method.
246
     *
247
     * Can be either an array with classes:
248
     *
249
     * ```php
250
     * public function import(ImportControllerInterface $importer)
251
     * {
252
     *     return [
253
     *         'path\to\class\Import',
254
     *         MyImporterClass::className(),
255
     *     ];
256
     * }
257
     * ```
258
     *
259
     * Or a direct functional call which executes importer things:
260
     *
261
     * ```php
262
     * public function import(ImportControllerInterface $importer)
263
     * {
264
     *     foreach ($importer->getDirectoryFiles('blocks') as $block) {
265
     *         // do something with block file.
266
     *     }
267
     * }
268
     * ```
269
     *
270
     * @param \luya\console\interfaces\ImportControllerInterface $importer The importer controller class which will be invoke to the import method.
271
     * @return boolean|array If an array is returned it must contain object class to created extending from {{luya\console\Command}}.
272
     */
273
    public function import(ImportControllerInterface $importer)
0 ignored issues
show
Unused Code introduced by
The parameter $importer is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
274
    {
275
        return false;
276
    }
277
    
278
    /**
279
     * returns "luya\base" for example.
280
     *
281
     * @return string
282
     */
283
    public function getNamespace()
284
    {
285
        return implode('\\', array_slice(explode('\\', get_class($this)), 0, -1));
286
    }
287
    
288
    /**
289
     * Returns all controller files of this module from the `getControllerPath()` folder, where the key is the reusable
290
     * id of this controller and value the file on the server.
291
     *
292
     * @return array Returns an array where the key is the controller id and value the original file.
293
     */
294
    public function getControllerFiles()
295
    {
296
        return ObjectHelper::getControllers($this);
297
    }
298
    
299
    /**
300
     * Overrides the yii2 default behavior by not throwing an exception if no alias has been defined
301
     * for the controller namespace. Otherwise each module requires an alias for its first namepsace entry
302
     * which results into exception for external modules without an alias.
303
     * exception.
304
     *
305
     * @inheritdoc
306
     */
307
    public function getControllerPath()
308
    {
309
        return Yii::getAlias('@' . str_replace('\\', '/', $this->controllerNamespace), false);
310
    }
311
312
    // STATIC METHODS
313
314
    /**
315
     * Internal used to register the translations from the translation array or set alias paths.
316
     *
317
     * This is a static behavior, so we can call this call without the object context, for example when
318
     * the composer plugin registers blocks but the module is not registered with translations.
319
     *
320
     * @return void
321
     */
322
    public static function onLoad()
323
    {
324
    }
325
    
326
    /**
327
     * Register a Translation to the i18n component.
328
     *
329
     * In order to register Translations you can register them inside the {{luya\base\Module::onLoad()}} method.
330
     *
331
     * ```php
332
     * public static function onLoad()
333
     * {
334
     *     $this->registerTranslation('mymodule*', static::staticBasePath() . '/messages', [
335
     *         'mymodule' => 'mymodule.php',
336
     *         'mymodule/sub' => 'sub.php',
337
     *     ]);
338
     * }
339
     * ```
340
     *
341
     * @param string $prefix The prefix of which the messages are indicated
342
     * @param string $basePath The path to the messages folder where the messages are located.
343
     * @param array $fileMap The files mapping inside the messages folder.
344
     */
345
    public static function registerTranslation($prefix, $basePath, array $fileMap)
346
    {
347
        if (!isset(Yii::$app->i18n->translations[$prefix])) {
348
            Yii::$app->i18n->translations[$prefix] = [
349
                'class' => 'yii\i18n\PhpMessageSource',
350
                'basePath' => $basePath,
351
                'fileMap' => $fileMap,
352
            ];
353
        }
354
    }
355
    
356
    /**
357
     * Get base path from static view port.
358
     *
359
     * @return string
360
     */
361
    public static function staticBasePath()
362
    {
363
        $class = new \ReflectionClass(get_called_class());
364
        
365
        return dirname($class->getFileName());
366
    }
367
368
    /**
369
     * Base translation method which invokes the onLoad function.
370
     *
371
     * This makes it possible to register module translations without adding the module
372
     * to the components list. This is very important for luya extensions.
373
     *
374
     * @param string $category the message category.
375
     * @param string $message the message to be translated.
376
     * @param array $params the parameters that will be used to replace the corresponding placeholders in the message.
377
     * @param string $language the language code (e.g. `en-US`, `en`). If this is null, the current
378
     * [[\yii\base\Application::language|application language]] will be used.
379
     * @return string the translated message.
380
     */
381
    public static function baseT($category, $message, array $params = [], $language = null)
382
    {
383
        static::onLoad();
384
        return Yii::t($category, $message, $params, $language);
385
    }
386
}
387