Completed
Push — master ( b31119...230834 )
by Stefano
23s queued 11s
created

TrashController::delete()   A

Complexity

Conditions 6
Paths 12

Size

Total Lines 31
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 19
nc 12
nop 0
dl 0
loc 31
rs 9.0111
c 0
b 0
f 0
1
<?php
2
/**
3
 * BEdita, API-first content management framework
4
 * Copyright 2018 ChannelWeb Srl, Chialab Srl
5
 *
6
 * This file is part of BEdita: you can redistribute it and/or modify
7
 * it under the terms of the GNU Lesser General Public License as published
8
 * by the Free Software Foundation, either version 3 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * See LICENSE.LGPL or <http://gnu.org/licenses/lgpl-3.0.html> for more details.
12
 */
13
namespace App\Controller;
14
15
use BEdita\SDK\BEditaClientException;
16
use Cake\Event\Event;
17
use Cake\Http\Response;
18
use Cake\Utility\Hash;
19
use Psr\Log\LogLevel;
20
21
/**
22
 * Trash can controller: list, restore & remove permanently objects
23
 *
24
 * @property \App\Controller\Component\PropertiesComponent $Properties
25
 */
26
class TrashController extends AppController
27
{
28
29
    /**
30
     * {@inheritDoc}
31
     * @codeCoverageIgnore
32
     */
33
    public function initialize() : void
34
    {
35
        parent::initialize();
36
37
        $this->loadComponent('Properties');
38
39
        $this->Modules->setConfig('currentModuleName', 'trash');
40
    }
41
42
    /**
43
     * {@inheritDoc}
44
     *
45
     * @codeCoverageIgnore
46
     */
47
    public function beforeRender(Event $event) : ?Response
48
    {
49
        $this->set('moduleLink', ['_name' => 'trash:list']);
50
51
        return parent::beforeRender($event);
0 ignored issues
show
Bug introduced by
Are you sure the usage of parent::beforeRender($event) targeting App\Controller\AppController::beforeRender() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
52
    }
53
54
    /**
55
     * Display deleted resources list.
56
     *
57
     * @return \Cake\Http\Response|null
58
     * @codeCoverageIgnore
59
     */
60
    public function index() : ?Response
61
    {
62
        $this->request->allowMethod(['get']);
63
64
        try {
65
            $response = $this->apiClient->getObjects('trash', $this->request->getQueryParams());
66
        } catch (BEditaClientException $e) {
67
            // Error! Back to dashboard.
68
            $this->log($e, LogLevel::ERROR);
69
            $this->Flash->error($e->getMessage(), ['params' => $e]);
70
71
            return $this->redirect(['_name' => 'dashboard']);
72
        }
73
74
        $this->set('objects', (array)$response['data']);
75
        $this->set('meta', (array)$response['meta']);
76
        $this->set('links', (array)$response['links']);
77
        $this->set('types', ['right' => $this->Modules->objectTypes(false)]);
78
79
        $this->set('properties', $this->Properties->indexList('trash'));
80
81
        return null;
82
    }
83
84
    /**
85
     * View single deleted resource.
86
     *
87
     * @param mixed $id Resource ID.
88
     * @return \Cake\Http\Response|null
89
     * @codeCoverageIgnore
90
     */
91
    public function view($id) : ?Response
92
    {
93
        $this->request->allowMethod(['get']);
94
95
        try {
96
            $response = $this->apiClient->getObject($id, 'trash');
97
        } catch (BEditaClientException $e) {
98
            // Error! Back to index.
99
            $this->log($e, LogLevel::ERROR);
100
            $this->Flash->error($e->getMessage(), ['params' => $e]);
101
102
            return $this->redirect(['_name' => 'trash:list']);
103
        }
104
105
        $object = $response['data'];
106
        $schema = $this->Schema->getSchema($object['type']);
107
108
        $this->set(compact('object', 'schema'));
109
        $this->set('properties', $this->Properties->viewGroups($object, 'trash'));
110
111
        return null;
112
    }
113
114
    /**
115
     * Restore resource.
116
     *
117
     * @return \Cake\Http\Response|null
118
     */
119
    public function restore() : ?Response
120
    {
121
        $this->request->allowMethod(['post']);
122
        $ids = [];
123
        if (!empty($this->request->getData('ids'))) {
124
            $ids = $this->request->getData('ids');
125
            if (is_string($ids)) {
126
                $ids = explode(',', $this->request->getData('ids'));
0 ignored issues
show
Bug introduced by
It seems like $this->request->getData('ids') can also be of type array; however, parameter $string of explode() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

126
                $ids = explode(',', /** @scrutinizer ignore-type */ $this->request->getData('ids'));
Loading history...
127
            }
128
        } else {
129
            $ids = [$this->request->getData('id')];
130
        }
131
        foreach ($ids as $id) {
132
            try {
133
                $this->apiClient->restoreObject($id, 'objects');
134
            } catch (BEditaClientException $e) {
135
                // Error! Back to object view.
136
                $this->log($e, LogLevel::ERROR);
137
                $this->Flash->error($e->getMessage(), ['params' => $e]);
138
139
                if (!empty($this->request->getData('ids'))) {
140
                    return $this->redirect(['_name' => 'trash:list'] + $this->listQuery());
141
                }
142
143
                return $this->redirect(['_name' => 'trash:view', 'id' => $id]);
144
            }
145
        }
146
147
        return $this->redirect(['_name' => 'trash:list'] + $this->listQuery());
148
    }
149
150
    /**
151
     * Permanently delete resource.
152
     *
153
     * @return \Cake\Http\Response|null
154
     */
155
    public function delete() : ?Response
156
    {
157
        $this->request->allowMethod(['post']);
158
        $ids = [];
159
        if (!empty($this->request->getData('ids'))) {
160
            $ids = $this->request->getData('ids');
161
            if (is_string($ids)) {
162
                $ids = explode(',', $this->request->getData('ids'));
0 ignored issues
show
Bug introduced by
It seems like $this->request->getData('ids') can also be of type array; however, parameter $string of explode() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

162
                $ids = explode(',', /** @scrutinizer ignore-type */ $this->request->getData('ids'));
Loading history...
163
            }
164
        } else {
165
            $ids = [$this->request->getData('id')];
166
        }
167
        foreach ($ids as $id) {
168
            try {
169
                $this->apiClient->remove($id);
170
            } catch (BEditaClientException $e) {
171
                // Error! Back to object view.
172
                $this->log($e, LogLevel::ERROR);
173
                $this->Flash->error($e->getMessage(), ['params' => $e]);
174
175
                if (!empty($this->request->getData('ids'))) {
176
                    return $this->redirect(['_name' => 'trash:list'] + $this->listQuery());
177
                }
178
179
                return $this->redirect(['_name' => 'trash:view', 'id' => $id]);
180
            }
181
        }
182
183
        $this->Flash->success(__('Object deleted from trash'));
184
185
        return $this->redirect(['_name' => 'trash:list'] + $this->listQuery());
186
    }
187
188
    /**
189
     * Return query filter array from request to be used in redirects
190
     *
191
     * @return array
192
     */
193
    protected function listQuery() : array
194
    {
195
        $query = $this->request->getData('query');
196
        if (empty($query)) {
197
            return [];
198
        }
199
        $query = htmlspecialchars_decode($query);
0 ignored issues
show
Bug introduced by
It seems like $query can also be of type array; however, parameter $string of htmlspecialchars_decode() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

199
        $query = htmlspecialchars_decode(/** @scrutinizer ignore-type */ $query);
Loading history...
200
201
        return (array)unserialize($query);
202
    }
203
204
    /**
205
     * Permanently delete multiple data.
206
     * If filter type is active, empty trash by type
207
     *
208
     * @return \Cake\Http\Response|null
209
     */
210
    public function empty() : ?Response
211
    {
212
        $this->request->allowMethod(['post']);
213
214
        $query = array_filter(array_intersect_key($this->listQuery(), ['filter' => '']));
215
        // cycle over trash results
216
        $response = $this->apiClient->getObjects('trash', $query);
217
        $counter = 0;
218
        while (Hash::get($response, 'meta.pagination.count', 0) > 0) {
219
            foreach ($response['data'] as $index => $data) {
220
                try {
221
                    $this->apiClient->remove($data['id'], $query);
0 ignored issues
show
Unused Code introduced by
The call to BEdita\SDK\BEditaClient::remove() has too many arguments starting with $query. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

221
                    $this->apiClient->/** @scrutinizer ignore-call */ 
222
                                      remove($data['id'], $query);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
222
                    $counter++;
223
                } catch (BEditaClientException $e) {
224
                    // Error! Back to trash index.
225
                    $this->log($e, LogLevel::ERROR);
226
                    $this->Flash->error($e->getMessage(), ['params' => $e]);
227
228
                    return $this->redirect(['_name' => 'trash:list'] + $this->listQuery());
229
                }
230
            }
231
            $response = $this->apiClient->getObjects('trash', $query);
232
        }
233
        $this->Flash->success(__(sprintf('%d objects deleted from trash', $counter)));
234
235
        return $this->redirect(['_name' => 'trash:list'] + $this->listQuery());
236
    }
237
}
238