Skip to content

Commit

Permalink
Merge pull request #20 from venveo/feature/all-fields-editable
Browse files Browse the repository at this point in the history
Feature/all fields editable
  • Loading branch information
Mosnar authored Feb 20, 2020
2 parents 368f7fb + 1d1e0f8 commit 7c425e2
Show file tree
Hide file tree
Showing 17 changed files with 277 additions and 102 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Bulk Edit Changelog

## 2.0.2 - 2020-02-20
### Added
- All field types (including custom ones and Matrix) now support bulk replacement!!!

## 2.0.1 - 2020-02-13
### Fixed
- Fixed problem with saving bulk edit jobs in Firefox
Expand Down
6 changes: 1 addition & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Bulk Edit plugin for Craft CMS 3.2
# Bulk Edit plugin for Craft CMS 3.2+

## Overview
The Bulk Edit plugin adds an action to supported element index pages that allows you to edit fields on a large number of
Expand All @@ -24,10 +24,6 @@ Additionally, some fields support different strategies for the edit process. At
Craft to pick it up. After the queue has finished, you may reload the page and see your changes.

## Limitation & Issues
* Custom fields and Matrix fields are not currently supported due to issues that arise when a field is rendered without
single entry selected.
* Currently, there isn't a way to edit properties on elements that are not custom fields (for example, title, slug,
post date, etc)
* Validation is not enforced when you're editing these fields, this means you can end up with elements with fields in
potentially erroneous states (for example, removing all content on a required field)
* After the queue finishes running, make sure you refresh the page to see the updates in the element index
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "venveo/craft-bulkedit",
"description": "Bulk edit entries",
"type": "craft-plugin",
"version": "2.0.1",
"version": "2.0.2",
"keywords": [
"craft",
"cms",
Expand Down
13 changes: 13 additions & 0 deletions src/base/AbstractElementTypeProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,20 @@

namespace venveo\bulkedit\base;

use Craft;
use craft\base\Element;

abstract class AbstractElementTypeProcessor implements ElementTypeProcessorInterface
{
public static function getEditableAttributes(): array
{
return [];
}

public static function getMockElement($elementIds = [], $params = []): Element
{
/** @var Element $elementPlaceholder */
$elementPlaceholder = Craft::createObject(static::getType(), $params);
return $elementPlaceholder;
}
}
5 changes: 5 additions & 0 deletions src/base/ElementTypeProcessorInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace venveo\bulkedit\base;

use craft\base\Element;
use craft\web\User;

interface ElementTypeProcessorInterface
Expand All @@ -27,4 +28,8 @@ public static function hasPermission($elementIds, User $user): bool;
* @return string
*/
public static function getType(): string;

public static function getEditableAttributes(): array;

public static function getMockElement($elementIds = [], $params = []): Element;
}
15 changes: 13 additions & 2 deletions src/controllers/BulkEditController.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
use Twig\Error\LoaderError;
use Twig\Error\RuntimeError;
use Twig\Error\SyntaxError;
use venveo\bulkedit\base\ElementTypeProcessorInterface;
use venveo\bulkedit\Plugin;
use venveo\bulkedit\services\BulkEdit as BulkEditService;
use yii\web\BadRequestHttpException;
Expand Down Expand Up @@ -81,12 +82,13 @@ public function actionGetFields(): Response

/** @var BulkEditService $service */
$service = Plugin::$plugin->bulkEdit;
$fields = $service->getFieldsForElementIds($elementIds, $elementType);

$fields = $service->getFieldWrappers($elementIds, $elementType);
$attributes = $service->getAttributeWrappers($elementType);

$view = Craft::$app->getView();
$modalHtml = $view->renderTemplate('venveo-bulk-edit/elementactions/BulkEdit/_fields', [
'fieldWrappers' => $fields,
'attributeWrappers' => $attributes,
'elementType' => $elementType,
'bulkedit' => $service,
'elementIds' => $elementIds,
Expand Down Expand Up @@ -168,17 +170,26 @@ public function actionGetEditScreen()

$view = Craft::$app->getView();

/** @var ElementTypeProcessorInterface $processor */
$processor = Plugin::getInstance()->bulkEdit->getElementTypeProcessor($elementType);
$elementPlaceholder = $processor::getMockElement($elementIds, [
'siteId' => $siteId
]);

// We've gotta register any asset bundles - this won't actually be rendered
foreach ($fieldModels as $fieldModel) {
$view->renderPageTemplate('_includes/field', [
'field' => $fieldModel,
'static' => true,
'element' => $elementPlaceholder,
'required' => false
]);
}

$modalHtml = $view->renderTemplate('venveo-bulk-edit/elementactions/BulkEdit/_edit', [
'fields' => $fieldModels,
'elementType' => $elementType,
'elementPlaceholder' => $elementPlaceholder,
'elementIds' => $elementIds,
'fieldData' => $enabledFields,
'site' => $site
Expand Down
14 changes: 13 additions & 1 deletion src/elements/processors/AssetProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

namespace venveo\bulkedit\elements\processors;

use Craft;
use craft\base\Element;
use craft\elements\Asset;
use craft\helpers\ArrayHelper;
use craft\records\FieldLayout;
Expand Down Expand Up @@ -39,7 +41,7 @@ public static function getLayoutsFromElementIds($elementIds): array
*/
public static function getType(): string
{
return get_class(new Asset);
return Asset::class;
}

/**
Expand All @@ -52,4 +54,14 @@ public static function hasPermission($elementIds, User $user): bool
{
return $user->checkPermission(Plugin::PERMISSION_BULKEDIT_ASSETS);
}

public static function getMockElement($elementIds = [], $params = []): Element
{
$asset = Craft::$app->assets->getAssetById($elementIds[0]);
/** @var Asset $elementPlaceholder */
$elementPlaceholder = Craft::createObject(static::getType(), $params);
// Field availability is determined by volume ID
$elementPlaceholder->volumeId = $asset->volumeId;
return $elementPlaceholder;
}
}
14 changes: 13 additions & 1 deletion src/elements/processors/CategoryProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

namespace venveo\bulkedit\elements\processors;

use Craft;
use craft\base\Element;
use craft\elements\Category;
use craft\helpers\ArrayHelper;
use craft\records\CategoryGroup;
Expand Down Expand Up @@ -48,7 +50,7 @@ public static function getLayoutsFromElementIds($elementIds): array
*/
public static function getType(): string
{
return get_class(new Category);
return Category::class;
}

/**
Expand All @@ -61,4 +63,14 @@ public static function hasPermission($elementIds, User $user): bool
{
return $user->checkPermission(Plugin::PERMISSION_BULKEDIT_CATEGORIES);
}

public static function getMockElement($elementIds = [], $params = []): Element
{
$category = Craft::$app->categories->getCategoryById($elementIds[0]);
/** @var Category $elementPlaceholder */
$elementPlaceholder = Craft::createObject(static::getType(), $params);
// Field availability is determined by volume ID
$elementPlaceholder->groupId = $category->groupId;
return $elementPlaceholder;
}
}
37 changes: 36 additions & 1 deletion src/elements/processors/EntryProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@

namespace venveo\bulkedit\elements\processors;

use Craft;
use craft\base\Element;
use craft\elements\Entry;
use craft\records\FieldLayout;
use craft\web\User;
use venveo\bulkedit\base\AbstractElementTypeProcessor;
use venveo\bulkedit\Plugin;
use venveo\bulkedit\services\BulkEdit;

class EntryProcessor extends AbstractElementTypeProcessor
{
Expand Down Expand Up @@ -36,7 +39,7 @@ public static function getLayoutsFromElementIds($elementIds): array
*/
public static function getType(): string
{
return get_class(new Entry);
return Entry::class;
}

/**
Expand All @@ -49,4 +52,36 @@ public static function hasPermission($elementIds, User $user): bool
{
return $user->checkPermission(Plugin::PERMISSION_BULKEDIT_ENTRIES);
}

/**
* @return array
*/
public static function getEditableAttributes(): array {
// return [
// [
// 'name' => 'Title',
// 'handle' => 'title',
// 'strategies' => [
// BulkEdit::STRATEGY_REPLACE
// ]
// ]
// ];
return [];
}

/**
* @param array $elementIds
* @param array $params
* @return Element
* @throws \yii\base\InvalidConfigException
*/
public static function getMockElement($elementIds = [], $params = []): Element
{
$templateEntry = Craft::$app->entries->getEntryById($elementIds[0]);
/** @var Entry $entry */
$entry = Craft::createObject(self::getType(), $params);
$entry->typeId = $templateEntry->typeId;
$entry->sectionId = $templateEntry->sectionId;
return $entry;
}
}
15 changes: 14 additions & 1 deletion src/elements/processors/ProductProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

namespace venveo\bulkedit\elements\processors;

use Craft;
use craft\base\Element;
use craft\commerce\records\Product;
use craft\commerce\records\ProductType;
use craft\helpers\ArrayHelper;
Expand Down Expand Up @@ -48,7 +50,7 @@ public static function getLayoutsFromElementIds($elementIds): array
*/
public static function getType(): string
{
return get_class(new \craft\commerce\elements\Product);
return \craft\commerce\elements\Product::class;
}

/**
Expand All @@ -61,4 +63,15 @@ public static function hasPermission($elementIds, User $user): bool
{
return $user->checkPermission(Plugin::PERMISSION_BULKEDIT_PRODUCTS);
}

public static function getMockElement($elementIds = [], $params = []): Element
{
/** @var \craft\commerce\elements\Product $product */
$product = \Craft::$app->elements->getElementById($elementIds[0], \craft\commerce\elements\Product::class);
/** @var \craft\commerce\elements\Product $elementPlaceholder */
$elementPlaceholder = Craft::createObject(static::getType(), $params);
// Field availability is determined by volume ID
$elementPlaceholder->typeId = $product->typeId;
return $elementPlaceholder;
}
}
2 changes: 1 addition & 1 deletion src/elements/processors/UserProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public static function getLayoutsFromElementIds($elementIds): array
*/
public static function getType(): string
{
return get_class(new User);
return User::class;
}

/**
Expand Down
21 changes: 2 additions & 19 deletions src/fields/processors/PlainTextProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use craft\fields\Table;
use craft\fields\Url;
use craft\redactor\Field as RedactorField;
use fruitstudios\linkit\fields\LinkitField;
use venveo\bulkedit\base\AbstractFieldProcessor;
use venveo\bulkedit\services\BulkEdit;

Expand All @@ -27,25 +28,7 @@ class PlainTextProcessor extends AbstractFieldProcessor
*/
public static function getSupportedFields(): array
{
$fields = [
PlainText::class,
Color::class,
Checkboxes::class,
Dropdown::class,
Date::class,
Table::class,
RadioButtons::class,
Lightswitch::class,
Url::class,
Email::class,
MultiSelect::class
];

if (Craft::$app->plugins->isPluginInstalled('redactor')) {
$fields[] = RedactorField::class;
}

return $fields;
return Craft::$app->fields->getAllFieldTypes();
}

/**
Expand Down
4 changes: 1 addition & 3 deletions src/fields/processors/RelationFieldProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,9 @@ class RelationFieldProcessor extends AbstractFieldProcessor
*/
public static function getSupportedFields(): array
{
$fields = [
return [
BaseRelationField::class
];

return $fields;
}

/**
Expand Down
25 changes: 25 additions & 0 deletions src/models/AttributeWrapper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php


namespace venveo\bulkedit\models;

use craft\base\Model;
use craft\records\User;
use yii\db\ActiveQueryInterface;

/**
* @property int|null ownerId
* @property integer siteId
* @property string elementIds
* @property ActiveQueryInterface $site
* @property User $owner
* @property ActiveQueryInterface $historyItems
* @property string fieldIds
* @property integer id
*/
class AttributeWrapper extends Model
{
public $handle;
public $name;
public $strategy;
}
Loading

0 comments on commit 7c425e2

Please sign in to comment.