From 5c1eb468577f4d3e4aa25aab190a5e4860a2a7d7 Mon Sep 17 00:00:00 2001 From: Yuriy Bakhtin Date: Fri, 20 Oct 2023 14:54:01 +0200 Subject: [PATCH 1/3] Allow deleting of uploaded file from template element --- docs/CHANGELOG.md | 1 + modules/template/models/FileContent.php | 5 +++++ modules/template/widgets/views/fileContentFormFields.php | 1 + 3 files changed, 7 insertions(+) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 0e153106..db165bab 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -7,6 +7,7 @@ Changelog - Fix #291: Fix broken URL in email footer - Fix #293: Initialize module content class - Enh #301: Tests for `next` version +- Enh #318: Allow deleting of uploaded file from template element 1.9.3 (June 13, 2023) --------------------- diff --git a/modules/template/models/FileContent.php b/modules/template/models/FileContent.php index 00d4c28b..6e8aa876 100644 --- a/modules/template/models/FileContent.php +++ b/modules/template/models/FileContent.php @@ -115,4 +115,9 @@ public function renderForm($form) ]); } + public function canEdit($user = null): bool + { + return PagePermission::canEdit(); + } + } diff --git a/modules/template/widgets/views/fileContentFormFields.php b/modules/template/widgets/views/fileContentFormFields.php index 11fd3d8f..42921f97 100644 --- a/modules/template/widgets/views/fileContentFormFields.php +++ b/modules/template/widgets/views/fileContentFormFields.php @@ -32,6 +32,7 @@ 'id' => $id . '-preview', 'popoverPosition' => 'top', 'items' => [$model->getFile()], + 'edit' => true, 'options' => ['style' => 'display:block;margin-left:150px']]) ?> $id . '-progress', 'options' => ['style' => 'display:block;margin-left:150px;width:500px']]) ?> From 58d23cb8cc32ae1569e527576e46cfc7c3fa25ee Mon Sep 17 00:00:00 2001 From: Yuriy Bakhtin Date: Mon, 23 Oct 2023 08:57:16 +0200 Subject: [PATCH 2/3] Additional check for empty template element "File content" --- modules/template/models/FileContent.php | 7 ++++++- modules/template/models/OwnerContent.php | 3 ++- modules/template/models/TemplateContentActiveRecord.php | 5 +++++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/modules/template/models/FileContent.php b/modules/template/models/FileContent.php index 6e8aa876..ff5a4bf8 100644 --- a/modules/template/models/FileContent.php +++ b/modules/template/models/FileContent.php @@ -120,4 +120,9 @@ public function canEdit($user = null): bool return PagePermission::canEdit(); } -} + public function isEmpty(): bool + { + return !$this->hasFile(); + } + + } diff --git a/modules/template/models/OwnerContent.php b/modules/template/models/OwnerContent.php index 40127967..2a65cd7e 100644 --- a/modules/template/models/OwnerContent.php +++ b/modules/template/models/OwnerContent.php @@ -191,7 +191,8 @@ public function renderEmpty($options = []) public function isEmpty() { - return $this->getInstance() == null; + $instance = $this->getInstance(); + return $instance === null || $instance->isEmpty(); } public function isDefault() diff --git a/modules/template/models/TemplateContentActiveRecord.php b/modules/template/models/TemplateContentActiveRecord.php index da0d9f73..ea13bca3 100644 --- a/modules/template/models/TemplateContentActiveRecord.php +++ b/modules/template/models/TemplateContentActiveRecord.php @@ -320,4 +320,9 @@ public function getOption($options, $key, $default = null) return isset($options[$key]) ? strval($options[$key]) : $default; } + public function isEmpty(): bool + { + return false; + } + } From 15f89f7a04b7a71319e13159d11052246721ef10 Mon Sep 17 00:00:00 2001 From: Yuriy Bakhtin Date: Mon, 23 Oct 2023 15:03:11 +0200 Subject: [PATCH 3/3] Allow resetting of file/image content to default --- docs/CHANGELOG.md | 2 +- .../controllers/OwnerContentController.php | 67 ++++++++++++++---- ...b.custom_pages.template.TemplateElement.js | 6 +- .../js/humhub.custom_pages.template.js | 34 ++++++++-- .../template/widgets/DeleteContentButton.php | 68 +++++++++++++++++++ .../widgets/views/deleteContentButton.php | 21 ++++++ .../widgets/views/fileContentFormFields.php | 65 ++++++++++-------- .../widgets/views/imageContentFormFields.php | 32 +++++---- .../widgets/views/templateElementAdminRow.php | 4 +- 9 files changed, 229 insertions(+), 70 deletions(-) create mode 100644 modules/template/widgets/DeleteContentButton.php create mode 100644 modules/template/widgets/views/deleteContentButton.php diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index db165bab..2ba37d0d 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -7,7 +7,7 @@ Changelog - Fix #291: Fix broken URL in email footer - Fix #293: Initialize module content class - Enh #301: Tests for `next` version -- Enh #318: Allow deleting of uploaded file from template element +- Enh #318: Allow resetting of file/image content to default 1.9.3 (June 13, 2023) --------------------- diff --git a/modules/template/controllers/OwnerContentController.php b/modules/template/controllers/OwnerContentController.php index a3b65f92..241f08f4 100644 --- a/modules/template/controllers/OwnerContentController.php +++ b/modules/template/controllers/OwnerContentController.php @@ -2,6 +2,8 @@ namespace humhub\modules\custom_pages\modules\template\controllers; +use humhub\modules\content\interfaces\ContentOwner; +use humhub\modules\custom_pages\modules\template\models\OwnerContent; use Yii; use humhub\modules\custom_pages\modules\template\widgets\EditElementModal; use humhub\modules\custom_pages\modules\template\models\OwnerContentVariable; @@ -11,6 +13,8 @@ use humhub\modules\custom_pages\modules\template\models\forms\EditMultipleElementsForm; use humhub\modules\custom_pages\modules\template\widgets\EditMultipleElementsModal; use yii\base\Response; +use yii\web\HttpException; +use yii\web\NotFoundHttpException; /** * This controller is used to manage OwnerContent instances for TemplateContentOwner. @@ -52,7 +56,7 @@ public function behaviors() * Edits the content of a specific OwnerContent for the given TemplateContentOwner. * * @return Response - * @throws \yii\web\HttpException + * @throws HttpException */ public function actionEdit($ownerModel, $ownerId, $name) { @@ -85,33 +89,24 @@ public function actionEdit($ownerModel, $ownerId, $name) * Used to delete owner content models. * * @return Response - * @throws \yii\web\HttpException + * @throws HttpException */ public function actionDelete() { + $this->forcePostRequest(); + $ownerModel = Yii::$app->request->post('ownerModel'); $ownerId = Yii::$app->request->post('ownerId'); $name = Yii::$app->request->post('name'); if (!$ownerModel || !$ownerId || !$name) { - throw new \yii\web\HttpException(400, Yii::t('CustomPagesModule.controllers_TemplateController', 'Invalid request data!')); + throw new HttpException(400, Yii::t('CustomPagesModule.controllers_TemplateController', 'Invalid request data!')); } - $this->forcePostRequest(); - $form = new EditOwnerContentForm(); $form->setElementData($ownerModel, $ownerId, $name); - // Do not allow the deletion of default content this is only allowed in admin controller. - if ($form->ownerContent->isDefault()) { - throw new \yii\web\HttpException(403, Yii::t('CustomPagesModule.controllers_TemplateController', 'You are not allowed to delete default content!')); - } else if ($form->ownerContent->isEmpty()) { - throw new \yii\web\HttpException(400, Yii::t('CustomPagesModule.controllers_TemplateController', 'Empty content elements cannot be delted!')); - } - - TemplateCache::flushByOwnerContent($form->ownerContent); - - $form->ownerContent->delete(); + $this->deleteOwnerContent($form->ownerContent); // Set our original owner for this element block $variable = new OwnerContentVariable(['ownerContent' => $form->element->getDefaultContent(true), 'options' => [ @@ -122,6 +117,48 @@ public function actionDelete() return $this->getJsonEditElementResult(true, $variable->render(true)); } + /** + * Used to delete owner content models by Content. + * + * @return Response + * @throws HttpException + */ + public function actionDeleteByContent() + { + $this->forcePostRequest(); + + $contentModel = Yii::$app->request->post('contentModel'); + $contentId = Yii::$app->request->post('contentId'); + + if (!$contentModel || !$contentId) { + throw new HttpException(400, Yii::t('CustomPagesModule.controllers_TemplateController', 'Invalid request data!')); + } + + $ownerContent = OwnerContent::findByContent($contentModel, $contentId); + + $this->deleteOwnerContent($ownerContent); + + return $this->asJson(['success' => true]); + } + + private function deleteOwnerContent($ownerContent) + { + if (!$ownerContent instanceof OwnerContent) { + throw new NotFoundHttpException(); + } + // Do not allow the deletion of default content this is only allowed in admin controller. + if ($ownerContent->isDefault()) { + throw new HttpException(403, Yii::t('CustomPagesModule.controllers_TemplateController', 'You are not allowed to delete default content!')); + } + if ($ownerContent->isEmpty()) { + throw new HttpException(400, Yii::t('CustomPagesModule.controllers_TemplateController', 'Empty content elements cannot be deleted!')); + } + + TemplateCache::flushByOwnerContent($ownerContent); + + return $ownerContent->delete(); + } + /** * Action for editing all owner content models for a given template instance in one view. * diff --git a/modules/template/resources/js/humhub.custom_pages.template.TemplateElement.js b/modules/template/resources/js/humhub.custom_pages.template.TemplateElement.js index 81b05e76..6fdacde7 100644 --- a/modules/template/resources/js/humhub.custom_pages.template.TemplateElement.js +++ b/modules/template/resources/js/humhub.custom_pages.template.TemplateElement.js @@ -310,9 +310,9 @@ humhub.module('custom_pages.template.TemplateElement', function (module, require TemplateElement.template = { menu: '', - editButton: '', - deleteButton: '' + editButton: '', + deleteButton: '' }; module.export = TemplateElement; -}); \ No newline at end of file +}); diff --git a/modules/template/resources/js/humhub.custom_pages.template.js b/modules/template/resources/js/humhub.custom_pages.template.js index be4311ee..a4f0010f 100644 --- a/modules/template/resources/js/humhub.custom_pages.template.js +++ b/modules/template/resources/js/humhub.custom_pages.template.js @@ -2,6 +2,7 @@ humhub.module('custom_pages.template', function (module, require, $) { var object = require('util').object; var string = require('util').string; var Preview = require('file').Preview; + var client = require('client'); var ImagePreview = function(node, options) { Preview.call(this, node, options); @@ -29,7 +30,7 @@ humhub.module('custom_pages.template', function (module, require, $) { }; ImagePreview.template = { - file_image: '
  • ' + file_image: '
  • ' }; ImagePreview.prototype.getTemplate = function (file) { @@ -83,9 +84,32 @@ humhub.module('custom_pages.template', function (module, require, $) { $(document).off('.custom_pages'); }; + const deleteElementContent = function (evt) { + const btn = evt.$trigger; + const data = { + contentModel: btn.data('owner-content'), + contentId: btn.data('owner-content-id'), + } + + client.post(evt, {data}).then(function (response) { + if (response.success) { + const preview = $('#' + btn.data('preview-id')); + if (preview.length) { + preview.fadeOut(400, function () { + $(this).find('.file-preview-item').remove(); + }); + } + btn.remove(); + } + }).catch(function (e) { + module.log.error(e, true); + }); + } + module.export({ - init: init, - unload: unload, - ImagePreview: ImagePreview + init, + unload, + ImagePreview, + deleteElementContent }); -}); \ No newline at end of file +}); diff --git a/modules/template/widgets/DeleteContentButton.php b/modules/template/widgets/DeleteContentButton.php new file mode 100644 index 00000000..1b292bee --- /dev/null +++ b/modules/template/widgets/DeleteContentButton.php @@ -0,0 +1,68 @@ +canDelete(); + } + + /** + * @inheritdoc + */ + public function run() + { + return $this->render('deleteContentButton', [ + 'url' => Url::to(['/custom_pages/template/owner-content/delete-by-content']), + 'options' => $this->getOptions() + ]); + } + + private function canDelete(): bool + { + if (!$this->model instanceof TemplateContentActiveRecord) { + return false; + } + + if ($this->model->isNewRecord) { + return false; + } + + $ownerContent = OwnerContent::findByContent($this->model); + + if (!$ownerContent || $ownerContent->isDefault() || $ownerContent->isEmpty()) { + return false; + } + + return PagePermission::canEdit(); + } + + private function getOptions(): array + { + return ['data' => [ + 'placement' => 'bottom', + 'owner-content' => get_class($this->model), + 'owner-content-id' => $this->model->id, + 'preview-id' => $this->previewId + ]]; + } +} diff --git a/modules/template/widgets/views/deleteContentButton.php b/modules/template/widgets/views/deleteContentButton.php new file mode 100644 index 00000000..b5b3e4e2 --- /dev/null +++ b/modules/template/widgets/views/deleteContentButton.php @@ -0,0 +1,21 @@ + +action('custom_pages.template.deleteElementContent', $url) + ->icon('times') + ->tooltip(Yii::t('CustomPagesModule.base', 'Reset the content to default value')) + ->options($options) + ->confirm(Yii::t('CustomPagesModule.modules_template_controller_OwnerContentController', 'Confirm content deletion'), + Yii::t('CustomPagesModule.modules_template_widgets_views_confirmDeletionModal', 'Do you really want to delete this content?'), + Yii::t('CustomPagesModule.base', 'Delete')) +?> diff --git a/modules/template/widgets/views/fileContentFormFields.php b/modules/template/widgets/views/fileContentFormFields.php index 42921f97..66ec9159 100644 --- a/modules/template/widgets/views/fileContentFormFields.php +++ b/modules/template/widgets/views/fileContentFormFields.php @@ -1,10 +1,13 @@ id; ?> @@ -12,29 +15,31 @@ field($model, 'file_guid')->hiddenInput(['class' => 'file-guid'])->label(false); ?>
    - - 'btn-primary', - 'model' => $model, - 'single' => true, - 'label' => true, - 'attribute' => 'file_guid', - 'dropZone' => '#' . $id, - 'tooltip' => false, - 'preview' => '#' . $id . '-preview', - 'progress' => '#' . $id . '-progress', - 'buttonOptions' => ['style' => 'float:left;'] - ])?> - - - $id . '-preview', - 'popoverPosition' => 'top', - 'items' => [$model->getFile()], - 'edit' => true, - 'options' => ['style' => 'display:block;margin-left:150px']]) ?> - - $id . '-progress', 'options' => ['style' => 'display:block;margin-left:150px;width:500px']]) ?> - +
    +
    + 'btn-primary', + 'model' => $model, + 'single' => true, + 'label' => true, + 'attribute' => 'file_guid', + 'dropZone' => '#' . $id, + 'tooltip' => false, + 'preview' => '#' . $id . '-preview', + 'progress' => '#' . $id . '-progress' + ]) ?> + $model, + 'previewId' => $id . '-preview' + ]) ?> +
    +
    + $id . '-preview', + 'popoverPosition' => 'top', + 'items' => [$model->getFile()] + ]) ?> + $id . '-progress']) ?> +
    +
    diff --git a/modules/template/widgets/views/imageContentFormFields.php b/modules/template/widgets/views/imageContentFormFields.php index 9e79721a..66400e2c 100644 --- a/modules/template/widgets/views/imageContentFormFields.php +++ b/modules/template/widgets/views/imageContentFormFields.php @@ -1,12 +1,15 @@ definition->is_default; @@ -18,23 +21,24 @@
    - 'btn-primary', 'model' => $model, 'single' => true, + 'label' => true, 'attribute' => 'file_guid', 'dropZone' => '#' . $id, 'tooltip' => Yii::t('CustomPagesModule.base', 'Upload image'), 'preview' => '#' . $id . '-preview', 'progress' => '#' . $id . '-progress' - ])?> - -
    -
    + ]) ?> + $model, + 'previewId' => $id . '-preview' + ]) ?>
    - $id . '-progress', 'options' => ['style' => 'width:500px']]) ?> - $id . '-progress', 'options' => ['style' => 'width:500px']]) ?> + $id . '-preview', 'items' => [$model->getFile()], 'jsWidget' => 'custom_pages.template.ImagePreview', diff --git a/modules/template/widgets/views/templateElementAdminRow.php b/modules/template/widgets/views/templateElementAdminRow.php index 0339bc46..3047c213 100644 --- a/modules/template/widgets/views/templateElementAdminRow.php +++ b/modules/template/widgets/views/templateElementAdminRow.php @@ -29,7 +29,7 @@ - + + class="btn btn-danger btn-icon-only btn-xs tt" href="#">