diff --git a/src/actions/AddComponent.php b/src/actions/AddComponent.php
index 40534c7..134df7b 100644
--- a/src/actions/AddComponent.php
+++ b/src/actions/AddComponent.php
@@ -16,24 +16,17 @@ public function handle(
string $type
): Component {
// Check if we can be added here
- if ($path) {
- $parentId = last(explode('/', $path));
- if (! empty($parentId)) {
- $parent = Component::find()->where([
- 'id' => $parentId,
- 'elementId' => $elementId,
- 'fieldId' => $fieldId,
- ])->one();
- if (! $parent->getType()->getSlotDefinition($slot)->allows($type)) {
- throw new \RuntimeException('Not allowed here');
- }
- }
+ $parent = (new GetParentFromPath)->handle($elementId, $fieldId, $path);
+ if ($parent && ! $parent->getType()->getSlotDefinition($slot)->allows($type)) {
+ throw new \RuntimeException('Not allowed here');
}
+ // Create the data
$componentData = new ComponentData;
$componentData->type = $type;
$componentData->save();
+ // Create the component
$component = new Component;
$component->elementId = $elementId;
$component->fieldId = $fieldId;
@@ -44,6 +37,7 @@ public function handle(
$component->sortOrder = $sortOrder;
$component->save();
+ // Refresh the instance so we have the correct data reference
$component->refresh();
return $component;
diff --git a/src/actions/GetParentFromPath.php b/src/actions/GetParentFromPath.php
new file mode 100644
index 0000000..0f87df7
--- /dev/null
+++ b/src/actions/GetParentFromPath.php
@@ -0,0 +1,19 @@
+ $elementId,
+ 'fieldId' => $fieldId,
+ 'id' => $parentId,
+ ]) : null;
+ }
+}
diff --git a/src/actions/MakeModelFromArray.php b/src/actions/MakeModelFromArray.php
index a92d656..4697848 100644
--- a/src/actions/MakeModelFromArray.php
+++ b/src/actions/MakeModelFromArray.php
@@ -6,6 +6,21 @@
use markhuot\keystone\db\ActiveRecord;
use yii\base\ModelEvent;
+/**
+ * Recursively create models from an array.
+ *
+ * ```php
+ * (new MakeModelFromArray)->handle(Component::class, ['id' => 123], errorOnMissing: true, createOnMissing: false)
+ * ```
+ *
+ * That would search for component 123 and error out if it could not be found.
+ *
+ * ```php
+ * (new MakeModelFromArray)->handle(PostData::class, ['foo' => 'bar'], errorOnMissing: false, createOnMissing: true)
+ * ```
+ *
+ * That would instantiate a new PostData class with the `foo` property set to `bar`.
+ */
class MakeModelFromArray
{
/**
diff --git a/src/actions/MapExpandedAttributeValue.php b/src/actions/MapExpandedAttributeValue.php
index b668efe..7da5558 100644
--- a/src/actions/MapExpandedAttributeValue.php
+++ b/src/actions/MapExpandedAttributeValue.php
@@ -2,6 +2,21 @@
namespace markhuot\keystone\actions;
+/**
+ * Takes an array of either CSS "shorthand" or "expanded" values and returns a css-ish
+ * representation of them.
+ *
+ * For example, given `->handle(['useExpanded' => false, 'shorthand' => 3], 'margin')` you
+ * would end up with `['margin' => 3]`.
+ *
+ * If you `useExpanded` like this, `->handle(['useExpanded' => true, 'expanded' => ['top' => 3]], 'margin')`
+ * then you would end up with `['margin-top' => 3]`.
+ *
+ * Notice that the `$property` attribute is automatically converted to `{$property}-top` or `{$property}-left`
+ * for the expanded values. If you need to customize that you can pass in an `$expandedProperty` attribute
+ * with `&` as a placeholder for the direction. E.g., `->handle([...], 'border', 'border-&-width')` would
+ * return `['border-top-width' => 3]` if `'top' => 3` was passed.
+ */
class MapExpandedAttributeValue
{
public function handle(?array $value, string $property, string $expandedProperty = null)
diff --git a/src/actions/MoveComponent.php b/src/actions/MoveComponent.php
index 3a92b9c..bff29d3 100644
--- a/src/actions/MoveComponent.php
+++ b/src/actions/MoveComponent.php
@@ -2,18 +2,19 @@
namespace markhuot\keystone\actions;
+use markhuot\keystone\enums\MoveComponentPosition;
use markhuot\keystone\models\Component;
use yii\db\Expression;
class MoveComponent
{
- public function handle(Component $source, Component $target, string $position, string $slotName = null)
+ public function handle(Component $source, Component $target, MoveComponentPosition $position, string $slotName = null)
{
- if ($position === 'above' || $position === 'below') {
+ if ($position === MoveComponentPosition::BEFORE || $position === MoveComponentPosition::AFTER) {
$this->handleAboveOrBelow($source, $target, $position);
}
- if ($position === 'beforeend') {
+ if ($position === MoveComponentPosition::BEFOREEND) {
$this->handleBeforeEnd($source, $target, $slotName);
}
}
@@ -39,7 +40,7 @@ public function handleAboveOrBelow(Component $source, Component $target, string
$target->refresh();
// make room for the insertion
- if ($position === 'above') {
+ if ($position === MoveComponentPosition::BEFORE) {
Component::updateAll([
'sortOrder' => new Expression('sortOrder + 1'),
], ['and',
@@ -50,7 +51,7 @@ public function handleAboveOrBelow(Component $source, Component $target, string
['>=', 'sortOrder', $target->sortOrder],
]);
}
- if ($position === 'below') {
+ if ($position === MoveComponentPosition::AFTER) {
Component::updateAll([
'sortOrder' => new Expression('sortOrder + 1'),
], ['and',
@@ -70,7 +71,7 @@ public function handleAboveOrBelow(Component $source, Component $target, string
// move the source to the target
$source->path = $target->path;
$source->slot = $target->slot;
- $source->sortOrder = $position == 'above' ? $target->sortOrder - 1 : $target->sortOrder + 1;
+ $source->sortOrder = $position == MoveComponentPosition::BEFORE ? $target->sortOrder - 1 : $target->sortOrder + 1;
$source->save();
// move any children of the source
diff --git a/src/actions/NormalizeFieldDataForComponent.php b/src/actions/NormalizeFieldDataForComponent.php
index e7d509b..45e64d3 100644
--- a/src/actions/NormalizeFieldDataForComponent.php
+++ b/src/actions/NormalizeFieldDataForComponent.php
@@ -26,7 +26,7 @@ public function handle(mixed $value, string $handle)
// If the field is editable, return an editable div
if ($field?->getBehavior('inlineEdit')) {
- if ($field->isEditableInPreview() && (Craft::$app->getRequest()->isPreview() ?? false)) {
+ if ($field->isEditableInLivePreview() && Craft::$app->getRequest()->getQueryParam('x-craft-live-preview') !== null) {
return new InlineEditData($this->component, $field, $value);
}
}
diff --git a/src/behaviors/InlineEditBehavior.php b/src/behaviors/InlineEditBehavior.php
index 02bdccd..a8cd112 100644
--- a/src/behaviors/InlineEditBehavior.php
+++ b/src/behaviors/InlineEditBehavior.php
@@ -6,15 +6,15 @@
class InlineEditBehavior extends Behavior
{
- protected bool $editableInPreview = false;
+ protected bool $editableInLivePreview = false;
- public function setEditableInPreview(bool $editable=true)
+ public function setEditableInLivePreview(bool $editable=true)
{
- $this->editableInPreview = $editable;
+ $this->editableInLivePreview = $editable;
}
- public function isEditableInPreview()
+ public function isEditableInLivePreview()
{
- return $this->editableInPreview;
+ return $this->editableInLivePreview;
}
}
diff --git a/src/controllers/ComponentsController.php b/src/controllers/ComponentsController.php
index 4958bb7..f0d4ef3 100644
--- a/src/controllers/ComponentsController.php
+++ b/src/controllers/ComponentsController.php
@@ -8,6 +8,7 @@
use markhuot\keystone\actions\DeleteComponent;
use markhuot\keystone\actions\EditComponentData;
use markhuot\keystone\actions\GetComponentType;
+use markhuot\keystone\actions\GetParentFromPath;
use markhuot\keystone\actions\MoveComponent;
use markhuot\keystone\behaviors\BodyParamObjectBehavior;
use markhuot\keystone\models\Component;
@@ -29,8 +30,7 @@ public function actionAdd()
$path = $this->request->getQueryParam('path');
$slot = $this->request->getQueryParam('slot');
$sortOrder = $this->request->getRequiredQueryParam('sortOrder');
- $parentId = last(explode('/', $path));
- $parent = $parentId ? Component::findOne(['elementId' => $elementId, 'fieldId' => $fieldId, 'id' => $parentId]) : null;
+ $parent = (new GetParentFromPath)->handle($elementId, $fieldId, $path);
return $this->asCpScreen()
->title('Add component')
diff --git a/src/enums/MoveComponentPosition.php b/src/enums/MoveComponentPosition.php
new file mode 100644
index 0000000..c0c9c8c
--- /dev/null
+++ b/src/enums/MoveComponentPosition.php
@@ -0,0 +1,10 @@
+