Completed
Push — 2.0 ( 5e3f46...673bed )
by Christopher
03:13
created

TermField::beforeSave()   C

Complexity

Conditions 9
Paths 7

Size

Total Lines 58
Code Lines 40

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 2 Features 0
Metric Value
c 2
b 2
f 0
dl 0
loc 58
rs 6.9928
cc 9
eloc 40
nc 7
nop 2

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->addBehavior('Tree', ['scope' => ['vocabulary_id' => $field->metadata->settings['vocabulary']]]);
61
            $terms = $TermsTable->find('treeList', ['spacer' => '&nbsp;&nbsp;']);
62
        }
63
64
        return $view->element('Taxonomy.taxonomy_field_edit', compact('field', 'terms'));
65
    }
66
67
    /**
68
     * {@inheritDoc}
69
     */
70
    public function validate(Field $field, Validator $validator)
71
    {
72
        if ($field->metadata->required) {
73
            $validator->notEmpty($field->name, __d('taxonomy', 'Field required.'), true);
74
        } else {
75
            $validator->allowEmpty($field->name, true);
76
        }
77
78
        if (intval($field->metadata->settings['max_values']) > 0) {
79
            if (!empty($field->metadata->settings['error_message'])) {
80
                $limitErrorMessage = $field->metadata->settings['error_message'];
81
            } else {
82
                $limitErrorMessage = __d('taxonomy', 'You can select {0,number} values as maximum.', $field->metadata->settings['max_values']);
83
            }
84
85
            $validator
86
            ->add($field->name, 'validateLimit', [
87
                'rule' => function ($value, $context) use ($field) {
88
                    if (!is_array($value)) {
89
                        $value = explode(',', (string)$value);
90
                    }
91
                    return count($value) <= $field->metadata->settings['max_values'];
92
                },
93
                'message' => $limitErrorMessage,
94
            ]);
95
        }
96
97
        return true;
98
    }
99
100
    /**
101
     * {@inheritDoc}
102
     */
103
    public function beforeSave(Field $field, $post)
104
    {
105
        if (!$field->metadata->settings['vocabulary']) {
106
            return true;
107
        }
108
109
        $TermsTable = TableRegistry::get('Taxonomy.Terms');
110
        if ($field->metadata->settings['type'] === 'autocomplete') {
111
            $termIds = explode(',', (string)$post);
112
            $TermsTable->addBehavior('Tree', [
113
            'scope' => [
114
                'vocabulary_id' => $field->metadata->settings['vocabulary']
115
            ]
116
            ]);
117
118
            // any non-integer value represents a new term to be registered
119
            foreach ($termIds as $i => $idOrName) {
120
                if (!intval($idOrName)) {
121
                    $alreadyExists = $TermsTable
122
                    ->find()
123
                    ->where(['name' => $idOrName])
124
                    ->first();
125
                    if ($alreadyExists) {
126
                        $termIds[$i] = $alreadyExists->id;
127
                    } else {
128
                        $termEntity = $TermsTable->newEntity([
129
                        'name' => $idOrName,
130
                        'vocabulary_id' => $field->metadata->settings['vocabulary'],
131
                        ]);
132
                        if ($TermsTable->save($termEntity)) {
133
                            $termIds[$i] = $termEntity->id;
134
                        } else {
135
                            unset($termIds[$i]);
136
                        }
137
                    }
138
                }
139
            }
140
            $field->set('extra', array_unique($termIds));
141
        } else {
142
            // single value given (radio)
143
            if (!is_array($post)) {
144
                $post = [$post];
145
            }
146
            $field->set('extra', array_unique($post));
147
        }
148
149
        $ids = empty($field->extra) ? [-1] : $field->extra;
150
        $termsNames = $TermsTable
151
            ->find()
152
            ->select(['name'])
153
            ->where(['id IN' => $ids])
154
            ->all()
155
            ->extract('name')
156
            ->toArray();
157
158
        $field->set('value', implode(' ', $termsNames));
159
        return true;
160
    }
161
162
    /**
163
     * {@inheritDoc}
164
     */
165
    public function afterSave(Field $field)
166
    {
167
        $entity = $field->get('metadata')->get('entity');
168
        $table = TableRegistry::get($entity->source());
169
        $pk = $table->primaryKey();
170
171
        if ($entity->has($pk)) {
172
            $TermsCache = TableRegistry::get('Taxonomy.EntitiesTerms');
173
            $tableAlias = Inflector::underscore($table->alias());
174
            $extra = !is_array($field->extra) ? [$field->extra] : $field->extra;
175
            $TermsCache->deleteAll([
176
                'entity_id' => $entity->get($pk),
177
                'table_alias' => $tableAlias,
178
                'field_instance_id' => $field->metadata->instance_id,
179
            ]);
180
181
            foreach ($extra as $termId) {
182
                Cache::delete("t{$termId}", 'terms_count');
183
                $cacheEntity = $TermsCache->newEntity([
184
                    'entity_id' => $entity->get($pk),
185
                    'term_id' => $termId,
186
                    'table_alias' => $tableAlias,
187
                    'field_instance_id' => $field->metadata->instance_id,
188
                ]);
189
                $TermsCache->save($cacheEntity);
190
            }
191
        }
192
    }
193
194
    /**
195
     * {@inheritDoc}
196
     */
197
    public function settings(FieldInstance $instance, View $view)
198
    {
199
        $vocabularies = TableRegistry::get('Taxonomy.Vocabularies')->find('list');
200
        return $view->element('Taxonomy.taxonomy_field_settings_form', compact('instance', 'vocabularies'));
201
    }
202
203
    /**
204
     * {@inheritDoc}
205
     */
206
    public function defaultSettings(FieldInstance $instance)
207
    {
208
        return [
209
        'vocabulary' => null,
210
        'type' => 'checkbox', // checkbox, select, tagging
211
        'max_values' => 0, // 0: unlimited
212
        'error_message' => null,
213
        ];
214
    }
215
216
    /**
217
     * {@inheritDoc}
218
     */
219
    public function viewModeSettings(FieldInstance $instance, View $view, $viewMode)
220
    {
221
        return $view->element('Taxonomy.taxonomy_field_view_mode_form', compact('instance'));
222
    }
223
224
    /**
225
     * {@inheritDoc}
226
     */
227 View Code Duplication
    public function defaultViewModeSettings(FieldInstance $instance, $viewMode)
228
    {
229
        return [
230
        'label_visibility' => 'above',
231
        'shortcodes' => false,
232
        'hidden' => false,
233
        'formatter' => 'plain',
234
        'link_template' => '<a href="{{url}}"{{attrs}}>{{content}}</a>',
235
        ];
236
    }
237
}
238