Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow deleting of uploaded file from template element #302

Merged
merged 3 commits into from
Oct 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 resetting of file/image content to default

1.9.3 (June 13, 2023)
---------------------
Expand Down
67 changes: 52 additions & 15 deletions modules/template/controllers/OwnerContentController.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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.
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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' => [
Expand All @@ -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.
*
Expand Down
12 changes: 11 additions & 1 deletion modules/template/models/FileContent.php
Original file line number Diff line number Diff line change
Expand Up @@ -115,4 +115,14 @@ public function renderForm($form)
]);
}

}
public function canEdit($user = null): bool
{
return PagePermission::canEdit();
}

public function isEmpty(): bool
{
return !$this->hasFile();
}

}
3 changes: 2 additions & 1 deletion modules/template/models/OwnerContent.php
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
5 changes: 5 additions & 0 deletions modules/template/models/TemplateContentActiveRecord.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -310,9 +310,9 @@ humhub.module('custom_pages.template.TemplateElement', function (module, require

TemplateElement.template = {
menu: '<div class="editMenu {cssClass}" style="display:none;"></div>',
editButton: '<a data-action-click="editAction" data-action-url="{url}" data-action-target="#{target}" class="template-menu-button btn btn-primary {btnSizeClass} tt" href="#"><i class="fa fa-pencil"></i></a>',
deleteButton: '<a data-action-click="deleteAction" data-action-url="{url}" data-action-target="#{target}" data-action-confirm="{confirmBody}" data-action-confirm-header="{confirmHeader}" data-action-confirm-text="{confirmText}" class="template-menu-button btn btn-danger {btnSizeClass} tt" href="#"><i class="fa fa-times"></i></a>'
editButton: '<a data-action-click="editAction" data-action-url="{url}" data-action-target="#{target}" class="template-menu-button btn btn-icon-only btn-primary {btnSizeClass} tt" href="#"><i class="fa fa-pencil"></i></a>',
deleteButton: '<a data-action-click="deleteAction" data-action-url="{url}" data-action-target="#{target}" data-action-confirm="{confirmBody}" data-action-confirm-header="{confirmHeader}" data-action-confirm-text="{confirmText}" class="template-menu-button btn btn-icon-only btn-danger {btnSizeClass} tt" href="#"><i class="fa fa-times"></i></a>'
};

module.export = TemplateElement;
});
});
34 changes: 29 additions & 5 deletions modules/template/resources/js/humhub.custom_pages.template.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -29,7 +30,7 @@ humhub.module('custom_pages.template', function (module, require, $) {
};

ImagePreview.template = {
file_image: '<li data-preview-guid="{guid}"><img src="{thumbnailUrl}" class="preview" /></li>'
file_image: '<li class="file-preview-item" data-preview-guid="{guid}"><img src="{thumbnailUrl}" class="preview" /></li>'
};

ImagePreview.prototype.getTemplate = function (file) {
Expand Down Expand Up @@ -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
});
});
});
68 changes: 68 additions & 0 deletions modules/template/widgets/DeleteContentButton.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?php
/**
* @link https://www.humhub.org/
* @copyright Copyright (c) HumHub GmbH & Co. KG
* @license https://www.humhub.com/licences
*/

namespace humhub\modules\custom_pages\modules\template\widgets;

use humhub\components\Widget;
use humhub\modules\custom_pages\modules\template\models\OwnerContent;
use humhub\modules\custom_pages\modules\template\models\PagePermission;
use humhub\modules\custom_pages\modules\template\models\TemplateContentActiveRecord;
use yii\helpers\Url;

class DeleteContentButton extends Widget
{
public ?TemplateContentActiveRecord $model = null;
public string $previewId = '';

/**
* @inheritdoc
*/
public function beforeRun()
{
return parent::beforeRun() && $this->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
]];
}
}
21 changes: 21 additions & 0 deletions modules/template/widgets/views/deleteContentButton.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php
/**
* @link https://www.humhub.org/
* @copyright Copyright (c) HumHub GmbH & Co. KG
* @license https://www.humhub.com/licences
*/

use humhub\widgets\Button;

/* @var string $url */
/* @var array $options */
?>
<?= Button::danger(Yii::t('CustomPagesModule.base', 'Delete'))
->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', '<strong>Confirm</strong> content deletion'),
Yii::t('CustomPagesModule.modules_template_widgets_views_confirmDeletionModal', 'Do you really want to delete this content?'),
Yii::t('CustomPagesModule.base', 'Delete'))
?>
64 changes: 35 additions & 29 deletions modules/template/widgets/views/fileContentFormFields.php
Original file line number Diff line number Diff line change
@@ -1,39 +1,45 @@
<?php
/* @var $model humhub\modules\custom_pages\modules\template\models\template\FileContent */
/* @var $form \humhub\modules\ui\form\widgets\ActiveForm */
use humhub\modules\custom_pages\modules\template\models\FileContent;
use humhub\modules\custom_pages\modules\template\widgets\DeleteContentButton;
use humhub\modules\file\widgets\FilePreview;
use humhub\modules\file\widgets\UploadButton;
use humhub\modules\file\widgets\UploadProgress;
use humhub\modules\ui\form\widgets\ActiveForm;

use yii\helpers\Url;

$uploadUrl = Url::to(['/file/file/upload']);
/* @var $model FileContent */
/* @var $form ActiveForm */

$id = 'fileContent-' . $model->id;
?>

<?= $form->field($model, 'file_guid')->hiddenInput(['class' => 'file-guid'])->label(false); ?>

<div id="<?= $id ?>" class="file-upload-container clearfix">

<?=
\humhub\modules\file\widgets\UploadButton::widget([
'cssButtonClass' => '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;']
])?>


<?= humhub\modules\file\widgets\FilePreview::widget([
'id' => $id . '-preview',
'popoverPosition' => 'top',
'items' => [$model->getFile()],
'options' => ['style' => 'display:block;margin-left:150px']]) ?>

<?= humhub\modules\file\widgets\UploadProgress::widget(['id' => $id . '-progress', 'options' => ['style' => 'display:block;margin-left:150px;width:500px']]) ?>

<div class="row">
<div class="col-md-4 uploadContainer">
<?= UploadButton::widget([
'cssButtonClass' => 'btn-primary',
'model' => $model,
'single' => true,
'label' => true,
'attribute' => 'file_guid',
'dropZone' => '#' . $id,
'tooltip' => false,
'preview' => '#' . $id . '-preview',
'progress' => '#' . $id . '-progress'
]) ?>
<?= DeleteContentButton::widget([
'model' => $model,
'previewId' => $id . '-preview'
]) ?>
</div>
<div class="col-md-8 previewContainer">
<?= FilePreview::widget([
'id' => $id . '-preview',
'popoverPosition' => 'top',
'items' => [$model->getFile()]
]) ?>
<?= UploadProgress::widget(['id' => $id . '-progress']) ?>
</div>
</div>
</div>
Loading