Completed
Push — master ( aea7bf...a66a99 )
by Basil
03:25
created

ApplicationTrait::ensureLocale()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 14
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 14
rs 9.4285
cc 3
eloc 6
nc 3
nop 1
1
<?php
2
3
namespace luya\traits;
4
5
use Yii;
6
use luya\base\AdminModuleInterface;
7
use luya\base\Module;
8
use luya\base\CoreModuleInterface;
9
use luya\base\PackageInstaller;
10
11
/**
12
 * LUYA Appliation trait
13
 *
14
 * @property string $webroot Returns the webroot directory event for console commands.
15
 * @property \luya\components\Mail $mail Get luya mail component
16
 *
17
 * @author Basil Suter <[email protected]>
18
 * @since 1.0.0
19
 */
20
trait ApplicationTrait
21
{
22
    /**
23
     * @var string Title for the application used in different sections like Login screen
24
     */
25
    public $siteTitle = 'LUYA Application';
26
    
27
    /**
28
     * @var string|boolean Set a token, which will be used to collect data from a central host, if you want to enable this feature.
29
     * Use http://passwordsgenerator.net/ to create complex strings. When you have enabled this feature you can collect information's from
30
     * all your hosts with `example.com/admin/remote?token=Sha1EncodedRemoteToken`.
31
     */
32
    public $remoteToken = false;
33
34
    /**
35
     * @var string The directory where your webroot represents, this is basically used to find the webroot directory
36
     * in the console mode, cause some importer classes need those variables.
37
     */
38
    public $webrootDirectory = 'public_html';
39
    
40
    /**
41
     * @var string This value will be used as hostInfo when running console applications in urlManager. An example for using the hostInfo
42
     *
43
     * ```php
44
     * 'consoleHostInfo' => 'https://luya.io'
45
     * ```
46
     */
47
    public $consoleHostInfo;
48
    
49
    /**
50
     * @var string This value is used when declared for console request as urlManger baseUrl in order to enable urlHandling. If {{luya\web\traits\ApplicationTrait::$consoleHostInfo}}
51
     * is defined, consoleBaseUrl will use `/` as default value. The base url is the path where the application is running after hostInfo like
52
     *
53
     * ```php
54
     * 'consoleBaseUrl' => '/luya-kickstarter'
55
     * ```
56
     *
57
     * But in the most cases when the website is online the baseUrl is `/` which is enabled by default when {{luya\web\traits\ApplicationTrait::$consoleHostInfo}} is defined.
58
     */
59
    public $consoleBaseUrl;
60
    
61
    /**
62
     * @var boolean If enabled, the application will throw an exception if a request is not from a secure connection (https). So any none secure request will throw
63
     * a {{yii\web\ForbiddenHttpException}}. This option will also make sure REST APIs are requested by a secure connection.
64
     * @since 1.0.5
65
     */
66
    public $ensureSecureConnection = false;
67
    
68
    /**
69
     * @var array Add tags to the TagParser class. Example
70
     *
71
     * ```php
72
     * 'tags' => [
73
     *     'foobar' => ['class' => '\app\tags\FoobarTag'],
74
     * ],
75
     * ```
76
     */
77
    public $tags = [];
78
79
    /**
80
     * @var array Can override the localisation value used for php internal `setlocale()` method for specific language. For example
81
     * the language is de but the it should use the locale charset `de_CH.utf8` (locale -a will return all locales installed on the server)
82
     * you can define them inside an array where key is the language and value the locale value to be used.
83
     *
84
     * ```php
85
     * public $locales = [
86
     *    'de' => 'de_CH',
87
     *    'en' => 'en_GB',
88
     * ];
89
     * ```
90
     */
91
    public $locales = [];
92
    
93
    /**
94
     * Add trace info to luya application trait
95
     */
96
    public function init()
97
    {
98
        parent::init();
99
        
100
        // add trace info
101
        Yii::trace('initialize LUYA Application', __METHOD__);
0 ignored issues
show
Deprecated Code introduced by
The method yii\BaseYii::trace() has been deprecated with message: since 2.0.14. Use [[debug()]] instead.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
102
        
103
        $this->setLocale($this->language);
0 ignored issues
show
Bug introduced by
The property language does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
104
    }
105
    
106
    /**
107
     * Transform the $language into a locale sign to set php env settings.
108
     *
109
     * Example transform input `de` to `de_CH` when available $locales property as
110
     * 
111
     * ```php
112
     * 'locales' => ['de' => 'de_CH']
113
     * ```
114
     *
115
     * @param string $lang Find the locale POSIX for the provided $lang short code.
116
     * @return string The localisation code for the provided lang short code.
117
     */
118
    public function ensureLocale($lang)
119
    {
120
        // see if the $lang is available in the $locales map.
121
        if (array_key_exists($lang, $this->locales)) {
122
            return $this->locales[$lang];
123
        }
124
        
125
        // generate from `de` the locale `de_DE` or from `en` `en_EN` only if $lang is 2 chars.
126
        if (strlen($lang) == 2) {
127
            return strtolower($lang) . '_' . strtoupper($lang);
128
        }
129
        
130
        return $lang;
131
    }
132
    
133
    /**
134
     * Setter method ensures the locilations POSIX from {{ensureLocale}} for the provided lang
135
     * and changes the Yii::$app->langauge and sets the `setlocale()` code from ensureLocale().
136
     *
137
     * From the setlocale docs about, try different locales:
138
     *
139
     * > If locale is an array or followed by additional parameters then each array element or parameter
140
     * > is tried to be set as new locale until success. This is useful if a locale is known under different
141
     * > names on different systems or for providing a fallback for a possibly not available locale.
142
     *
143
     * @param string $lang The language short code to set the locale for.
144
     */
145
    public function setLocale($lang)
146
    {
147
        $locale = str_replace(['.utf8', '.UTF-8'], '', $this->ensureLocale($lang));
148
        $this->language = $locale;
149
        setlocale(LC_ALL, $locale.'.utf8', $locale.'UTF-8', $locale);
150
    }
151
152
    /**
153
     * Get the package Installer
154
     * @return \luya\base\PackageInstaller
155
     */
156
    public function getPackageInstaller()
157
    {
158
        $file = Yii::getAlias('@vendor/luyadev/installer.php');
159
        
160
        $data = is_file($file) ? include $file : [];
161
         
162
        return new PackageInstaller($data);
163
    }
164
    
165
    /**
166
     * @inheritdoc
167
     */
168
    protected function bootstrap()
169
    {
170
        foreach ($this->getPackageInstaller()->getConfigs() as $config) {
171
            $this->bootstrap = array_merge($this->bootstrap, $config->bootstrap);
0 ignored issues
show
Bug introduced by
The property bootstrap does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
172
        }
173
        
174
        parent::bootstrap();
175
    }
176
    
177
    private $_webroot;
178
    
179
    /**
180
     * Read only property which is used in cli bootstrap process to set the @webroot alias
181
     *
182
     * ```php
183
     * Yii::setAlias('@webroot', $app->webroot);
184
     * ```
185
     */
186
    public function getWebroot()
187
    {
188
        if ($this->_webroot === null) {
189
            $this->_webroot = realpath(realpath($this->basePath) . DIRECTORY_SEPARATOR . $this->webrootDirectory);
0 ignored issues
show
Bug introduced by
The property basePath does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
190
        }
191
        
192
        return $this->_webroot;
193
    }
194
195
    /**
196
     * Add additional core components to the yii2 base core components.
197
     */
198
    public function luyaCoreComponents()
199
    {
200
        return array_merge(parent::coreComponents(), [
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (coreComponents() instead of luyaCoreComponents()). Are you sure this is correct? If so, you might want to change this to $this->coreComponents().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
201
            'mail' => ['class' => 'luya\components\Mail'],
202
            'formatter' => ['class' => 'luya\components\Formatter'],
203
        ]);
204
    }
205
206
    /**
207
     * Get an array with all modules which are an instance of the `luya\base\Module`.
208
     *
209
     * @return \luya\base\Module
210
     */
211 View Code Duplication
    public function getApplicationModules()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
212
    {
213
        $modules = [];
214
215
        foreach ($this->getModules() as $id => $obj) {
0 ignored issues
show
Bug introduced by
It seems like getModules() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
216
            if ($obj instanceof Module) {
217
                $modules[$id] = $obj;
218
            }
219
        }
220
221
        return $modules;
222
    }
223
224
    /**
225
     * Return a list with all registered frontend modules except 'luya' and 'cms'. This is needed in the module block.
226
     *
227
     * @return \luya\base\Module
228
     */
229 View Code Duplication
    public function getFrontendModules()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
230
    {
231
        $modules = [];
232
233
        foreach ($this->getModules() as $id => $obj) {
0 ignored issues
show
Bug introduced by
It seems like getModules() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
234
            if ($obj instanceof Module && !$obj instanceof AdminModuleInterface && !$obj instanceof CoreModuleInterface) {
235
                $modules[$id] = $obj;
236
            }
237
        }
238
239
        return $modules;
240
    }
241
    
242
    /**
243
     * Return all Admin Module Interface implementing modules.
244
     *
245
     * @return \luya\base\AdminModuleInterface
246
     */
247 View Code Duplication
    public function getAdminModules()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
248
    {
249
        $modules = [];
250
        
251
        foreach ($this->getModules() as $id => $obj) {
0 ignored issues
show
Bug introduced by
It seems like getModules() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
252
            if ($obj instanceof Module && $obj instanceof AdminModuleInterface) {
253
                $modules[$id] = $obj;
254
            }
255
        }
256
        
257
        return $modules;
258
    }
259
}
260