FlashMessageFilter   A
last analyzed

Complexity

Total Complexity 17

Size/Duplication

Total Lines 151
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 17
lcom 1
cbo 6
dl 0
loc 151
ccs 0
cts 70
cp 0
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A afterAction() 0 9 3
A resultMatch() 0 4 2
A setMessage() 0 31 4
A findMessage() 0 9 2
A findMessageFromAction() 0 15 3
A resolveMessageStatusCode() 0 14 3
1
<?php
2
3
/**
4
 * @copyright  Copyright (c) Flipbox Digital Limited
5
 * @license    https://github.com/flipboxfactory/craft-ember/blob/master/LICENSE
6
 * @link       https://github.com/flipboxfactory/craft-ember/
7
 */
8
9
namespace flipbox\craft\ember\filters;
10
11
use Craft;
12
use yii\base\Action;
13
use yii\base\ActionFilter;
14
use yii\helpers\Json;
15
use yii\web\Controller;
16
17
/**
18
 * @author Flipbox Factory <[email protected]>
19
 * @since 2.0.0
20
 *
21
 * @property Controller $sender
22
 */
23
class FlashMessageFilter extends ActionFilter
24
{
25
    use ActionTrait,
26
        FormatTrait;
27
28
    /**
29
     * Allow redirection of a null result
30
     * @var bool
31
     */
32
    public $allowNull = false;
33
34
    /**
35
     * @var array this property defines the message mapping for each action.
36
     * For each action that should only support limited set of messages
37
     * you add a message with the action id as array key and an array of
38
     * allowed messages using an (optional) status code as a key and the message
39
     * as the value (e.g. '200' => 'Success', '401' => 'Fail').
40
     * If an action is not defined a message will not be presented.
41
     *
42
     * You can use `'*'` to stand for all actions. When an action is explicitly
43
     * specified, it takes precedence over the specification given by `'*'`.
44
     *
45
     * For example,
46
     *
47
     * ```php
48
     * [
49
     *   'create' => [201 => 'Created successfully.', 401 => 'Failed to create.'],
50
     *   'update' => [200 => 'Updated successfully.', 401 => 'Failed to update.'],
51
     *   '*' => ['*' => 'General message'],
52
     * ]
53
     * ```
54
     */
55
    public $actions = [];
56
57
    /**
58
     * @var string
59
     */
60
    public $message;
61
62
    /**
63
     * @param Action $action
64
     * @param mixed $result
65
     * @return mixed
66
     */
67
    public function afterAction($action, $result)
68
    {
69
        if ($this->formatMatch($action->id) &&
70
            $this->resultMatch($result)
71
        ) {
72
            $this->setMessage($action);
73
        }
74
        return parent::afterAction($action, $result);
75
    }
76
77
    /**
78
     * @param $result
79
     * @return bool
80
     */
81
    protected function resultMatch($result): bool
82
    {
83
        return $result !== null || ($this->allowNull === true);
84
    }
85
86
    /**
87
     * @param Action $action
88
     */
89
    protected function setMessage(Action $action)
90
    {
91
        try {
92
            if (!$message = $this->findMessage($action->id)) {
93
                return;
94
            }
95
96
            if (Craft::$app->getResponse()->getIsSuccessful()) {
97
                Craft::$app->getSession()->setNotice($message);
98
                return;
99
            }
100
101
            Craft::$app->getSession()->setError($message);
102
        } catch (\Exception $e) {
103
            Craft::warning(
104
                sprintf(
105
                    "Exception caught while trying to set flash message. Exception: [%s].",
106
                    (string)Json::encode([
107
                        'Trace' => $e->getTraceAsString(),
108
                        'File' => $e->getFile(),
109
                        'Line' => $e->getLine(),
110
                        'Code' => $e->getCode(),
111
                        'Message' => $e->getMessage()
112
                    ])
113
                ),
114
                __METHOD__
115
            );
116
        }
117
118
        return;
119
    }
120
121
    /**
122
     * @param string $action
123
     * @return null|string
124
     */
125
    protected function findMessage(string $action)
126
    {
127
        // Look for definitions
128
        if ($message = $this->findMessageFromAction($action)) {
129
            return $message;
130
        }
131
132
        return $this->message;
133
    }
134
135
    /**
136
     * @param string $action
137
     * @return null|string
138
     */
139
    protected function findMessageFromAction(string $action)
140
    {
141
        // Default format
142
        $messages = $this->findAction($action);
143
144
        if (is_array($messages)) {
145
            return $this->resolveMessageStatusCode($messages);
146
        }
147
148
        if (!empty($messages)) {
149
            return (string)$messages;
150
        }
151
152
        return null;
153
    }
154
155
    /**
156
     * @param array $messages
157
     * @return string|null
158
     */
159
    protected function resolveMessageStatusCode(array $messages)
160
    {
161
        $statusCode = Craft::$app->getResponse()->getStatusCode();
162
163
        if (isset($messages[$statusCode])) {
164
            return (string)$messages[$statusCode];
165
        };
166
167
        if (isset($messages['*'])) {
168
            return (string)$messages['*'];
169
        }
170
171
        return null;
172
    }
173
}
174