Completed
Pull Request — master (#57)
by Bart
03:48
created

CategoryGroups::getLocaleDefinition()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 7
rs 9.4285
ccs 4
cts 4
cp 1
cc 1
eloc 4
nc 1
nop 1
crap 1
1
<?php
2
3
namespace NerdsAndCompany\Schematic\Services;
4
5
use Craft\Craft;
6
use Craft\CategoryGroupModel;
7
use Craft\CategoryGroupLocaleModel;
8
9
/**
10
 * Schematic Category Groups Service.
11
 *
12
 * Sync Craft Setups.
13
 *
14
 * @author    Nerds & Company
15
 * @copyright Copyright (c) 2015-2016, Nerds & Company
16
 * @license   MIT
17
 *
18
 * @link      http://www.nerds.company
19
 */
20
class CategoryGroups extends Base
21
{
22
    /**
23
     * Export categoryGroups.
24
     *
25
     * @param CategoryGroupModel[] $categoryGroups
26
     *
27
     * @return array
28
     */
29 3
    public function export(array $categoryGroups = [])
30
    {
31 3
        Craft::log(Craft::t('Exporting Category Groups'));
32
33 3
        $categoryGroupDefinitions = [];
34
35 3
        foreach ($categoryGroups as $categoryGroup) {
36 2
            $categoryGroupDefinitions[$categoryGroup->handle] = $this->getCategoryGroupDefinition($categoryGroup);
37 3
        }
38
39 3
        return $categoryGroupDefinitions;
40
    }
41
42
    /**
43
     * Get category groups definition.
44
     *
45
     * @param CategoryGroupModel $categoryGroup
46
     *
47
     * @return array
48
     */
49 2
    private function getCategoryGroupDefinition(CategoryGroupModel $categoryGroup)
50
    {
51 2
        $fieldLayout = Craft::app()->fields->getLayoutById($categoryGroup->fieldLayoutId);
52
        return [
53 2
            'name' => $categoryGroup->name,
54 2
            'hasUrls' => $categoryGroup->hasUrls,
55 2
            'template' => $categoryGroup->template,
56 2
            'maxLevels' => $categoryGroup->maxLevels,
57 2
            'locales' => $this->getLocaleDefinitions($categoryGroup->getLocales()),
58 2
            'fieldLayout' => Craft::app()->schematic_fields->getFieldLayoutDefinition($fieldLayout),
59 2
        ];
60
    }
61
62
    /**
63
     * Get locale definitions.
64
     *
65
     * @param CategoryGroupLocaleModel[] $locales
66
     *
67
     * @return array
68
     */
69 2
    private function getLocaleDefinitions(array $locales)
70
    {
71 2
        $localeDefinitions = [];
72
73 2
        foreach ($locales as $locale) {
74 2
            $localeDefinitions[$locale->locale] = $this->getLocaleDefinition($locale);
75 2
        }
76
77 2
        return $localeDefinitions;
78
    }
79
80
    /**
81
     * Get locale definition.
82
     *
83
     * @param CategoryGroupLocaleModel $locale
84
     *
85
     * @return array
86
     */
87 2
    private function getLocaleDefinition(CategoryGroupLocaleModel $locale)
88
    {
89
        return [
90 2
            'urlFormat' => $locale->urlFormat,
91 2
            'nestedUrlFormat' => $locale->nestedUrlFormat,
92 2
        ];
93
    }
94
95
    /**
96
     * Attempt to import category groups.
97
     *
98
     * @param array $categoryGroupDefinitions
99
     * @param bool  $force                If set to true category groups not included in the import will be deleted
100
     *
101
     * @return Result
102
     */
103 4
    public function import(array $categoryGroupDefinitions, $force = false)
104
    {
105 4
        Craft::log(Craft::t('Importing Category Groups'));
106
107 4
        $this->resetCraftCategoriesServiceCache();
108
        $categoryGroups = Craft::app()->categories->getAllGroups('handle');
109
110
        foreach ($categoryGroupDefinitions as $categoryGroupHandle => $categoryGroupDefinition) {
111
            $categoryGroup = array_key_exists($categoryGroupHandle, $categoryGroups)
112
                ? $categoryGroups[$categoryGroupHandle]
113
                : new CategoryGroupModel();
114
115
            unset($categoryGroups[$categoryGroupHandle]);
116
117
            $this->populateCategoryGroup($categoryGroup, $categoryGroupDefinition, $categoryGroupHandle);
118
119
            if (!Craft::app()->categories->saveGroup($categoryGroup)) { // Save categorygroup via craft
120
                $this->addErrors($categoryGroup->getAllErrors());
121
122
                continue;
123
            }
124
        }
125
126
        if ($force) {
127
            foreach ($categoryGroups as $categoryGroup) {
128
                Craft::app()->categories->deleteGroupById($categoryGroup->id);
129
            }
130
        }
131
132
        return $this->getResultModel();
133
    }
134
135
    /**
136
     * Populate categorygroup.
137
     *
138
     * @param CategoryGroupModel $categoryGroup
139
     * @param array          $categoryGroupDefinition
140
     * @param string         $categoryGroupHandle
141
     */
142
    private function populateCategoryGroup(CategoryGroupModel $categoryGroup, array $categoryGroupDefinition, $categoryGroupHandle)
143
    {
144
        $categoryGroup->setAttributes([
145
            'handle' => $categoryGroupHandle,
146
            'name' => $categoryGroupDefinition['name'],
147
            'hasUrls' => $categoryGroupDefinition['hasUrls'],
148
            'template' => $categoryGroupDefinition['template'],
149
            'maxLevels' => $categoryGroupDefinition['maxLevels'],
150
        ]);
151
152
        $this->populateCategoryGroupLocales($categoryGroup, $categoryGroupDefinition['locales']);
153
154
        $fieldLayout = Craft::app()->schematic_fields->getFieldLayout($categoryGroupDefinition['fieldLayout']);
155
        $categoryGroup->setFieldLayout($fieldLayout);
156
    }
157
158
    /**
159
     * Populate section locales.
160
     *
161
     * @param CategoryGroupModel $categoryGroup
162
     * @param $localeDefinitions
163
     */
164
    private function populateCategoryGroupLocales(CategoryGroupModel $categoryGroup, $localeDefinitions)
165
    {
166
        $locales = $categoryGroup->getLocales();
167
168
        foreach ($localeDefinitions as $localeId => $localeDef) {
169
            $locale = array_key_exists($localeId, $locales) ? $locales[$localeId] : new CategoryGroupLocaleModel();
170
171
            $locale->setAttributes([
172
                'locale' => $localeId,
173
                'urlFormat' => $localeDef['urlFormat'],
174
                'nestedUrlFormat' => $localeDef['nestedUrlFormat'],
175
            ]);
176
177
            // Todo: Is this a hack? I don't see another way.
178
            // Todo: Might need a sorting order as well? It's NULL at the moment.
179
            Craft::app()->db->createCommand()->insertOrUpdate('locales', [
180
                'locale' => $locale->locale,
181
            ], []);
182
183
            $locales[$localeId] = $locale;
184
        }
185
186
        $categoryGroup->setLocales($locales);
187
    }
188
189
    /**
190
     * Reset craft fields service cache using reflection
191
     */
192 4
    private function resetCraftCategoriesServiceCache()
193
    {
194 4
        $obj         = Craft::app()->categories;
195 4
        $refObject   = new \ReflectionObject($obj);
196 4
        $refProperty = $refObject->getProperty('_fetchedAllCategoryGroups');
197
        $refProperty->setAccessible(true);
198
        $refProperty->setValue($obj, false);
199
        $refProperty = $refObject->getProperty('_categoryGroupsById');
200
        $refProperty->setAccessible(true);
201
        $refProperty->setValue($obj, array());
202
    }
203
}
204