Completed
Push — master ( df46a8...ddc7c0 )
by Misbahul D
03:24
created

Module::init()   B

Complexity

Conditions 5
Paths 8

Size

Total Lines 22
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 10
Bugs 2 Features 3
Metric Value
c 10
b 2
f 3
dl 0
loc 22
rs 8.6737
cc 5
eloc 13
nc 8
nop 0
1
<?php
2
3
namespace mdm\admin;
4
5
use Yii;
6
use yii\helpers\Inflector;
7
use yii\helpers\ArrayHelper;
8
9
/**
10
 * GUI manager for RBAC.
11
 * 
12
 * Use [[\yii\base\Module::$controllerMap]] to change property of controller. 
13
 * To change listed menu, use property [[$menus]].
14
 * 
15
 * ```
16
 * 'layout' => 'left-menu', // default to null mean use application layout.
17
 * 'controllerMap' => [
18
 *     'assignment' => [
19
 *         'class' => 'mdm\admin\controllers\AssignmentController',
20
 *         'userClassName' => 'app\models\User',
21
 *         'idField' => 'id'
22
 *     ]
23
 * ],
24
 * 'menus' => [
25
 *     'assignment' => [
26
 *         'label' => 'Grand Access' // change label
27
 *     ],
28
 *     'route' => null, // disable menu
29
 * ],
30
 * ```
31
 * 
32
 * @property string $mainLayout Main layout using for module. Default to layout of parent module.
33
 * Its used when `layout` set to 'left-menu', 'right-menu' or 'top-menu'.
34
 * @property array $menus List avalible menu of module.
35
 * It generated by module items .
36
 * 
37
 * @author Misbahul D Munir <[email protected]>
38
 * @since 1.0
39
 */
40
class Module extends \yii\base\Module
41
{
42
    /**
43
     * @inheritdoc
44
     */
45
    public $defaultRoute = 'assignment';
46
    /**
47
     * @var array Nav bar items.
48
     */
49
    public $navbar;
50
    /**
51
     * @var string Main layout using for module. Default to layout of parent module.
52
     * Its used when `layout` set to 'left-menu', 'right-menu' or 'top-menu'.
53
     */
54
    public $mainLayout = '@mdm/admin/views/layouts/main.php';
55
    /**
56
     * @var array 
57
     * @see [[menus]]
58
     */
59
    private $_menus = [];
60
    /**
61
     * @var array 
62
     * @see [[menus]]
63
     */
64
    private $_coreItems = [
65
        'user' => 'Users',
66
        'assignment' => 'Assignments',
67
        'role' => 'Roles',
68
        'permission' => 'Permissions',
69
        'route' => 'Routes',
70
        'rule' => 'Rules',
71
        'menu' => 'Menus',
72
    ];
73
    /**
74
     * @var array 
75
     * @see [[items]]
76
     */
77
    private $_normalizeMenus;
78
79
    /**
80
     * @var string Default url for breadcrumb
81
     */
82
    public $defaultUrl;
83
84
    /**
85
     * @var string Default url label for breadcrumb
86
     */
87
    public $defaultUrlLabel;
88
89
    /**
90
     * @inheritdoc
91
     */
92
    public function init()
93
    {
94
        parent::init();
95
        if (!isset(Yii::$app->i18n->translations['rbac-admin'])) {
96
            Yii::$app->i18n->translations['rbac-admin'] = [
97
                'class' => 'yii\i18n\PhpMessageSource',
98
                'sourceLanguage' => 'en',
99
                'basePath' => '@mdm/admin/messages'
100
            ];
101
        }
102
        
103
        //user did not define the Navbar?
104
        if ($this->navbar === null && Yii::$app instanceof \yii\web\Application) {
105
            $this->navbar = [
106
                ['label' => Yii::t('rbac-admin', 'Help'), 'url' => ['default/index']],
107
                ['label' => Yii::t('rbac-admin', 'Application'), 'url' => Yii::$app->homeUrl]
108
            ];
109
        }
110
        if (class_exists('yii\jui\JuiAsset')) {
111
            Yii::$container->set('mdm\admin\AutocompleteAsset', 'yii\jui\JuiAsset');
112
        }
113
    }
114
115
    /**
116
     * Get avalible menu.
117
     * @return array
118
     */
119
    public function getMenus()
120
    {
121
        if ($this->_normalizeMenus === null) {
122
            $mid = '/' . $this->getUniqueId() . '/';
123
            // resolve core menus
124
            $this->_normalizeMenus = [];
125
126
            $config = components\Configs::instance();
127
            $conditions = [
128
                'user' => $config->db && $config->db->schema->getTableSchema($config->userTable),
129
                'assignment' => ($userClass = Yii::$app->getUser()->identityClass) && is_subclass_of($userClass, 'yii\db\BaseActiveRecord'),
0 ignored issues
show
Bug introduced by
The method getUser does only exist in yii\web\Application, but not in yii\console\Application.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
130
                'menu' => $config->db && $config->db->schema->getTableSchema($config->menuTable),
131
            ];
132
            foreach ($this->_coreItems as $id => $lable) {
133
                if (!isset($conditions[$id]) || $conditions[$id]) {
134
                    $this->_normalizeMenus[$id] = ['label' => Yii::t('rbac-admin', $lable), 'url' => [$mid . $id]];
135
                }
136
            }
137
            foreach (array_keys($this->controllerMap) as $id) {
138
                $this->_normalizeMenus[$id] = ['label' => Yii::t('rbac-admin', Inflector::humanize($id)), 'url' => [$mid . $id]];
139
            }
140
141
            // user configure menus
142
            foreach ($this->_menus as $id => $value) {
143
                if (empty($value)) {
144
                    unset($this->_normalizeMenus[$id]);
145
                    continue;
146
                }
147
                if (is_string($value)) {
148
                    $value = ['label' => $value];
149
                }
150
                $this->_normalizeMenus[$id] = isset($this->_normalizeMenus[$id]) ? array_merge($this->_normalizeMenus[$id], $value)
151
                        : $value;
152
                if (!isset($this->_normalizeMenus[$id]['url'])) {
153
                    $this->_normalizeMenus[$id]['url'] = [$mid . $id];
154
                }
155
            }
156
        }
157
        return $this->_normalizeMenus;
158
    }
159
160
    /**
161
     * Set or add avalible menu.
162
     * @param array $menus
163
     */
164
    public function setMenus($menus)
165
    {
166
        $this->_menus = array_merge($this->_menus, $menus);
167
        $this->_normalizeMenus = null;
0 ignored issues
show
Documentation Bug introduced by
It seems like null of type null is incompatible with the declared type array of property $_normalizeMenus.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
168
    }
169
170
    /**
171
     * @inheritdoc
172
     */
173
    public function beforeAction($action)
174
    {
175
        if (parent::beforeAction($action)) {
176
            /* @var $action \yii\base\Action */
177
            $view = $action->controller->getView();
178
179
            $view->params['breadcrumbs'][] = [
180
                'label' => ($this->defaultUrlLabel ?: Yii::t('rbac-admin', 'Admin')),
181
                'url' => ['/' . ($this->defaultUrl ?: $this->uniqueId)]
182
            ];
183
            return true;
184
        }
185
        return false;
186
    }
187
}
188