Completed
Push — 2.0 ( 7d648f...ad55f4 )
by Christopher
02:04
created

TermField::beforeSave()   C

Complexity

Conditions 9
Paths 7

Size

Total Lines 62
Code Lines 40

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 9
eloc 40
nc 7
nop 2
dl 0
loc 62
rs 6.6867
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * Licensed under The GPL-3.0 License
4
 * For full copyright and license information, please see the LICENSE.txt
5
 * Redistributions of files must retain the above copyright notice.
6
 *
7
 * @since    2.0.0
8
 * @author   Christopher Castro <[email protected]>
9
 * @link     http://www.quickappscms.org
10
 * @license  http://opensource.org/licenses/gpl-3.0.html GPL-3.0 License
11
 */
12
namespace Taxonomy\Field;
13
14
use Cake\Cache\Cache;
15
use Cake\ORM\TableRegistry;
16
use Cake\Utility\Inflector;
17
use Cake\Validation\Validator;
18
use CMS\View\View;
19
use Field\Handler;
20
use Field\Model\Entity\Field;
21
use Field\Model\Entity\FieldInstance;
22
23
/**
24
 * Term Field Handler.
25
 *
26
 * This field allows to store terms information. Used to classify contents.
27
 */
28
class TermField extends Handler
29
{
30
31
    /**
32
     * {@inheritDoc}
33
     */
34
    public function info()
35
    {
36
        return [
37
            'type' => 'text',
38
            'name' => __d('taxonomy', 'Term Reference'),
39
            'description' => __d('taxonomy', 'Defines terms list based on taxonomy vocabularies.'),
40
            'hidden' => false,
41
        ];
42
    }
43
44
    /**
45
     * {@inheritDoc}
46
     */
47
    public function render(Field $field, View $view)
48
    {
49
        return $view->element('Taxonomy.taxonomy_field_display', compact('field'));
50
    }
51
52
    /**
53
     * {@inheritDoc}
54
     */
55
    public function edit(Field $field, View $view)
56
    {
57
        $terms = [];
58
        if ($field->metadata->settings['vocabulary']) {
59
            $TermsTable = TableRegistry::get('Taxonomy.Terms');
60
            $TermsTable->removeBehavior('Tree');
61
            $TermsTable->addBehavior('Tree', [
62
                'scope' => [
63
                    'vocabulary_id' => $field->metadata->settings['vocabulary']
64
                ]
65
            ]);
66
            $terms = $TermsTable->find('treeList', ['spacer' => '&nbsp;&nbsp;']);
67
        }
68
69
        return $view->element('Taxonomy.taxonomy_field_edit', compact('field', 'terms'));
70
    }
71
72
    /**
73
     * {@inheritDoc}
74
     */
75
    public function validate(Field $field, Validator $validator)
76
    {
77
        if ($field->metadata->required) {
78
            $validator->notEmpty($field->name, __d('taxonomy', 'Field required.'), true);
79
        } else {
80
            $validator->allowEmpty($field->name, true);
81
        }
82
83
        if (intval($field->metadata->settings['max_values']) > 0) {
84
            if (!empty($field->metadata->settings['error_message'])) {
85
                $limitErrorMessage = $field->metadata->settings['error_message'];
86
            } else {
87
                $limitErrorMessage = __d('taxonomy', 'You can select {0,number} values as maximum.', $field->metadata->settings['max_values']);
88
            }
89
90
            $validator
91
                ->add($field->name, 'validateLimit', [
92
                    'rule' => function ($value, $context) use ($field) {
93
                        if (!is_array($value)) {
94
                            $value = explode(',', (string)$value);
95
                        }
96
97
                        return count($value) <= $field->metadata->settings['max_values'];
98
                    },
99
                    'message' => $limitErrorMessage,
100
                ]);
101
        }
102
103
        return true;
104
    }
105
106
    /**
107
     * {@inheritDoc}
108
     */
109
    public function beforeSave(Field $field, $post)
110
    {
111
        if (!$field->metadata->settings['vocabulary']) {
112
            return true;
113
        }
114
115
        $TermsTable = TableRegistry::get('Taxonomy.Terms');
116
        if ($field->metadata->settings['type'] === 'autocomplete') {
117
            $termIds = explode(',', (string)$post);
118
119
            $TermsTable->removeBehavior('Tree');
120
            $TermsTable->addBehavior('Tree', [
121
                'scope' => [
122
                    'vocabulary_id' => $field->metadata->settings['vocabulary']
123
                ]
124
            ]);
125
126
            // any non-integer value represents a new term to be registered
127
            foreach ($termIds as $i => $idOrName) {
128
                if (!intval($idOrName)) {
129
                    $alreadyExists = $TermsTable->find()
130
                        ->where(['name' => $idOrName])
131
                        ->first();
132
133
                    if ($alreadyExists) {
134
                        $termIds[$i] = $alreadyExists->id;
135
                    } else {
136
                        $termEntity = $TermsTable->newEntity([
137
                            'name' => $idOrName,
138
                            'vocabulary_id' => $field->metadata->settings['vocabulary'],
139
                        ]);
140
141
                        if ($TermsTable->save($termEntity)) {
142
                            $termIds[$i] = $termEntity->id;
143
                        } else {
144
                            unset($termIds[$i]);
145
                        }
146
                    }
147
                }
148
            }
149
            $field->set('extra', array_unique($termIds));
150
        } else {
151
            // single value given (radio)
152
            if (!is_array($post)) {
153
                $post = [$post];
154
            }
155
            $field->set('extra', array_unique($post));
156
        }
157
158
        $ids = empty($field->extra) ? [-1] : $field->extra;
159
        $termsNames = $TermsTable
160
            ->find()
161
            ->select(['name'])
162
            ->where(['id IN' => $ids])
163
            ->all()
164
            ->extract('name')
165
            ->toArray();
166
167
        $field->set('value', implode(' ', $termsNames));
168
169
        return true;
170
    }
171
172
    /**
173
     * {@inheritDoc}
174
     */
175
    public function afterSave(Field $field)
176
    {
177
        $entity = $field->get('metadata')->get('entity');
178
        $table = TableRegistry::get($entity->source());
179
        $pk = $table->primaryKey();
180
181
        if ($entity->has($pk)) {
182
            $tableAlias = Inflector::underscore($table->alias());
183
            $extra = !is_array($field->extra) ? [$field->extra] : $field->extra;
184
185
            TableRegistry::get('Taxonomy.EntitiesTerms')->deleteAll([
186
                'entity_id' => $entity->get($pk),
187
                'table_alias' => $tableAlias,
188
                'field_instance_id' => $field->metadata->instance_id,
189
            ]);
190
191
            foreach ($extra as $termId) {
192
                Cache::delete("t{$termId}", 'terms_count');
193
                $link = TableRegistry::get('Taxonomy.EntitiesTerms')
194
                    ->newEntity([
195
                        'entity_id' => $entity->get($pk),
196
                        'term_id' => $termId,
197
                        'table_alias' => $tableAlias,
198
                        'field_instance_id' => $field->metadata->instance_id,
199
                    ]);
200
201
                TableRegistry::get('Taxonomy.EntitiesTerms')->save($link);
202
            }
203
        }
204
    }
205
206
    /**
207
     * {@inheritDoc}
208
     */
209
    public function afterDelete(Field $field)
210
    {
211
        $entity = $field->get('metadata')->get('entity');
212
        $table = TableRegistry::get($entity->source());
213
        $pk = $table->primaryKey();
214
215
        if ($entity->has($pk)) {
216
            $tableAlias = Inflector::underscore($table->alias());
217
            $extra = !is_array($field->extra) ? [$field->extra] : $field->extra;
218
            TableRegistry::get('Taxonomy.EntitiesTerms')
219
                ->deleteAll([
220
                    'entity_id' => $entity->get($pk),
221
                    'table_alias' => $tableAlias,
222
                    'field_instance_id' => $field->metadata->instance_id,
223
                ]);
224
225
            foreach ($extra as $termId) {
226
                Cache::delete("t{$termId}", 'terms_count');
227
            }
228
        }
229
    }
230
231
    /**
232
     * {@inheritDoc}
233
     */
234
    public function settings(FieldInstance $instance, View $view)
235
    {
236
        $vocabularies = TableRegistry::get('Taxonomy.Vocabularies')->find('list');
237
238
        return $view->element('Taxonomy.taxonomy_field_settings_form', compact('instance', 'vocabularies'));
239
    }
240
241
    /**
242
     * {@inheritDoc}
243
     */
244
    public function defaultSettings(FieldInstance $instance)
245
    {
246
        return [
247
            'vocabulary' => null,
248
            'type' => 'checkbox', // checkbox, select, tagging
249
            'max_values' => 0, // 0: unlimited
250
            'error_message' => null,
251
        ];
252
    }
253
254
    /**
255
     * {@inheritDoc}
256
     */
257
    public function viewModeSettings(FieldInstance $instance, View $view, $viewMode)
258
    {
259
        return $view->element('Taxonomy.taxonomy_field_view_mode_form', compact('instance'));
260
    }
261
262
    /**
263
     * {@inheritDoc}
264
     */
265 View Code Duplication
    public function defaultViewModeSettings(FieldInstance $instance, $viewMode)
266
    {
267
        return [
268
            'label_visibility' => 'above',
269
            'shortcodes' => false,
270
            'hidden' => false,
271
            'formatter' => 'plain',
272
            'link_template' => '<a href="{{url}}"{{attrs}}>{{content}}</a>',
273
        ];
274
    }
275
}
276