Test Setup Failed
Push — master ( a4f66d...29baaf )
by Mihail
41:06
created

AdminController::getConfigs()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
rs 10
cc 2
eloc 2
nc 2
nop 0
1
<?php
2
3
namespace Extend\Core\Arch;
4
5
6
use Ffcms\Core\App;
7
use Apps\ActiveRecord\App as AppRecord;
8
use Ffcms\Core\Exception\ForbiddenException;
9
use Ffcms\Core\Helper\Serialize;
10
use Ffcms\Core\Helper\Type\Obj;
11
use Ffcms\Core\Helper\Type\Str;
12
13
/**
14
 * Class AdminController - class to extend classic admin controllers by extension type.
15
 * Used: access security control, application listing, widget listing, current extension data
16
 * @package Extend\Core\Arch
17
 */
18
class AdminController extends Controller
19
{
20
    public $type = 'app';
21
22
    /** @var array $applications */
23
    protected $applications;
24
    /** @var array $widgets */
25
    protected $widgets;
26
27
    /** @var AppRecord $application */
28
    protected $application;
29
    /** @var AppRecord $widget */
30
    protected $widget;
31
32
    public function __construct($checkVersion = true)
33
    {
34
        parent::__construct();
35
        $this->buildExtensions();
36
        $this->checkAccess();
37
38
        // if version is not necessary to check - continue
39
        if ($checkVersion === false) {
40
            return;
41
        } elseif ($this->application === null) {
42
            // check if appdata is loaded from db
43
            throw new ForbiddenException('This application is not installed!');
44
        }
45
46
        // check app version matching
47
        if (!method_exists($this->application, 'checkVersion') || $this->application->checkVersion() !== true) {
48
            App::$Session->getFlashBag()->add(
49
                'error',
50
                __('Attention! Version of this application scripts is no match to database version. Please, make update!')
51
            );
52
        }
53
    }
54
55
    /**
56
     * Build apps/widgets table in local property
57
     */
58
    private function buildExtensions()
59
    {
60
        $controller = Str::lastIn(get_class($this), '\\', true);
61
        foreach ($this->table as $item) {
0 ignored issues
show
Bug introduced by
The expression $this->table of type object|array|string|boolean is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
62
            if ($item->type === 'app') {
63
                $this->applications[] = $item;
64
                if ($this->type === 'app' && $item->sys_name === $controller) {
65
                    $this->application = $item;
66
                }
67
            } elseif ($item->type === 'widget') {
68
                $this->widgets[] = $item;
69
                if ($this->type === 'widget' && $item->sys_name === $controller) {
70
                    $this->widget = $item;
71
                }
72
            }
73
        }
74
    }
75
76
    /**
77
     * Check if current user can access to admin controllers
78
     */
79
    private function checkAccess()
80
    {
81
        $user = App::$User->identity();
82
        // user is not authed ?
83 View Code Duplication
        if ($user === null || !App::$User->isAuth()) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
84
            $redirectUrl = App::$Alias->scriptUrl . '/user/login';
85
            App::$Response->redirect($redirectUrl, true);
86
            exit();
0 ignored issues
show
Coding Style Compatibility introduced by
The method checkAccess() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
87
        }
88
89
        $permission = env_name . '/' . App::$Request->getController() . '/' . App::$Request->getAction();
90
91
        // doesn't have permission? get the f*ck out
92 View Code Duplication
        if (!$user->getRole()->can($permission)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
93
            App::$Session->invalidate();
94
95
            $redirectUrl = App::$Alias->scriptUrl . '/user/login';
96
            App::$Response->redirect($redirectUrl, true);
97
            exit();
0 ignored issues
show
Coding Style Compatibility introduced by
The method checkAccess() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
98
        }
99
    }
100
101
    /**
102
     * Get all extensions as table active record
103
     * @return \Illuminate\Database\Eloquent\Collection|static[]
104
     */
105
    public function getTable()
106
    {
107
        return $this->table;
108
    }
109
110
    /**
111
     * Get all extensions as active records by current type
112
     * @param string|null $type
113
     * @return mixed
114
     */
115
    public function getTypeTable($type = null)
116
    {
117
        if ($type === null) {
118
            $type = $this->type;
119
        }
120
        return $type === 'widget' ? $this->widgets : $this->applications;
121
    }
122
123
    /**
124
     * Get current extension active record
125
     * @param string|null $type
126
     * @return mixed
127
     */
128
    public function getTypeItem($type = null)
129
    {
130
        if ($type === null) {
131
            $type = $this->type;
132
        }
133
        return $type === 'widget' ? $this->widget : $this->application;
134
    }
135
136
    /**
137
     * Get current extension configs
138
     * @return array
139
     */
140
    public function getConfigs()
141
    {
142
        return $this->type === 'widget' ? (array)Serialize::decode($this->widget->config) : (array)Serialize::decode($this->application->configs);
143
    }
144
145
    /**
146
     * Save extension configs
147
     * @param array $configs
148
     * @return bool
149
     */
150
    public function setConfigs(array $configs = null)
151
    {
152
        if ($configs === null || !Obj::isArray($configs) || count($configs) < 1) {
153
            return false;
154
        }
155
156
        // get extension is based on it type
157
        $id = 0;
158
        if ($this->type === 'app') {
159
            $id = $this->application->id;
160
        } elseif ($this->type === 'widget') {
161
            $id = $this->widget->id;
162
        }
163
164
        // serialize configs
165
        $serialized = Serialize::encode($configs);
166
        // get active record relation for this id
167
        $obj = \Apps\ActiveRecord\App::find($id);
168
169
        if ($obj === null) {
170
            return false;
171
        }
172
173
        // save data in db
174
        $obj->configs = $serialized;
175
        $obj->save();
176
        return true;
177
    }
178
179
}