From 21953932f1ba1139ee0dda6b878213a5430bc87b Mon Sep 17 00:00:00 2001 From: Bart van Gennep Date: Thu, 13 Apr 2017 13:09:44 +0200 Subject: [PATCH 1/6] Created schematic_sources service Mapped element index settings sources --- src/Console/App.php | 5 +- src/Models/Field.php | 92 +--------------------- src/Services/ElementIndexSettings.php | 30 ++++++- src/Services/Sources.php | 108 ++++++++++++++++++++++++++ tests/Services/SchematicTest.php | 3 +- 5 files changed, 146 insertions(+), 92 deletions(-) create mode 100644 src/Services/Sources.php diff --git a/src/Console/App.php b/src/Console/App.php index 0a8edbe3..76203a06 100644 --- a/src/Console/App.php +++ b/src/Console/App.php @@ -65,7 +65,7 @@ public function init() if ($appId = $this->config->get('appId')) { $this->setId($appId); } - + // Initialize Cache and LogRouter right away (order is important) $this->getComponent('cache'); $this->getComponent('log'); @@ -340,6 +340,9 @@ private function _setSchematicComponents() 'schematic_tagGroups' => [ 'class' => Service\TagGroups::class, ], + 'schematic_sources' => [ + 'class' => Service\Sources::class, + ], ]; // Element index settings are supported from Craft 2.5 diff --git a/src/Models/Field.php b/src/Models/Field.php index 16b00fca..8c263fe3 100644 --- a/src/Models/Field.php +++ b/src/Models/Field.php @@ -49,11 +49,11 @@ public function getDefinition(FieldModel $field, $includeContext) } if (isset($definition['settings']['sources'])) { - $definition['settings']['sources'] = $this->getMappedSources($field->type, $definition['settings']['sources'], 'id', 'handle'); + $definition['settings']['sources'] = Craft::app()->schematic_sources->getMappedSources($field->type, $definition['settings']['sources'], 'id', 'handle'); } if (isset($definition['settings']['source'])) { - $definition['settings']['source'] = $this->getSource($field->type, $definition['settings']['source'], 'id', 'handle'); + $definition['settings']['source'] = Craft::app()->schematic_sources->getSource($field->type, $definition['settings']['source'], 'id', 'handle'); } return $definition; @@ -82,98 +82,14 @@ public function populate(array $fieldDefinition, FieldModel $field, $fieldHandle if (isset($fieldDefinition['settings']['sources'])) { $settings = $fieldDefinition['settings']; - $settings['sources'] = $this->getMappedSources($field->type, $settings['sources'], 'handle', 'id'); + $settings['sources'] = Craft::app()->schematic_sources->getMappedSources($field->type, $settings['sources'], 'handle', 'id'); $field->settings = $settings; } if (isset($fieldDefinition['settings']['source'])) { $settings = $fieldDefinition['settings']; - $settings['source'] = $this->getSource($field->type, $settings['source'], 'handle', 'id'); + $settings['source'] = Craft::app()->schematic_sources->getSource($field->type, $settings['source'], 'handle', 'id'); $field->settings = $settings; } } - - /** - * Get sources based on the indexFrom attribute and return them with the indexTo attribute. - * - * @param string $fieldType - * @param string|array $sources - * @param string $indexFrom - * @param string $indexTo - * - * @return array|string - */ - private function getMappedSources($fieldType, $sources, $indexFrom, $indexTo) - { - $mappedSources = $sources; - if (is_array($sources)) { - $mappedSources = []; - foreach ($sources as $source) { - $mappedSources[] = $this->getSource($fieldType, $source, $indexFrom, $indexTo); - } - } - - return $mappedSources; - } - - /** - * Gets a source by the attribute indexFrom, and returns it with attribute $indexTo. - * - * @TODO Break up and simplify this method - * - * @param string $fieldType - * @param string $source - * @param string $indexFrom - * @param string $indexTo - * - * @return string - */ - private function getSource($fieldType, $source, $indexFrom, $indexTo) - { - if ($source == 'singles' || $source == '*') { - return $source; - } - - /** @var BaseElementModel $sourceObject */ - $sourceObject = null; - - if (strpos($source, ':') > -1) { - list($sourceType, $sourceFrom) = explode(':', $source); - switch ($sourceType) { - case 'section': - $service = Craft::app()->sections; - $method = 'getSectionBy'; - break; - case 'group': - $service = $fieldType == 'Users' ? Craft::app()->userGroups : Craft::app()->categories; - $method = 'getGroupBy'; - break; - case 'folder': - $service = Craft::app()->schematic_assetSources; - $method = 'getSourceBy'; - break; - case 'taggroup': - $service = Craft::app()->tags; - $method = 'getTagGroupBy'; - break; - } - } elseif ($source !== 'singles') { - //Backwards compatibility - $sourceType = 'section'; - $sourceFrom = $source; - $service = Craft::app()->sections; - $method = 'getSectionBy'; - } - - if (isset($service) && isset($method) && isset($sourceFrom)) { - $method = $method.$indexFrom; - $sourceObject = $service->$method($sourceFrom); - } - - if ($sourceObject && isset($sourceType)) { - return $sourceType.':'.$sourceObject->$indexTo; - } - - return ''; - } } diff --git a/src/Services/ElementIndexSettings.php b/src/Services/ElementIndexSettings.php index 467a4dec..520ffc36 100644 --- a/src/Services/ElementIndexSettings.php +++ b/src/Services/ElementIndexSettings.php @@ -44,7 +44,8 @@ public function import(array $settingDefinitions, $force = false) Craft::log(Craft::t('Importing Element Index Settings')); foreach ($settingDefinitions as $elementType => $settings) { - if (!$this->getElementIndexesService()->saveSettings($elementType, $settings)) { + $mappedSettings = $this->getMappedSettings($settings, 'handle', 'id'); + if (!$this->getElementIndexesService()->saveSettings($elementType, $mappedSettings)) { $this->addError(Craft::t('Element Index Settings for {elementType} could not be installed', ['elementType' => $elementType])); } } @@ -79,10 +80,35 @@ public function export(array $data = []) if (is_array($settings)) { // Group by element type and add to definitions - $settingDefinitions[$elementTypeName] = $settings; + $mappedSettings = $this->getMappedSettings($settings, 'id', 'handle'); + $settingDefinitions[$elementTypeName] = $mappedSettings; } } return $settingDefinitions; } + + /** + * Get mapped element index settings, converting source ids to handles or back again + * + * @param array $settings + * @param string $fromIndex + * @param string $toIndex + * + * @return array + */ + private function getMappedSettings(array $settings, $fromIndex, $toIndex) + { + $mappedSettings = ['sources' => []]; + foreach ($settings['sources'] as $source => $sourceSettings) { + $mappedSource = Craft::app()->schematic_sources->getSource(false, $source, $fromIndex, $toIndex); + $tableAttributesSettings = []; + foreach ($sourceSettings as $index => $columnSource) { + $mappedColumnSource = Craft::app()->schematic_sources->getSource(false, $columnSource, $fromIndex, $toIndex); + $tableAttributesSettings[$index] = $mappedColumnSource; + } + $mappedSettings['sources'][$mappedSource]['tableAttributes'] = $tableAttributesSettings; + } + return $mappedSettings; + } } diff --git a/src/Services/Sources.php b/src/Services/Sources.php new file mode 100644 index 00000000..5bf6a70c --- /dev/null +++ b/src/Services/Sources.php @@ -0,0 +1,108 @@ +getSource($fieldType, $source, $indexFrom, $indexTo); + } + } + + return $mappedSources; + } + + /** + * Gets a source by the attribute indexFrom, and returns it with attribute $indexTo. + * + * @TODO Break up and simplify this method + * + * @param string $fieldType + * @param string $source + * @param string $indexFrom + * @param string $indexTo + * + * @return string + */ + public function getSource($fieldType, $source, $indexFrom, $indexTo) + { + if ($source == 'singles' || $source == '*') { + return $source; + } + + /** @var BaseElementModel $sourceObject */ + $sourceObject = null; + + if (strpos($source, ':') > -1) { + list($sourceType, $sourceFrom) = explode(':', $source); + switch ($sourceType) { + case 'section': + $service = Craft::app()->sections; + $method = 'getSectionBy'; + break; + case 'group': + $service = $fieldType == 'Users' ? Craft::app()->userGroups : Craft::app()->categories; + $method = 'getGroupBy'; + break; + case 'folder': + $service = Craft::app()->schematic_assetSources; + $method = 'getSourceBy'; + break; + case 'taggroup': + $service = Craft::app()->tags; + $method = 'getTagGroupBy'; + break; + case 'field': + $service = Craft::app()->fields; + $method = 'getFieldBy'; + break; + } + } elseif ($source !== 'singles') { + //Backwards compatibility + $sourceType = 'section'; + $sourceFrom = $source; + $service = Craft::app()->sections; + $method = 'getSectionBy'; + } + + if (isset($service) && isset($method) && isset($sourceFrom)) { + $method = $method.$indexFrom; + $sourceObject = $service->$method($sourceFrom); + } + + if ($sourceObject && isset($sourceType)) { + return $sourceType.':'.$sourceObject->$indexTo; + } + + return ''; + } +} diff --git a/tests/Services/SchematicTest.php b/tests/Services/SchematicTest.php index 68d3540f..bc6f4d04 100644 --- a/tests/Services/SchematicTest.php +++ b/tests/Services/SchematicTest.php @@ -28,7 +28,7 @@ * * @link http://www.nerds.company * - * @coversDefaultClass NerdsAndCompany\Schematic\Services\Schematic + * @coversDefaultClass \NerdsAndCompany\Schematic\Services\Schematic * @covers :: */ class SchematicTest extends BaseTest @@ -265,6 +265,7 @@ private function mockServices() $this->createMockService(CategoryGroups::class, 'schematic_categoryGroups'); $this->createMockService(TagGroups::class, 'schematic_tagGroups'); $this->createMockService(ElementIndexSettings::class, 'schematic_elementIndexSettings'); + $this->createMockService(Sources::class, 'schematic_sources'); $mockPluginsService = $this->getMockPluginsService(); $this->setCraftComponent('plugins', $mockPluginsService); From 923fd8c9be319fd13f3eda083e4af9ee0913cef6 Mon Sep 17 00:00:00 2001 From: Bart van Gennep Date: Thu, 13 Apr 2017 14:17:25 +0200 Subject: [PATCH 2/6] Fix elementindex tests --- src/Services/ElementIndexSettings.php | 4 +-- tests/Services/ElementIndexSettingsTest.php | 32 +++++++++++++++++++++ tests/Services/SchematicTest.php | 1 - 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/src/Services/ElementIndexSettings.php b/src/Services/ElementIndexSettings.php index 520ffc36..a32978d9 100644 --- a/src/Services/ElementIndexSettings.php +++ b/src/Services/ElementIndexSettings.php @@ -103,11 +103,11 @@ private function getMappedSettings(array $settings, $fromIndex, $toIndex) foreach ($settings['sources'] as $source => $sourceSettings) { $mappedSource = Craft::app()->schematic_sources->getSource(false, $source, $fromIndex, $toIndex); $tableAttributesSettings = []; - foreach ($sourceSettings as $index => $columnSource) { + foreach ($sourceSettings['tableAttributes'] as $index => $columnSource) { $mappedColumnSource = Craft::app()->schematic_sources->getSource(false, $columnSource, $fromIndex, $toIndex); $tableAttributesSettings[$index] = $mappedColumnSource; } - $mappedSettings['sources'][$mappedSource]['tableAttributes'] = $tableAttributesSettings; + $mappedSettings['sources'][$mappedSource] = ['tableAttributes' => $tableAttributesSettings]; } return $mappedSettings; } diff --git a/tests/Services/ElementIndexSettingsTest.php b/tests/Services/ElementIndexSettingsTest.php index 8618cfc2..1afe26e8 100644 --- a/tests/Services/ElementIndexSettingsTest.php +++ b/tests/Services/ElementIndexSettingsTest.php @@ -37,6 +37,7 @@ class ElementIndexSettingsTest extends BaseTest public function setUp() { $this->schematicElementIndexSettingsService = new ElementIndexSettings(); + $this->setMockSources(); } /** @@ -155,4 +156,35 @@ public function getElementIndexSettingsData() ], ]; } + + /** + * @return Mock|Sources + */ + private function setMockSources() + { + $mockSources = $this->getMockBuilder(Sources::class) + ->disableOriginalConstructor() + ->getMock(); + + $mockSources->expects($this->any()) + ->method('getSource') + ->willReturn($this->returnCallback(array($this, 'getMockSourceCallback'))); + + $this->setComponent(Craft::app(), 'schematic_sources', $mockSources); + + return $mockSources; + } + + /** + * @param string $fieldType + * @param string $source + * @param string $fromIndex + * @param string $toIndex + * + * @return string + */ + public function getMockSourceCallback($fieldType, $source, $fromIndex, $toIndex) + { + return $source; + } } diff --git a/tests/Services/SchematicTest.php b/tests/Services/SchematicTest.php index bc6f4d04..663c17ee 100644 --- a/tests/Services/SchematicTest.php +++ b/tests/Services/SchematicTest.php @@ -265,7 +265,6 @@ private function mockServices() $this->createMockService(CategoryGroups::class, 'schematic_categoryGroups'); $this->createMockService(TagGroups::class, 'schematic_tagGroups'); $this->createMockService(ElementIndexSettings::class, 'schematic_elementIndexSettings'); - $this->createMockService(Sources::class, 'schematic_sources'); $mockPluginsService = $this->getMockPluginsService(); $this->setCraftComponent('plugins', $mockPluginsService); From b97ce685c192c50b265e1a522519ef9eee5b2df7 Mon Sep 17 00:00:00 2001 From: Bart van Gennep Date: Thu, 13 Apr 2017 15:39:10 +0200 Subject: [PATCH 3/6] Return given source in stead of empty string when no match found --- src/Services/Sources.php | 2 +- tests/Services/ElementIndexSettingsTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Services/Sources.php b/src/Services/Sources.php index 5bf6a70c..4d9722d3 100644 --- a/src/Services/Sources.php +++ b/src/Services/Sources.php @@ -103,6 +103,6 @@ public function getSource($fieldType, $source, $indexFrom, $indexTo) return $sourceType.':'.$sourceObject->$indexTo; } - return ''; + return $source; } } diff --git a/tests/Services/ElementIndexSettingsTest.php b/tests/Services/ElementIndexSettingsTest.php index 1afe26e8..0f94294e 100644 --- a/tests/Services/ElementIndexSettingsTest.php +++ b/tests/Services/ElementIndexSettingsTest.php @@ -168,7 +168,7 @@ private function setMockSources() $mockSources->expects($this->any()) ->method('getSource') - ->willReturn($this->returnCallback(array($this, 'getMockSourceCallback'))); + ->will($this->returnCallback(array($this, 'getMockSourceCallback'))); $this->setComponent(Craft::app(), 'schematic_sources', $mockSources); From 580a0be26383c95884792607e10d90046e2cd4b1 Mon Sep 17 00:00:00 2001 From: Bart van Gennep Date: Thu, 13 Apr 2017 17:14:09 +0200 Subject: [PATCH 4/6] Expanded element index settings test to include sources --- tests/Services/ElementIndexSettingsTest.php | 97 ++++++++++++++++++--- 1 file changed, 86 insertions(+), 11 deletions(-) diff --git a/tests/Services/ElementIndexSettingsTest.php b/tests/Services/ElementIndexSettingsTest.php index 0f94294e..fb9b4be8 100644 --- a/tests/Services/ElementIndexSettingsTest.php +++ b/tests/Services/ElementIndexSettingsTest.php @@ -4,10 +4,12 @@ use Craft\Craft; use Craft\BaseTest; -use Craft\ElementsService; -use Craft\ElementIndexesService; use Craft\CategoryElementType; +use Craft\ElementIndexesService; +use Craft\ElementsService; use Craft\EntryElementType; +use Craft\FieldModel; +use Craft\FieldsService; use NerdsAndCompany\Schematic\Models\Result; use PHPUnit_Framework_MockObject_MockObject as Mock; @@ -38,6 +40,7 @@ public function setUp() { $this->schematicElementIndexSettingsService = new ElementIndexSettings(); $this->setMockSources(); + $this->setMockFieldsService(); } /** @@ -62,10 +65,14 @@ protected function getMockElementsService($getAllElementTypesResponse = []) * * @return Mock */ - protected function getMockElementIndexesService($getSettingsResponse = []) + protected function getMockElementIndexesService() { + $getSettingsResponse = $this->getElementIndexSettingsSavedData(); $mock = $this->getMockBuilder(ElementIndexesService::class)->getMock(); - $mock->expects($this->any())->method('getSettings')->willReturn($getSettingsResponse['Entry']); + $mock->expects($this->any())->method('getSettings')->will($this->returnValueMap([ + ['Entry', $getSettingsResponse['Entry']], + ['Category', $getSettingsResponse['Category']] + ])); $mock->expects($this->any())->method('saveSettings')->willReturn(false); return $mock; @@ -78,8 +85,8 @@ protected function getMockElementIndexesService($getSettingsResponse = []) */ public function testImport() { - $data = $this->getElementIndexSettingsData(); - $mockElementIndexesService = $this->getMockElementIndexesService($data); + $data = $this->getElementIndexSettingsExportedData(); + $mockElementIndexesService = $this->getMockElementIndexesService(); $this->setComponent(Craft::app(), 'elementIndexes', $mockElementIndexesService); $import = $this->schematicElementIndexSettingsService->import($data); @@ -99,8 +106,8 @@ public function testExport() $mockElementsService = $this->getMockElementsService($data); $this->setComponent(Craft::app(), 'elements', $mockElementsService); - $data = $this->getElementIndexSettingsData(); - $mockElementIndexesService = $this->getMockElementIndexesService($data); + $data = $this->getElementIndexSettingsExportedData(); + $mockElementIndexesService = $this->getMockElementIndexesService(); $this->setComponent(Craft::app(), 'elementIndexes', $mockElementIndexesService); $export = $this->schematicElementIndexSettingsService->export(); @@ -121,11 +128,11 @@ public function getElementsData() } /** - * Returns element index settings data. + * Returns element index settings saved data. * * @return array */ - public function getElementIndexSettingsData() + private function getElementIndexSettingsSavedData() { return [ 'Category' => [ @@ -137,6 +144,45 @@ public function getElementIndexSettingsData() '3' => 'expiryDate', '4' => 'author', '5' => 'link', + '6' => 'field:1', + ], + ], + ], + ], + 'Entry' => [ + 'sources' => [ + '*' => [ + 'tableAttributes' => [ + '1' => 'section', + '2' => 'postDate', + '3' => 'expiryDate', + '4' => 'author', + '5' => 'link', + ], + ], + ], + ], + ]; + } + + /** + * Returns element index settings exported data. + * + * @return array + */ + private function getElementIndexSettingsExportedData() + { + return [ + 'Category' => [ + 'sources' => [ + '*' => [ + 'tableAttributes' => [ + '1' => 'section', + '2' => 'postDate', + '3' => 'expiryDate', + '4' => 'author', + '5' => 'link', + '6' => 'field:handle', ], ], ], @@ -185,6 +231,35 @@ private function setMockSources() */ public function getMockSourceCallback($fieldType, $source, $fromIndex, $toIndex) { - return $source; + switch ($source) { + case 'field:handle': + return 'field:1'; + break; + case 'field:1': + return 'field:handle'; + break; + default: + return $source; + break; + } + } + + /** + * @return Mock|CraftFieldsService + */ + private function setMockFieldsService() + { + $mockFieldsService = $this->getMockBuilder(FieldsService::class) + ->disableOriginalConstructor() + ->getMock(); + + $mockFieldsService->expects($this->any()) + ->method('getFieldById') + ->with('1') + ->willReturn(new FieldModel(['handle' => 'handle'])); + + $this->setComponent(Craft::app(), 'fields', $mockFieldsService); + + return $mockFieldsService; } } From a44c0b79811c029a313c1805ff26d1a931456e78 Mon Sep 17 00:00:00 2001 From: Bart van Gennep Date: Thu, 13 Apr 2017 17:14:16 +0200 Subject: [PATCH 5/6] Updated changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index deffc9ce..613bae72 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +###3.7.2### +- Use handles for element index settings + ###3.7.1### - Removed Asset Transform dimensionChangeTime attribute from schema From 7557073ebf85677ae2a7677e9cb6c7b07e0ef47e Mon Sep 17 00:00:00 2001 From: Bart van Gennep Date: Fri, 14 Apr 2017 10:22:46 +0200 Subject: [PATCH 6/6] Codestyle fixes --- src/Services/Sources.php | 4 ++-- tests/Services/SchematicTest.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Services/Sources.php b/src/Services/Sources.php index 4d9722d3..c10037fe 100644 --- a/src/Services/Sources.php +++ b/src/Services/Sources.php @@ -59,8 +59,8 @@ public function getSource($fieldType, $source, $indexFrom, $indexTo) return $source; } - /** @var BaseElementModel $sourceObject */ - $sourceObject = null; + /** @var BaseElementModel $sourceObject */ + $sourceObject = null; if (strpos($source, ':') > -1) { list($sourceType, $sourceFrom) = explode(':', $source); diff --git a/tests/Services/SchematicTest.php b/tests/Services/SchematicTest.php index 663c17ee..68d3540f 100644 --- a/tests/Services/SchematicTest.php +++ b/tests/Services/SchematicTest.php @@ -28,7 +28,7 @@ * * @link http://www.nerds.company * - * @coversDefaultClass \NerdsAndCompany\Schematic\Services\Schematic + * @coversDefaultClass NerdsAndCompany\Schematic\Services\Schematic * @covers :: */ class SchematicTest extends BaseTest