Completed
Push — develop ( 2974ab...dcee28 )
by Schlaefer
02:44
created

SettingsTable::validationDefault()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 1
dl 0
loc 30
rs 9.44
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * Saito - The Threaded Web Forum
7
 *
8
 * @copyright Copyright (c) the Saito Project Developers
9
 * @link https://github.com/Schlaefer/Saito
10
 * @license http://opensource.org/licenses/MIT
11
 */
12
13
namespace App\Model\Table;
14
15
use App\Lib\Model\Table\AppSettingTable;
16
use App\Model\Table\EntriesTable;
17
use Cake\Cache\Cache;
18
use Cake\Core\Configure;
19
use Cake\Validation\Validator;
20
use \Stopwatch\Lib\Stopwatch;
21
22
class SettingsTable extends AppSettingTable
23
{
24
    protected $_optionalEmailFields = [
25
        'email_contact',
26
        'email_register',
27
        'email_system'
28
    ];
29
30
    /**
31
     * {@inheritDoc}
32
     */
33
    public function initialize(array $config)
34
    {
35
        $this->setPrimaryKey('name');
36
    }
37
38
    /**
39
     * {@inheritDoc}
40
     */
41
    public function validationDefault(Validator $validator)
42
    {
43
        $validator
44
            ->notEmptyString('name')
45
            ->add(
46
                'name',
47
                [
48
                    'maxLength' => [
49
                        'rule' => ['maxLength', 255],
50
                    ],
51
                ]
52
            );
53
54
        $validator
55
            ->allowEmptyString('value')
56
            ->add(
57
                'value',
58
                [
59
                    'maxLength' => [
60
                        'rule' => ['maxLength', 255],
61
                    ],
62
                    'subjectMaxLength' => [
63
                        'rule' => [$this, 'validateSubjectMaxLength'],
64
                        'message' => __('vld.settings.subjectMaxLength', EntriesTable::SUBJECT_MAXLENGTH)
65
                    ],
66
                ]
67
            );
68
69
        return $validator;
70
    }
71
72
    /* @td getSettings vs Load why to functions? */
73
74
    /**
75
     * Reads settings from DB and returns them in a compact array
76
     *
77
     * Note that this is the stored config in the DB. It may differ from the
78
     * current config used by the app in Config::read('Saito.Settings'), e.g.
79
     * when modified with a load-preset.
80
     *
81
     * @throws \RuntimeException
82
     * @return array Settings
83
     */
84
    public function getSettings()
85
    {
86
        $settings = $this->find();
87
        if (empty($settings)) {
88
            throw new \RuntimeException(
89
                'No settings found in settings table.'
90
            );
91
        }
92
        $settings = $this->_compactKeyValue($settings);
0 ignored issues
show
Documentation introduced by
$settings is of type object<Cake\ORM\Query>, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
93
94
        $this->_fillOptionalEmailAddresses($settings);
95
96
        return $settings;
97
    }
98
99
    /**
100
     * Loads settings from storage into Configuration `Saito.Settings`
101
     *
102
     * @param array $preset allows to overwrite loaded values
103
     * @return array Settings
104
     */
105
    public function load($preset = [])
106
    {
107
        Stopwatch::start('Settings->getSettings()');
108
109
        $cacheKey = 'Saito.appSettings.' . Configure::read('Saito.v');
110
111
        $settings = Cache::remember(
112
            $cacheKey,
113
            function () {
114
                return $this->getSettings();
115
            }
116
        );
117
        if ($preset) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $preset of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
118
            $settings = $preset + $settings;
119
        }
120
        Configure::write('Saito.Settings', $settings);
121
        Stopwatch::end('Settings->getSettings()');
122
123
        return $settings;
124
    }
125
126
    /**
127
     * clear cache
128
     *
129
     * @return void
130
     */
131
    public function clearCache()
132
    {
133
        parent::clearCache();
134
        Cache::delete('Saito.appSettings');
135
    }
136
137
    /**
138
     * {@inheritDoc}
139
     */
140
    public function validateSubjectMaxLength($value, array $context)
141
    {
142
        if ($context['data']['name'] === 'subject_maxlength') {
143
            return (int)$context['data']['value'] <= EntriesTable::SUBJECT_MAXLENGTH;
144
        }
145
146
        return true;
147
    }
148
149
    /**
150
     * Returns a key-value array
151
     *
152
     * Fast version of Set::combine($results, '{n}.Setting.name',
153
     * '{n}.Setting.value');
154
     *
155
     * @param array $results results
156
     * @return array
157
     */
158
    protected function _compactKeyValue($results)
159
    {
160
        $settings = [];
161
        foreach ($results as $result) {
162
            $settings[$result->get('name')] = $result->get('value');
163
        }
164
165
        return $settings;
166
    }
167
168
    /**
169
     * Defaults optional email addresses to main address
170
     *
171
     * @param array $settings settings
172
     * @return void
173
     */
174
    protected function _fillOptionalEmailAddresses(&$settings)
175
    {
176
        foreach ($this->_optionalEmailFields as $field) {
177
            if (empty($settings[$field])) {
178
                $settings[$field] = $settings['forum_email'];
179
            }
180
        }
181
    }
182
}
183