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()->all(); |
||
87 | if (empty($settings)) { |
||
88 | throw new \RuntimeException( |
||
89 | 'No settings found in settings table.' |
||
90 | ); |
||
91 | } |
||
92 | $compact = []; |
||
93 | foreach ($settings as $result) { |
||
94 | $compact[$result->get('name')] = $result->get('value'); |
||
95 | } |
||
96 | |||
97 | $this->_fillOptionalEmailAddresses($compact); |
||
98 | |||
99 | return $compact; |
||
100 | } |
||
101 | |||
102 | /** |
||
103 | * Loads settings from storage into Configuration `Saito.Settings` |
||
104 | * |
||
105 | * @param array $preset allows to overwrite loaded values |
||
106 | * @return array Settings |
||
107 | */ |
||
108 | public function load($preset = []) |
||
109 | { |
||
110 | Stopwatch::start('Settings->getSettings()'); |
||
111 | |||
112 | $cacheKey = 'Saito.appSettings.' . Configure::read('Saito.v'); |
||
113 | |||
114 | $settings = Cache::remember( |
||
115 | $cacheKey, |
||
116 | function () { |
||
117 | return $this->getSettings(); |
||
118 | } |
||
119 | ); |
||
120 | if ($preset) { |
||
0 ignored issues
–
show
|
|||
121 | $settings = $preset + $settings; |
||
122 | } |
||
123 | Configure::write('Saito.Settings', $settings); |
||
124 | Stopwatch::end('Settings->getSettings()'); |
||
125 | |||
126 | return $settings; |
||
127 | } |
||
128 | |||
129 | /** |
||
130 | * clear cache |
||
131 | * |
||
132 | * @return void |
||
133 | */ |
||
134 | public function clearCache() |
||
135 | { |
||
136 | parent::clearCache(); |
||
137 | Cache::delete('Saito.appSettings'); |
||
138 | } |
||
139 | |||
140 | /** |
||
141 | * {@inheritDoc} |
||
142 | */ |
||
143 | public function validateSubjectMaxLength($value, array $context) |
||
144 | { |
||
145 | if ($context['data']['name'] === 'subject_maxlength') { |
||
146 | return (int)$context['data']['value'] <= EntriesTable::SUBJECT_MAXLENGTH; |
||
147 | } |
||
148 | |||
149 | return true; |
||
150 | } |
||
151 | |||
152 | /** |
||
153 | * Defaults optional email addresses to main address |
||
154 | * |
||
155 | * @param array $settings settings |
||
156 | * @return void |
||
157 | */ |
||
158 | protected function _fillOptionalEmailAddresses(&$settings) |
||
159 | { |
||
160 | foreach ($this->_optionalEmailFields as $field) { |
||
161 | if (empty($settings[$field])) { |
||
162 | $settings[$field] = $settings['forum_email']; |
||
163 | } |
||
164 | } |
||
165 | } |
||
166 | } |
||
167 |
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.