Passed
Push — master ( 02a4a5...734a7e )
by Mihail
05:36
created

Feedback   A

Complexity

Total Complexity 23

Size/Duplication

Total Lines 184
Duplicated Lines 5.43 %

Coupling/Cohesion

Components 1
Dependencies 14

Importance

Changes 3
Bugs 1 Features 0
Metric Value
c 3
b 1
f 0
dl 10
loc 184
rs 10
wmc 23
lcom 1
cbo 14

5 Methods

Rating   Name   Duplication   Size   Complexity  
A actionIndex() 0 4 1
D actionRead() 0 38 9
B actionCreate() 3 27 5
B actionClose() 7 35 6
B actionList() 0 34 2

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
3
namespace Apps\Controller\Front;
4
5
use Apps\ActiveRecord\FeedbackPost;
6
use Apps\Model\Front\Feedback\FormAnswerAdd;
7
use Apps\Model\Front\Feedback\FormFeedbackAdd;
8
use Extend\Core\Arch\FrontAppController as Controller;
9
use Ffcms\Core\App;
10
use Ffcms\Core\Exception\ForbiddenException;
11
use Ffcms\Core\Exception\NotFoundException;
12
use Ffcms\Core\Helper\HTML\SimplePagination;
13
use Ffcms\Core\Helper\Type\Obj;
14
use Ffcms\Core\Helper\Type\Str;
15
16
/**
17
 * Class Feedback. Create, read, update and delete app for user feedback
18
 * @package Apps\Controller\Front
19
 */
20
class Feedback extends Controller
21
{
22
    const ITEM_PER_PAGE = 10;
23
    
24
    /**
25
     * This action is not allowed there
26
     * @throws NotFoundException
27
     */
28
    public function actionIndex()
29
    {
30
        throw new NotFoundException('Nothing there...');
31
    }
32
33
    /**
34
     * Add new feedback message action
35
     * @return string
36
     * @throws \Ffcms\Core\Exception\NativeException
37
     * @throws ForbiddenException
38
     * @throws \Ffcms\Core\Exception\SyntaxException
39
     */
40
    public function actionCreate()
41
    {
42
        // get configs
43
        $configs = $this->getConfigs();
44 View Code Duplication
        if (!App::$User->isAuth() && (int)$configs['guestAdd'] !== 1) {
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...
45
            throw new ForbiddenException(__('Feedback available only for authorized users'));
46
        }
47
48
        // initialize model
49
        $model = new FormFeedbackAdd((int)$configs['useCaptcha'] === 1);
50
        if ($model->send()) {
51
            if ($model->validate()) {
52
                // if validation is passed save data to db and get row
53
                $record = $model->make();
54
                App::$Session->getFlashBag()->add('success', __('Your message was added successful'));
55
                $this->response->redirect('feedback/read/' . $record->id . '/' . $record->hash);
0 ignored issues
show
Bug introduced by
The method redirect cannot be called on $this->response (of type string).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
56
            } else {
57
                App::$Session->getFlashBag()->add('error', __('Message is not sended! Please, fix issues in form below'));
58
            }
59
        }
60
61
        // render output view
62
        return $this->view->render('create', [
0 ignored issues
show
Documentation introduced by
The property view does not exist on object<Apps\Controller\Front\Feedback>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
63
            'model' => $model->filter(),
64
            'useCaptcha' => (int)$configs['useCaptcha'] === 1
65
        ]);
66
    }
67
68
69
    /**
70
     * Read feedback message and answers and work with add answer model
71
     * @param int $id
72
     * @param string $hash
73
     * @return string
74
     * @throws \Ffcms\Core\Exception\NativeException
75
     * @throws ForbiddenException
76
     * @throws \Ffcms\Core\Exception\SyntaxException
77
     */
78
    public function actionRead($id, $hash)
79
    {
80
        if (!Obj::isLikeInt($id) || Str::length($hash) < 16 || Str::length($hash) > 64) {
81
            throw new ForbiddenException(__('The feedback request is not founded'));
82
        }
83
84
        // get feedback post record from database
85
        $recordPost = FeedbackPost::where('id', '=', $id)
86
            ->where('hash', '=', $hash)
87
            ->first();
88
89
        if ($recordPost === null) {
90
            throw new ForbiddenException(__('The feedback request is not founded'));
91
        }
92
93
        $userId = App::$User->isAuth() ? App::$User->identity()->getId() : 0;
94
        $model = null;
95
        // check if feedback post is not closed for answers
96
        if ((int)$recordPost->closed === 0) {
97
            // init new answer add model
98
            $model = new FormAnswerAdd($recordPost, $userId);
99
            // if answer is sender lets try to make it model
100
            if ($model->send() && $model->validate()) {
101
                $model->make();
102
                App::$Session->getFlashBag()->add('success', __('Your answer was added'));
103
                $model->clearProperties();
104
            }
105
            // secure display html data
106
            $model = $model->filter();
107
        }
108
109
        // render output view
110
        return $this->view->render('read', [
0 ignored issues
show
Documentation introduced by
The property view does not exist on object<Apps\Controller\Front\Feedback>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
111
            'model' => $model,
112
            'post' => $recordPost,
113
            'answers' => $recordPost->getAnswers()->get() // get feedback answers
114
        ]);
115
    }
116
117
    /**
118
     * @param int $id
119
     * @param string $hash
120
     * @return string
121
     * @throws \Ffcms\Core\Exception\NativeException
122
     * @throws ForbiddenException
123
     * @throws \Ffcms\Core\Exception\SyntaxException
124
     */
125
    public function actionClose($id, $hash)
126
    {
127
        // get feedback post record from database
128
        $record = FeedbackPost::where('id', '=', $id)
129
            ->where('hash', '=', $hash)
130
            ->where('closed', '=', 0)
131
            ->first();
132
133
        // check does we found it
134
        if ($record === null) {
135
            throw new ForbiddenException(__('The feedback request is not founded'));
136
        }
137
138
        // check if action is submited
139
        if ($this->request->request->get('closeRequest', false)) {
0 ignored issues
show
Documentation introduced by
The property request does not exist on object<Apps\Controller\Front\Feedback>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
140
            // if created by authorized user
141 View Code Duplication
            if ((int)$record->user_id !== 0) {
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...
142
                $user = App::$User->identity();
143
                // button is pressed not by request creator
144
                if ($user === null || $user->getId() !== (int)$record->user_id) {
145
                    throw new ForbiddenException(__('This feedback request was created by another user'));
146
                }
147
            }
148
149
            // switch closed to 1 and make sql query
150
            $record->closed = 1;
151
            $record->save();
152
153
            // add notification and redirect
154
            App::$Session->getFlashBag()->add('warning', __('Feedback request now is closed!'));
155
            $this->response->redirect('feedback/read/' . $id . '/' . $hash);
0 ignored issues
show
Bug introduced by
The method redirect cannot be called on $this->response (of type string).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
156
        }
157
158
        return $this->view->render('close');
0 ignored issues
show
Documentation introduced by
The property view does not exist on object<Apps\Controller\Front\Feedback>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
159
    }
160
161
    /**
162
     * List feedback requests messages from authorized user
163
     * @return string
164
     * @throws \Ffcms\Core\Exception\NativeException
165
     * @throws ForbiddenException
166
     * @throws \Ffcms\Core\Exception\SyntaxException
167
     */
168
    public function actionList()
169
    {
170
        // set current page and offset
171
        $page = (int)$this->request->query->get('page');
0 ignored issues
show
Documentation introduced by
The property request does not exist on object<Apps\Controller\Front\Feedback>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
172
        $offset = $page * self::ITEM_PER_PAGE;
173
174
        // check if user is authorized or throw exception
175
        if (!App::$User->isAuth()) {
176
            throw new ForbiddenException(__('Feedback listing available only for authorized users'));
177
        }
178
179
        // get current user object
180
        $user = App::$User->identity();
181
182
        // initialize query with major condition
183
        $query = FeedbackPost::where('user_id', '=', $user->getId());
184
185
        // build pagination
186
        $pagination = new SimplePagination([
187
            'url' => ['feedback/list'],
188
            'page' => $page,
189
            'step' => self::ITEM_PER_PAGE,
190
            'total' => $query->count()
191
        ]);
192
193
        // build records object from prepared query using page offset
194
        $records = $query->orderBy('id', 'desc')->skip($offset)->take(self::ITEM_PER_PAGE)->get();
195
196
        // render viewer with parameters
197
        return $this->view->render('list', [
0 ignored issues
show
Documentation introduced by
The property view does not exist on object<Apps\Controller\Front\Feedback>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
198
            'records' => $records,
199
            'pagination' => $pagination,
200
        ]);
201
    }
202
203
}