Skip to content

Commit

Permalink
populate certain fields directly via console or CP
Browse files Browse the repository at this point in the history
  • Loading branch information
RobinSecondred committed Jul 8, 2024
1 parent 2c2b8b9 commit 1129b91
Show file tree
Hide file tree
Showing 8 changed files with 241 additions and 20 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down
35 changes: 29 additions & 6 deletions src/Seeder.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;

}
);
}
Expand Down
85 changes: 85 additions & 0 deletions src/console/controllers/PopulateController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<?php
/**
* Craft CMS Plugins
*
* Created with PhpStorm.
*
* @link https://github.com/Anubarak/
* @email [email protected]
* @copyright Copyright (c) 2024 Robin Schambach|Secondred Newmedia GmbH
*/

namespace anubarak\seeder\console\controllers;

use anubarak\seeder\Seeder;
use craft\console\Controller;
use craft\helpers\ArrayHelper;
use craft\helpers\Db;
use yii\console\ExitCode;

/**
* Class PopulateController
*
* @package anubarak\seeder\console\controllers
* @since 08.07.2024
* @author by Robin Schambach
*/
class PopulateController extends Controller
{
/**
* comma separated fields that should be populated
*
* @var string|null $fields
*/
public ?string $fields = null;

/**
* @inheritdoc
*/
public function options($actionID): array
{
$options = parent::options($actionID);
if ($actionID === 'index') {
$options[] = 'fields';
}

return $options;
}

/**
* populate an element by it's ID, optionally pass a comma separated list of fields
*
* @param int $id
*
* @return int|void
* @throws \yii\base\ExitException
* @throws \yii\base\InvalidConfigException
* @throws \yii\base\NotSupportedException
* @author Robin Schambach
* @since 08.07.2024
*/
public function actionIndex(int $id)
{
$element = \Craft::$app->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;
}
}
97 changes: 85 additions & 12 deletions src/controllers/SeederController.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
*
Expand Down Expand Up @@ -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++;
Expand All @@ -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);
}

Expand All @@ -225,7 +297,7 @@ public function actionGenerateMatrix(): Response
/**
* createUniqueBlocks
*
* @param \craft\models\EntryType $blockType
* @param \craft\models\EntryType $blockType
* @param array $fields
* @param $i
*
Expand Down Expand Up @@ -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++;
Expand All @@ -303,6 +375,7 @@ public function getAllCombinations(array $arrays): iterable
{
if ($arrays === []) {
yield [];

return;
}
$head = array_shift($arrays);
Expand Down
6 changes: 5 additions & 1 deletion src/services/SeederService.php
Original file line number Diff line number Diff line change
Expand Up @@ -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 ¯\_(ツ)_/¯
Expand All @@ -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) {
Expand Down
18 changes: 18 additions & 0 deletions src/templates/generateContent.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{% import '_includes/forms' as forms %}

<input type="hidden" name="action" value="element-seeder/seeder/generate-content">
<input type="hidden" name="elementId" value="{{ elementId }}">
{% for data in fieldData %}
<div class="field">
<h2>{{ data.tab }}</h2>
<div>
{% for field in data.fields %}
{{ forms.lightSwitchField({
label: field.label(),
name: 'fields[' ~ field.attribute() ~ ']',
}) }}
{% endfor %}
</div>
</div>
<hr>
{% endfor %}
12 changes: 12 additions & 0 deletions src/web/assets/cp/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
});

0 comments on commit 1129b91

Please sign in to comment.