diff --git a/CHANGELOG.md b/CHANGELOG.md index 0db2621..44bae6a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Craft Seeder Changelog +## 5.0.0.1 - 2024-07-08 + +### added + +- add a way to populate certain fields for single elements directly via CP or console + ## 5.0.0 - 2024-06-26 ### added diff --git a/composer.json b/composer.json index df68e45..f446e3c 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,7 @@ { "name": "anubarak/craft-seeder", "description": "Easy entries seeder for Craft CMS", - "version": "5.0.0", + "version": "5.0.0.1", "type": "craft-plugin", "keywords": [ "craft", diff --git a/src/Seeder.php b/src/Seeder.php index 49d1fc3..56389fb 100644 --- a/src/Seeder.php +++ b/src/Seeder.php @@ -126,26 +126,49 @@ static function(DefineHtmlEvent $event) { break; } } - if (!$show) { - return; - } + \Craft::$app->getView()->registerAssetBundle(SeederAssetBundle::class); + $div = Html::tag('div', '', [ 'data-icon' => 'wand-magic-sparkles' ]); - $event->html = Html::tag('button', $div. 'Seed Matrix', [ + $content = Html::tag('button', $div. 'Seed Content', [ 'type' => 'button', - 'data' => [ 'element-id' => $event->sender->id ], 'class' => [ 'btn', - 'seed-element', + 'seed-element-content', + ] + ]); + + if ($show) { + $div = Html::tag('div', '', [ + 'data-icon' => 'wand-magic-sparkles' + ]); + $content .= Html::tag('button', $div. 'Seed Matrix', [ + 'type' => 'button', + + 'data' => [ + 'element-id' => $event->sender->id + ], + 'class' => [ + 'btn', + 'seed-element', + ] + ]); + } + + $outerDiv = Html::tag('div', $content , [ + 'class' => [ + 'flex' ] ]); + $event->html = $outerDiv; + } ); } diff --git a/src/console/controllers/PopulateController.php b/src/console/controllers/PopulateController.php new file mode 100644 index 0000000..096a52d --- /dev/null +++ b/src/console/controllers/PopulateController.php @@ -0,0 +1,85 @@ +getElements()->getElementById($id); + if (!$element) { + $this->stderr('No element found with ID: ' . $id . PHP_EOL); + + return ExitCode::UNSPECIFIED_ERROR; + } + + $fields = []; + if ($this->fields) { + $fields = ArrayHelper::toArray($this->fields); + } + + $seeder = Seeder::$plugin->getSeeder(); + $seeder->populateFields($element, $fields); + if (!\Craft::$app->getElements()->saveElement($element)) { + $this->stderr('Failed to save element with ID: ' . $id . PHP_EOL); + + return ExitCode::UNSPECIFIED_ERROR; + } + + return ExitCode::OK; + } +} \ No newline at end of file diff --git a/src/controllers/SeederController.php b/src/controllers/SeederController.php index 205cbeb..0dfd5f9 100644 --- a/src/controllers/SeederController.php +++ b/src/controllers/SeederController.php @@ -15,6 +15,7 @@ use anubarak\seeder\records\SeederUserRecord; use anubarak\seeder\Seeder; use Craft; +use craft\fieldlayoutelements\CustomField; use craft\fields\BaseOptionsField; use craft\fields\Lightswitch; use craft\fields\Matrix; @@ -129,6 +130,77 @@ public function actionElementMatrixModal(): Response ]); } + /** + * actionElementContentModal + * + * @return \yii\web\Response + * @author Robin Schambach + * @since 08.07.2024 + */ + public function actionElementContentModal(): Response + { + $elementId = $this->request->getQueryParam('elementId'); + $element = Craft::$app->getElements()->getElementById($elementId); + $data = []; + if ($element->getFieldLayout()) { + foreach ($element->getFieldLayout()->getTabs() as $tab) { + $d = [ + 'tab' => $tab->name, + 'fields' => [] + ]; + foreach ($tab->getElements() as $fieldLayoutElement) { + if ($fieldLayoutElement instanceof CustomField) { + $d['fields'][] = $fieldLayoutElement; + } + } + $data[] = $d; + } + } + + return $this->asCpScreen() + ->contentTemplate('element-seeder/generateContent.twig', [ + 'elementId' => $element->id, + 'fieldData' => $data, + ]); + } + + /** + * actionGenerateContent + * + * @return \yii\web\Response + * @throws \Throwable + * @throws \craft\errors\ElementNotFoundException + * @throws \yii\base\Exception + * @throws \yii\base\ExitException + * @throws \yii\base\InvalidConfigException + * @throws \yii\base\NotSupportedException + * @throws \yii\web\MethodNotAllowedHttpException + * @author Robin Schambach + * @since 08.07.2024 + */ + public function actionGenerateContent(): Response + { + $this->requirePostRequest(); + $elementId = $this->request->getBodyParam('elementId'); + $element = Craft::$app->getElements()->getElementById($elementId); + + $seeder = Seeder::$plugin->getSeeder(); + + $fields = $this->request->getBodyParam('fields'); + $fieldHandles = []; + foreach ($fields as $handle => $value) { + if ((bool) $value) { + $fieldHandles[] = $handle; + } + } + $seeder->populateFields($element, $fieldHandles); + if (!\Craft::$app->getElements()->saveElement($element)) { + return $this->asModelFailure($element, 'Could not save Element due to validation errors'); + } + + return $this->asSuccess('Content generated successfully'); + } + /** * actionGenerateMatrix * @@ -174,28 +246,28 @@ public function actionGenerateMatrix(): Response $fields[] = $blockTypeField; } - if($fields){ + if ($fields) { $uniqueBlocks = $this->createUniqueBlocks($entryType, $fields, $i); - foreach ($uniqueBlocks as $key => $block){ + foreach ($uniqueBlocks as $key => $block) { $fieldValue[$key] = $block; } } else { // add a number of blocks $nr = $blockTypeConfig['number'] ?? null; if ($nr) { - for($x = 0; $x < $nr; $x++){ + for ($x = 0; $x < $nr; $x++) { // just add random blocks $f = []; foreach ($entryType->getFieldLayout()->getCustomFields() as $blockTypeField) { $v = $seeder->getFieldData($blockTypeField); - if($v){ + if ($v) { $f[$blockTypeField->handle] = $v; } } $fieldValue['new:' . $i] = [ - 'type' => $entryType->handle, - 'title' => Seeder::$plugin->fields->Title(), + 'type' => $entryType->handle, + 'title' => Seeder::$plugin->fields->Title(), 'fields' => $f ]; $i++; @@ -205,17 +277,17 @@ public function actionGenerateMatrix(): Response } $ids = $element->getFieldValue($matrixField->handle)->ids(); - foreach ($fieldValue as $key => $item){ - $ids[] =$key; + foreach ($fieldValue as $key => $item) { + $ids[] = $key; } $element->setFieldValue($matrixField->handle, [ 'sortOrder' => $ids, - 'entries' => $fieldValue + 'entries' => $fieldValue ]); } - if(!Craft::$app->getElements()->saveElement($element)){ + if (!Craft::$app->getElements()->saveElement($element)) { return $this->asModelFailure($element); } @@ -225,7 +297,7 @@ public function actionGenerateMatrix(): Response /** * createUniqueBlocks * - * @param \craft\models\EntryType $blockType + * @param \craft\models\EntryType $blockType * @param array $fields * @param $i * @@ -281,7 +353,7 @@ public function createUniqueBlocks(EntryType $blockType, array $fields, &$i): ar } $fieldValue['new' . $i] = [ - 'type' => $blockType->handle, + 'type' => $blockType->handle, 'fields' => $f ]; $i++; @@ -303,6 +375,7 @@ public function getAllCombinations(array $arrays): iterable { if ($arrays === []) { yield []; + return; } $head = array_shift($arrays); diff --git a/src/services/SeederService.php b/src/services/SeederService.php index cf5bb7d..c29dac8 100644 --- a/src/services/SeederService.php +++ b/src/services/SeederService.php @@ -95,7 +95,7 @@ public function __construct(array $config = []) * @throws \yii\base\InvalidConfigException * @throws \yii\base\NotSupportedException */ - public function populateFields(ElementInterface $element): ElementInterface + public function populateFields(ElementInterface $element, array $fieldHandles = []): ElementInterface { $layout = $element->getFieldLayout(); // no layout -> nothing we can do ¯\_(ツ)_/¯ @@ -106,6 +106,10 @@ public function populateFields(ElementInterface $element): ElementInterface $fields = $layout->getCustomFields(); foreach ($fields as $field) { + if (!empty($fieldHandles) && !\in_array($field->handle, $fieldHandles, true)) { + continue; + } + try { $fieldData = $this->getFieldData($field, $element); if ($fieldData) { diff --git a/src/templates/generateContent.twig b/src/templates/generateContent.twig new file mode 100644 index 0000000..8272b39 --- /dev/null +++ b/src/templates/generateContent.twig @@ -0,0 +1,18 @@ +{% import '_includes/forms' as forms %} + + + +{% for data in fieldData %} +
+

{{ data.tab }}

+
+ {% for field in data.fields %} + {{ forms.lightSwitchField({ + label: field.label(), + name: 'fields[' ~ field.attribute() ~ ']', + }) }} + {% endfor %} +
+
+
+{% endfor %} \ No newline at end of file diff --git a/src/web/assets/cp/main.js b/src/web/assets/cp/main.js index 59cf5d4..7ea3aff 100644 --- a/src/web/assets/cp/main.js +++ b/src/web/assets/cp/main.js @@ -13,3 +13,15 @@ seederBtn.forEach(el => { el.addEventListener('click', handler); }) + +const seedContentHandler = (event) => { + new Craft.CpScreenSlideout('element-seeder/seeder/element-content-modal', { + showHeader: true, + params: { + elementId: event.currentTarget.dataset.elementId + } + }); +} +document.querySelectorAll('.seed-element-content').forEach(el => { + el.addEventListener('click', seedContentHandler); +}); \ No newline at end of file