Passed
Push — master ( a29a7e...12a432 )
by Mihail
08:06
created

Feedback::actionClose()   B

Complexity

Conditions 6
Paths 5

Size

Total Lines 34
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 34
rs 8.439
c 0
b 0
f 0
cc 6
eloc 16
nc 5
nop 2
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\Any;
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(): ?string
29
    {
30
        throw new NotFoundException('Nothing there...');
31
    }
32
33
    /**
34
     * Add new feedback message action
35
     * @return string
36
     * @throws ForbiddenException
37
     * @throws \Ffcms\Core\Exception\SyntaxException
38
     */
39
    public function actionCreate(): ?string
40
    {
41
        // get configs
42
        $configs = $this->getConfigs();
43
        if (!App::$User->isAuth() && !(bool)$configs['guestAdd']) {
44
            throw new ForbiddenException(__('Feedback available only for authorized users'));
45
        }
46
47
        // initialize model
48
        $model = new FormFeedbackAdd((int)$configs['useCaptcha'] === 1);
49
        if ($model->send()) {
50
            if ($model->validate()) {
51
                // if validation is passed save data to db and get row
52
                $record = $model->make();
53
                App::$Session->getFlashBag()->add('success', __('Your message was added successful'));
54
                $this->response->redirect('feedback/read/' . $record->id . '/' . $record->hash);
55
            } else {
56
                App::$Session->getFlashBag()->add('error', __('Message is not sended! Please, fix issues in form below'));
57
            }
58
        }
59
60
        // render output view
61
        return $this->view->render('create', [
62
            'model' => $model,
63
            'useCaptcha' => (int)$configs['useCaptcha'] === 1
64
        ]);
65
    }
66
67
68
    /**
69
     * Read feedback message and answers and work with add answer model
70
     * @param string $id
71
     * @param string $hash
72
     * @return string
73
     * @throws ForbiddenException
74
     * @throws \Ffcms\Core\Exception\SyntaxException
75
     */
76
    public function actionRead(string $id, string $hash): ?string
77
    {
78
        if (!Any::isInt($id) || Str::length($hash) < 16 || Str::length($hash) > 64) {
79
            throw new ForbiddenException(__('The feedback request is not founded'));
80
        }
81
82
        // get feedback post record from database
83
        $recordPost = FeedbackPost::where('id', $id)
84
            ->where('hash', $hash)
85
            ->first();
86
87
        if (!$recordPost) {
88
            throw new ForbiddenException(__('The feedback request is not founded'));
89
        }
90
91
        $userId = App::$User->isAuth() ? App::$User->identity()->getId() : 0;
92
        $model = null;
93
        // check if feedback post is not closed for answers
94
        if (!(bool)$recordPost->closed) {
0 ignored issues
show
Bug introduced by
The property closed does not seem to exist on Ffcms\Core\Arch\ActiveModel. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
95
            // init new answer add model
96
            $model = new FormAnswerAdd($recordPost, $userId);
97
            // if answer is sender lets try to make it model
98
            if ($model->send() && $model->validate()) {
99
                $model->make();
100
                App::$Session->getFlashBag()->add('success', __('Your answer was added'));
101
                $model->clearProperties();
102
            }
103
        }
104
105
        // render output view
106
        return $this->view->render('read', [
107
            'model' => $model,
108
            'post' => $recordPost,
109
            'answers' => $recordPost->getAnswers()->get() // get feedback answers
110
        ]);
111
    }
112
113
    /**
114
     * Close feedback request from new answers.
115
     * @param string $id
116
     * @param string $hash
117
     * @return string
118
     * @throws ForbiddenException
119
     * @throws \Ffcms\Core\Exception\SyntaxException
120
     */
121
    public function actionClose(string $id, string $hash): ?string
122
    {
123
        // get feedback post record from database
124
        $record = FeedbackPost::where('id', '=', $id)
125
            ->where('hash', '=', $hash)
126
            ->where('closed', '=', 0)
127
            ->first();
128
129
        // check does we found it
130
        if (!$record) {
131
            throw new ForbiddenException(__('The feedback request is not founded'));
132
        }
133
134
        // check if action is submited
135
        if ($this->request->request->get('closeRequest', false)) {
136
            // if created by authorized user
137
            if ((int)$record->user_id !== 0) {
0 ignored issues
show
Bug introduced by
The property user_id does not seem to exist on Ffcms\Core\Arch\ActiveModel. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
138
                $user = App::$User->identity();
139
                // button is pressed not by request creator
140
                if ($user === null || $user->getId() !== (int)$record->user_id) {
141
                    throw new ForbiddenException(__('This feedback request was created by another user'));
142
                }
143
            }
144
145
            // switch closed to 1 and make sql query
146
            $record->closed = 1;
0 ignored issues
show
Bug introduced by
The property closed does not seem to exist on Ffcms\Core\Arch\ActiveModel. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
147
            $record->save();
148
149
            // add notification and redirect
150
            App::$Session->getFlashBag()->add('warning', __('Feedback request now is closed!'));
151
            $this->response->redirect('feedback/read/' . $id . '/' . $hash);
152
        }
153
154
        return $this->view->render('close');
155
    }
156
157
    /**
158
     * List feedback requests messages from authorized user
159
     * @return string
160
     * @throws ForbiddenException
161
     * @throws \Ffcms\Core\Exception\SyntaxException
162
     */
163
    public function actionList(): ?string
164
    {
165
        // set current page and offset
166
        $page = (int)$this->request->query->get('page');
167
        $offset = $page * self::ITEM_PER_PAGE;
168
169
        // check if user is authorized or throw exception
170
        if (!App::$User->isAuth()) {
171
            throw new ForbiddenException(__('Feedback listing available only for authorized users'));
172
        }
173
174
        // get current user object
175
        $user = App::$User->identity();
176
177
        // initialize query with major condition
178
        $query = FeedbackPost::where('user_id', '=', $user->getId());
179
180
        // build pagination
181
        $pagination = new SimplePagination([
182
            'url' => ['feedback/list'],
183
            'page' => $page,
184
            'step' => self::ITEM_PER_PAGE,
185
            'total' => $query->count()
186
        ]);
187
188
        // build records object from prepared query using page offset
189
        $records = $query->orderBy('id', 'desc')->skip($offset)->take(self::ITEM_PER_PAGE)->get();
190
191
        // render viewer with parameters
192
        return $this->view->render('list', [
193
            'records' => $records,
194
            'pagination' => $pagination,
195
        ]);
196
    }
197
}
198