-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix drag and drop, better use of drafts
- Loading branch information
Showing
16 changed files
with
462 additions
and
80 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
<?php | ||
|
||
namespace markhuot\keystone\actions; | ||
|
||
use Craft; | ||
use craft\base\ElementInterface; | ||
use craft\helpers\DateTimeHelper; | ||
use craft\helpers\StringHelper; | ||
use markhuot\keystone\db\Table; | ||
use markhuot\keystone\fields\Keystone; | ||
use markhuot\keystone\models\Component; | ||
|
||
class DuplicateComponentTree | ||
{ | ||
static array $mapping = []; | ||
|
||
public function handle(ElementInterface $source, ElementInterface $destination, Keystone $field) | ||
{ | ||
$query = Component::find()->where([ | ||
'elementId' => $source->id, | ||
'fieldId' => $field->id, | ||
])->orderBy(['path' => 'asc']); | ||
|
||
foreach ($query->each() as $component) { | ||
$duplicate = new Component; | ||
$duplicate->id = $component->id; | ||
$duplicate->elementId = $destination->id; | ||
$duplicate->fieldId = $field->id; | ||
$duplicate->dataId = $component->dataId; | ||
$duplicate->sortOrder = $component->sortOrder; | ||
$duplicate->path = $this->remapPath($component->path); | ||
$duplicate->level = $component->level; | ||
$duplicate->slot = $component->slot; | ||
$duplicate->dateCreated = DateTimeHelper::now(); | ||
$duplicate->dateUpdated = DateTimeHelper::now(); | ||
$duplicate->uid = StringHelper::UUID(); | ||
$duplicate->save(); | ||
|
||
static::$mapping[$component->id] = $duplicate->id; | ||
} | ||
|
||
// I'd love to use INSERT INTO components (elementId, fieldId, ...) SELECT * FROM components WHERE elementId= and fieldId= | ||
// but Craft breaks this because they subclass the db->createCommand() and don't allow you to pass | ||
// a query as the second parameter. They look for $columns[dateCreated] on that second param which | ||
// works when setting raw values but not if a query is passed because it tries to $query[dateCreated] | ||
// and Query isn't array-accessible. | ||
// | ||
// $query = Component::find()->select(['fieldId', 'componentId', 'sortOrder', 'path', 'level', 'slot'])->where([ | ||
// 'elementId' => $source->id, | ||
// 'fieldId' => $field->id, | ||
// ]); | ||
// $params = [ | ||
// 'elementId' => $source->id, | ||
// 'fieldId' => $field->id, | ||
// ]; | ||
// Craft::$app->db->createCommand(Craft::$app->db->getQueryBuilder()->insert(Table::COMPONENTS, $query, $params))->execute(); | ||
// Craft::$app->db->createCommand()->insert(Table::COMPONENTS, $query); | ||
} | ||
|
||
protected function remapPath(?string $path) | ||
{ | ||
if ($path === null) { | ||
return null; | ||
} | ||
|
||
return collect(explode('/', $path)) | ||
->map(function ($segment) use ($path) { | ||
if (! isset(static::$mapping[$segment])) { | ||
throw new \RuntimeException('Could not remap ' . $path . ' because ' . $segment . ' could not be found'); | ||
} | ||
|
||
return static::$mapping[$segment]; | ||
}) | ||
->join('/'); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<?php | ||
|
||
namespace markhuot\keystone\actions; | ||
|
||
use markhuot\keystone\models\Component; | ||
|
||
class EditComponentData | ||
{ | ||
public function handle(Component $component, array $data) | ||
{ | ||
$component->data->merge($data); | ||
$component->data->save(); | ||
$component->refresh(); | ||
|
||
return $component; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
<?php | ||
|
||
namespace markhuot\keystone\actions; | ||
|
||
use markhuot\keystone\models\Component; | ||
use yii\db\Expression; | ||
|
||
class MoveComponent | ||
{ | ||
public function handle(Component $source, Component $target, string $position) | ||
{ | ||
// remove ourselves from the list | ||
Component::updateAll([ | ||
'sortOrder' => new Expression('sortOrder - 1') | ||
], ['and', | ||
['=', 'elementId', $source->elementId], | ||
['=', 'fieldId', $source->fieldId], | ||
['path' => $source->path], | ||
['>', 'sortOrder', $source->sortOrder] | ||
]); | ||
|
||
// Refresh our target to get the updated/correct sortOrder | ||
$target->refresh(); | ||
|
||
// make room for the insertion | ||
if ($position === 'above') { | ||
Component::updateAll([ | ||
'sortOrder' => new Expression('sortOrder + 1') | ||
], ['and', | ||
['=', 'elementId', $target->elementId], | ||
['=', 'fieldId', $target->fieldId], | ||
['path' => $target->path], | ||
['>=', 'sortOrder', $target->sortOrder] | ||
]); | ||
} | ||
if ($position === 'below') | ||
{ | ||
Component::updateAll([ | ||
'sortOrder' => new Expression('sortOrder + 1') | ||
], ['and', | ||
['=', 'elementId', $target->elementId], | ||
['=', 'fieldId', $target->fieldId], | ||
['path' => $target->path], | ||
['>', 'sortOrder', $target->sortOrder] | ||
]); | ||
} | ||
|
||
// Refresh the target again, in case it changed, so we're setting the correct | ||
// sort order | ||
$target->refresh(); | ||
$source->refresh(); | ||
|
||
$source->path = $target->path; | ||
$source->sortOrder = $position == 'above' ? $target->sortOrder - 1 : $target->sortOrder + 1; | ||
$source->save(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.