Merge branch 'cleanmaster' into modules
This commit is contained in:
@@ -28,6 +28,7 @@ use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
use Thelia\Core\Event\Document\DocumentCreateOrUpdateEvent;
|
||||
use Thelia\Core\Event\Document\DocumentDeleteEvent;
|
||||
use Thelia\Core\Event\Document\DocumentEvent;
|
||||
use Thelia\Core\Event\UpdateFilePositionEvent;
|
||||
use Thelia\Exception\ImageException;
|
||||
use Thelia\Model\ConfigQuery;
|
||||
use Thelia\Tools\FileManager;
|
||||
@@ -195,6 +196,11 @@ class Document extends BaseCachedFile implements EventSubscriberInterface
|
||||
$event->setModelDocument($event->getModelDocument());
|
||||
}
|
||||
|
||||
public function updatePosition(UpdateFilePositionEvent $event)
|
||||
{
|
||||
return $this->genericUpdatePosition($event->getQuery(), $event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Take care of deleting document in the database and file storage
|
||||
*
|
||||
@@ -218,6 +224,7 @@ class Document extends BaseCachedFile implements EventSubscriberInterface
|
||||
TheliaEvents::DOCUMENT_DELETE => array("deleteDocument", 128),
|
||||
TheliaEvents::DOCUMENT_SAVE => array("saveDocument", 128),
|
||||
TheliaEvents::DOCUMENT_UPDATE => array("updateDocument", 128),
|
||||
TheliaEvents::DOCUMENT_UPDATE_POSITION => array("updatePosition", 128),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
use Thelia\Core\Event\Image\ImageCreateOrUpdateEvent;
|
||||
use Thelia\Core\Event\Image\ImageDeleteEvent;
|
||||
use Thelia\Core\Event\Image\ImageEvent;
|
||||
use Thelia\Core\Event\UpdateImagePositionEvent;
|
||||
use Thelia\Core\Event\UpdateFilePositionEvent;
|
||||
use Thelia\Model\ConfigQuery;
|
||||
use Thelia\Tools\FileManager;
|
||||
use Thelia\Tools\URL;
|
||||
@@ -302,7 +302,7 @@ class Image extends BaseCachedFile implements EventSubscriberInterface
|
||||
$event->setModelImage($event->getModelImage());
|
||||
}
|
||||
|
||||
public function updatePosition(UpdateImagePositionEvent $event)
|
||||
public function updatePosition(UpdateFilePositionEvent $event)
|
||||
{
|
||||
return $this->genericUpdatePosition($event->getQuery(), $event);
|
||||
}
|
||||
|
||||
@@ -95,6 +95,11 @@
|
||||
<requirement key="parentType">.*</requirement>
|
||||
<requirement key="parentId">\d+</requirement>
|
||||
</route>
|
||||
<route id="admin.document.update-position" path="/admin/document/type/{parentType}/{parentId}/update-position">
|
||||
<default key="_controller">Thelia\Controller\Admin\FileController::updateDocumentPositionAction</default>
|
||||
<requirement key="parentType">.*</requirement>
|
||||
<requirement key="parentId">\d+</requirement>
|
||||
</route>
|
||||
<route id="admin.document.update.view" path="/admin/document/type/{parentType}/{documentId}/update" methods="get">
|
||||
<default key="_controller">Thelia\Controller\Admin\FileController::viewDocumentAction</default>
|
||||
<requirement key="parentType">.*</requirement>
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace Thelia\Controller\Admin;
|
||||
|
||||
use Propel\Runtime\Exception\PropelException;
|
||||
use Symfony\Component\HttpFoundation\File\UploadedFile;
|
||||
use Thelia\Core\Event\UpdateImagePositionEvent;
|
||||
use Thelia\Core\Event\UpdateFilePositionEvent;
|
||||
use Thelia\Core\HttpFoundation\Response;
|
||||
use Thelia\Core\Security\Resource\AdminResources;
|
||||
use Thelia\Core\Event\Document\DocumentCreateOrUpdateEvent;
|
||||
@@ -615,10 +615,10 @@ class FileController extends BaseAdminController
|
||||
}
|
||||
|
||||
// Feed event
|
||||
$imageUpdateImagePositionEvent = new UpdateImagePositionEvent(
|
||||
$imageUpdateImagePositionEvent = new UpdateFilePositionEvent(
|
||||
$fileManager->getImageModelQuery($parentType),
|
||||
$imageId,
|
||||
UpdateImagePositionEvent::POSITION_ABSOLUTE,
|
||||
UpdateFilePositionEvent::POSITION_ABSOLUTE,
|
||||
$position
|
||||
);
|
||||
|
||||
@@ -650,6 +650,60 @@ class FileController extends BaseAdminController
|
||||
return new Response($message);
|
||||
}
|
||||
|
||||
public function updateDocumentPositionAction($parentType, $parentId)
|
||||
{
|
||||
$message = null;
|
||||
|
||||
$documentId = $this->getRequest()->request->get('document_id');
|
||||
$position = $this->getRequest()->request->get('position');
|
||||
|
||||
$this->checkAuth(AdminResources::retrieve($parentType), array(), AccessManager::UPDATE);
|
||||
$this->checkXmlHttpRequest();
|
||||
|
||||
$fileManager = new FileManager($this->container);
|
||||
$documentModelQuery = $fileManager->getDocumentModelQuery($parentType);
|
||||
$model = $documentModelQuery->findPk($documentId);
|
||||
|
||||
if ($model === null || $position === null) {
|
||||
return $this->pageNotFound();
|
||||
}
|
||||
|
||||
// Feed event
|
||||
$documentUpdateDocumentPositionEvent = new UpdateFilePositionEvent(
|
||||
$fileManager->getDocumentModelQuery($parentType),
|
||||
$documentId,
|
||||
UpdateFilePositionEvent::POSITION_ABSOLUTE,
|
||||
$position
|
||||
);
|
||||
|
||||
// Dispatch Event to the Action
|
||||
try {
|
||||
$this->dispatch(
|
||||
TheliaEvents::DOCUMENT_UPDATE_POSITION,
|
||||
$documentUpdateDocumentPositionEvent
|
||||
);
|
||||
} catch (\Exception $e) {
|
||||
|
||||
$message = $this->getTranslator()
|
||||
->trans(
|
||||
'Fail to update document position',
|
||||
array(),
|
||||
'document'
|
||||
) . $e->getMessage();
|
||||
}
|
||||
|
||||
if(null === $message) {
|
||||
$message = $this->getTranslator()
|
||||
->trans(
|
||||
'Document position updated',
|
||||
array(),
|
||||
'document'
|
||||
);
|
||||
}
|
||||
|
||||
return new Response($message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Manage how a document has to be deleted (AJAX)
|
||||
*
|
||||
|
||||
@@ -404,6 +404,7 @@ final class TheliaEvents
|
||||
* Save given documents
|
||||
*/
|
||||
const DOCUMENT_UPDATE = "action.updateDocument";
|
||||
const DOCUMENT_UPDATE_POSITION = "action.updateDocumentPosition";
|
||||
|
||||
/**
|
||||
* Delete given document
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace Thelia\Core\Event;
|
||||
|
||||
use Propel\Runtime\ActiveQuery\ModelCriteria;
|
||||
|
||||
class UpdateImagePositionEvent extends UpdatePositionEvent
|
||||
class UpdateFilePositionEvent extends UpdatePositionEvent
|
||||
{
|
||||
protected $query;
|
||||
|
||||
@@ -7,6 +7,7 @@ use Propel\Runtime\Connection\ConnectionInterface;
|
||||
|
||||
class CategoryDocument extends BaseCategoryDocument
|
||||
{
|
||||
use \Thelia\Model\Tools\ModelEventDispatcherTrait;
|
||||
use \Thelia\Model\Tools\PositionManagementTrait;
|
||||
|
||||
/**
|
||||
|
||||
@@ -7,6 +7,7 @@ use Propel\Runtime\Connection\ConnectionInterface;
|
||||
|
||||
class ContentDocument extends BaseContentDocument
|
||||
{
|
||||
use \Thelia\Model\Tools\ModelEventDispatcherTrait;
|
||||
use \Thelia\Model\Tools\PositionManagementTrait;
|
||||
|
||||
/**
|
||||
|
||||
@@ -7,6 +7,7 @@ use Propel\Runtime\Connection\ConnectionInterface;
|
||||
|
||||
class FolderDocument extends BaseFolderDocument
|
||||
{
|
||||
use \Thelia\Model\Tools\ModelEventDispatcherTrait;
|
||||
use \Thelia\Model\Tools\PositionManagementTrait;
|
||||
|
||||
/**
|
||||
|
||||
@@ -7,6 +7,7 @@ use Propel\Runtime\Connection\ConnectionInterface;
|
||||
|
||||
class ProductDocument extends BaseProductDocument
|
||||
{
|
||||
use \Thelia\Model\Tools\ModelEventDispatcherTrait;
|
||||
use \Thelia\Model\Tools\PositionManagementTrait;
|
||||
|
||||
/**
|
||||
|
||||
@@ -6,9 +6,10 @@ $(function($){
|
||||
|
||||
|
||||
|
||||
// Remove image on click
|
||||
// Remove document on click
|
||||
$.documentUploadManager.initDocumentDropZone = function() {
|
||||
$.documentUploadManager.onClickDeleteDocument();
|
||||
$.documentUploadManager.sortDocument();
|
||||
|
||||
var documentDropzone = new Dropzone("#documents-dropzone", {
|
||||
dictDefaultMessage : $('.btn-browse').html(),
|
||||
@@ -39,6 +40,7 @@ $(function($){
|
||||
documentDropzone.removeFile(file);
|
||||
$.documentUploadManager.updateDocumentListAjax();
|
||||
$.documentUploadManager.onClickDeleteDocument();
|
||||
$.documentUploadManager.sortDocument();
|
||||
});
|
||||
|
||||
|
||||
@@ -67,7 +69,7 @@ $(function($){
|
||||
});
|
||||
};
|
||||
|
||||
// Remove image on click
|
||||
// Remove document on click
|
||||
$.documentUploadManager.onClickDeleteDocument = function() {
|
||||
$('.document-manager .document-delete-btn').on('click', function (e) {
|
||||
e.preventDefault();
|
||||
@@ -97,4 +99,52 @@ $(function($){
|
||||
return false;
|
||||
});
|
||||
};
|
||||
|
||||
$.documentUploadManager.sortDocument = function() {
|
||||
$( "#js-sort-document" ).sortable({
|
||||
placeholder: "ui-sortable-placeholder col-sm-6 col-md-3",
|
||||
change: function( event, ui ) {
|
||||
/* refresh position */
|
||||
var pickedElement = ui.item;
|
||||
var position = 0;
|
||||
$( "#js-sort-document").children('li').each(function(k, element) {
|
||||
if($(element).data('sort-id') == pickedElement.data('sort-id')) {
|
||||
return true;
|
||||
}
|
||||
position++;
|
||||
if($(element).is('.ui-sortable-placeholder')) {
|
||||
pickedElement.find('.js-sorted-position').html(position);
|
||||
} else {
|
||||
$(element).find('.js-sorted-position').html(position);
|
||||
}
|
||||
});
|
||||
},
|
||||
stop: function( event, ui ) {
|
||||
/* update */
|
||||
var newPosition = ui.item.find('.js-sorted-position').html();
|
||||
var documentId = ui.item.data('sort-id');
|
||||
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: documentReorder,
|
||||
data: {
|
||||
document_id: documentId,
|
||||
position: newPosition
|
||||
},
|
||||
statusCode: {
|
||||
404: function() {
|
||||
$(".document-manager .message").html(
|
||||
documentReorderErrorMessage
|
||||
);
|
||||
}
|
||||
}
|
||||
}).done(function(data) {
|
||||
$(".document-manager .message").html(
|
||||
data
|
||||
);
|
||||
});
|
||||
}
|
||||
});
|
||||
$( "#js-sort-document" ).disableSelection();
|
||||
};
|
||||
});
|
||||
|
||||
@@ -428,4 +428,17 @@ table {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// document list style
|
||||
ul.document-list {
|
||||
> li {
|
||||
padding: @table-condensed-cell-padding;
|
||||
line-height: @line-height-base;
|
||||
border-top: 1px solid @table-border-color;
|
||||
&:nth-child(odd) {
|
||||
background-color: @table-bg-accent;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -32,5 +32,7 @@ Parameters:
|
||||
<script>
|
||||
var documentDropZoneUrl = "{url path="/admin/document/type/$documentType/$parentId/save-ajax"}";
|
||||
var documentListUrl = "{url path="/admin/document/type/$documentType/$parentId/list-ajax"}";
|
||||
var documentReorder = "{url path="/admin/document/type/$documentType/$parentId/update-position"}";
|
||||
var documentListErrorMessage = "{intl l='Can\'t load documents, please refresh this page.'}";
|
||||
var documentReorderErrorMessage = "{intl l='Can\'t reorder documents, please refresh this page.'}";
|
||||
</script>
|
||||
|
||||
@@ -7,29 +7,27 @@ Parameters:
|
||||
parentId = Document parent id, ex: category id
|
||||
|
||||
*}
|
||||
|
||||
{ifloop rel="document"}
|
||||
<table class="table table-striped table-condensed table-left-aligned">
|
||||
<ul id="js-sort-document" class="list-unstyled document-list">
|
||||
{loop type="document" name="document" source="{$documentType}" order="manual" source_id="{$parentId}"}
|
||||
<tr>
|
||||
<td>
|
||||
<a href="{$DOCUMENT_PATH}" title="{$TITLE}" class="" target="_blank">{$TITLE}</a>
|
||||
</td>
|
||||
<td>
|
||||
<div class="btn-group">
|
||||
<a class="image-update-btn btn btn-default btn-xs disabled js-sorted-position" href="#">{$POSITION}</a>
|
||||
<a class="document-update-btn btn btn-default btn-xs" href="{url path="/admin/document/type/$documentType/$ID/update"}" data-error-message="{intl l='Please retry'}">
|
||||
<span class="glyphicon glyphicon-edit"></span>
|
||||
</a>
|
||||
<a class="document-delete-btn btn btn-default btn-xs" href="{url path="/admin/document/type/$documentType/delete/$ID"}" data-error-message="{intl l='Please retry'}">
|
||||
<span class="glyphicon glyphicon-trash"></span>
|
||||
</a>
|
||||
</div>
|
||||
<td>
|
||||
</tr>
|
||||
<li class="clearfix ui-state-default" data-sort-id="{$ID}">
|
||||
<a href="{$DOCUMENT_PATH}" title="{$TITLE}" class="pull-left" target="_blank">{$TITLE}</a>
|
||||
|
||||
|
||||
<div class="btn-group pull-right">
|
||||
<a class="image-update-btn btn btn-default btn-xs disabled js-sorted-position" href="#">{$POSITION}</a>
|
||||
<a class="document-update-btn btn btn-default btn-xs" href="{url path="/admin/document/type/$documentType/$ID/update"}" data-error-message="{intl l='Please retry'}">
|
||||
<span class="glyphicon glyphicon-edit"></span>
|
||||
</a>
|
||||
<a class="document-delete-btn btn btn-default btn-xs" href="{url path="/admin/document/type/$documentType/delete/$ID"}" data-error-message="{intl l='Please retry'}">
|
||||
<span class="glyphicon glyphicon-trash"></span>
|
||||
</a>
|
||||
</div>
|
||||
</li>
|
||||
{/loop}
|
||||
</table>
|
||||
</ul>
|
||||
{/ifloop}
|
||||
|
||||
{elseloop rel="document"}
|
||||
<div class="alert alert-info">{intl l='There is no documents attached to this %type.' type=$documentType}</div>
|
||||
{/elseloop}
|
||||
|
||||
Reference in New Issue
Block a user