Added readonly support to the mediamanager widget and the ability to set the MediaLibary cache key through code

This commit is contained in:
Luke Towers 2018-04-19 10:23:15 -06:00
parent 08d8b33fc6
commit 4d304645d7
9 changed files with 128 additions and 52 deletions

View File

@ -40,6 +40,11 @@ class MediaManager extends WidgetBase
protected $brokenImageHash = null;
/**
* @var boolean Determines whether the widget is in readonly mode or not
*/
public $readOnly = false;
/**
* @var boolean Determines whether the bottom toolbar is visible.
*/
@ -53,9 +58,10 @@ class MediaManager extends WidgetBase
/**
* Constructor.
*/
public function __construct($controller, $alias)
public function __construct($controller, $alias, $readOnly = false)
{
$this->alias = $alias;
$this->readOnly = $readOnly;
parent::__construct($controller, []);
@ -73,6 +79,16 @@ class MediaManager extends WidgetBase
$this->addJs('js/mediamanager-browser-min.js', 'core');
}
/**
* Abort the request with an access-denied code if readOnly mode is active
*/
protected function abortIfReadOnly()
{
if ($this->readOnly) {
abort(403);
}
}
/**
* Renders the widget.
* @return string
@ -230,6 +246,8 @@ class MediaManager extends WidgetBase
public function onDeleteItem()
{
$this->abortIfReadOnly();
$paths = Input::get('paths');
if (!is_array($paths)) {
@ -290,6 +308,8 @@ class MediaManager extends WidgetBase
public function onLoadRenamePopup()
{
$this->abortIfReadOnly();
$path = Input::get('path');
$path = MediaLibrary::validatePath($path);
@ -303,6 +323,8 @@ class MediaManager extends WidgetBase
public function onApplyName()
{
$this->abortIfReadOnly();
$newName = trim(Input::get('name'));
if (!strlen($newName)) {
throw new ApplicationException(Lang::get('cms::lang.asset.name_cant_be_empty'));
@ -352,6 +374,8 @@ class MediaManager extends WidgetBase
public function onCreateFolder()
{
$this->abortIfReadOnly();
$name = trim(Input::get('name'));
if (!strlen($name)) {
throw new ApplicationException(Lang::get('cms::lang.asset.name_cant_be_empty'));
@ -395,6 +419,8 @@ class MediaManager extends WidgetBase
public function onLoadMovePopup()
{
$this->abortIfReadOnly();
$exclude = Input::get('exclude', []);
if (!is_array($exclude)) {
throw new ApplicationException('Invalid input data');
@ -425,6 +451,8 @@ class MediaManager extends WidgetBase
public function onMoveItems()
{
$this->abortIfReadOnly();
$dest = trim(Input::get('dest'));
if (!strlen($dest)) {
throw new ApplicationException(Lang::get('backend::lang.media.please_select_move_dest'));
@ -498,6 +526,8 @@ class MediaManager extends WidgetBase
public function onLoadImageCropPopup()
{
$this->abortIfReadOnly();
$path = Input::get('path');
$path = MediaLibrary::validatePath($path);
$cropSessionKey = md5(FormHelper::getSessionKey());
@ -521,6 +551,8 @@ class MediaManager extends WidgetBase
public function onEndCroppingSession()
{
$this->abortIfReadOnly();
$cropSessionKey = Input::get('cropSessionKey');
if (!preg_match('/^[0-9a-z]+$/', $cropSessionKey)) {
throw new ApplicationException('Invalid input data');
@ -531,6 +563,8 @@ class MediaManager extends WidgetBase
public function onCropImage()
{
$this->abortIfReadOnly();
$imageSrcPath = trim(Input::get('img'));
$selectionData = Input::get('selection');
$cropSessionKey = Input::get('cropSessionKey');
@ -562,6 +596,8 @@ class MediaManager extends WidgetBase
public function onResizeImage()
{
$this->abortIfReadOnly();
$cropSessionKey = Input::get('cropSessionKey');
if (!preg_match('/^[0-9a-z]+$/', $cropSessionKey)) {
throw new ApplicationException('Invalid input data');
@ -589,7 +625,7 @@ class MediaManager extends WidgetBase
}
//
// Methods for th internal use
// Methods for internal use
//
protected function prepareVars()
@ -1078,6 +1114,10 @@ class MediaManager extends WidgetBase
protected function checkUploadPostback()
{
if ($this->readOnly) {
return;
}
$fileName = null;
$quickMode = false;

View File

@ -274,7 +274,7 @@ this.selectionMarker=document.createElement('div')
this.selectionMarker.setAttribute('data-control','selection-marker')
this.scrollContentElement.insertBefore(this.selectionMarker,this.scrollContentElement.firstChild)}
MediaManager.prototype.doObjectsCollide=function(aTop,aLeft,aWidth,aHeight,bTop,bLeft,bWidth,bHeight){return!(((aTop+aHeight)<(bTop))||(aTop>(bTop+bHeight))||((aLeft+aWidth)<bLeft)||(aLeft>(bLeft+bWidth)))}
MediaManager.prototype.initUploader=function(){if(!this.itemListElement)
MediaManager.prototype.initUploader=function(){if(!this.itemListElement||this.options.readOnly)
return
var uploaderOptions={clickable:this.$el.find('[data-control="upload"]').get(0),url:this.options.url,paramName:'file_data',headers:{},createImageThumbnails:false}
if(this.options.uniqueId){uploaderOptions.headers['X-OCTOBER-FILEUPLOAD']=this.options.uniqueId}

View File

@ -708,7 +708,7 @@
//
MediaManager.prototype.initUploader = function() {
if (!this.itemListElement)
if (!this.itemListElement || this.options.readOnly)
return
var uploaderOptions = {

View File

@ -10,11 +10,13 @@
data-selection-not-image="<?= e(trans('backend::lang.media.selection_not_image')) ?>"
data-bottom-toolbar="<?= $this->bottomToolbar ? 'true' : 'false' ?>"
data-crop-and-insert-button="<?= $this->cropAndInsertButton ? 'true' : 'false' ?>"
data-read-only="<?= $this->readOnly ? 'true' : 'false'; ?>"
tabindex="0"
>
<?= $this->makePartial('toolbar') ?>
<?= $this->makePartial('upload-progress') ?>
<?= (!$this->readOnly) ? $this->makePartial('upload-progress') : '' ?>
<div class="layout-row whiteboard">
<div class="layout">
@ -65,4 +67,4 @@
</div>
<?= $this->makePartial('new-folder-form') ?>
</div>
</div>

View File

@ -9,13 +9,15 @@
<?= e(trans('backend::lang.media.insert')) ?>
</button>
<button
type="button"
data-command="popup-command"
data-popup-command="crop-and-insert"
class="btn btn-primary hide">
<?= e(trans('backend::lang.media.crop_and_insert')) ?>
</button>
<?php if (!$this->readOnly) : ?>
<button
type="button"
data-command="popup-command"
data-popup-command="crop-and-insert"
class="btn btn-primary hide">
<?= e(trans('backend::lang.media.crop_and_insert')) ?>
</button>
<?php endif; ?>
<button
type="button"
@ -25,4 +27,4 @@
</button>
</div>
</div>
</div>
</div>

View File

@ -37,14 +37,16 @@
<h4 title="<?= e(basename($item->path)) ?>">
<?= e(basename($item->path)) ?>
<a
href="#"
data-rename
data-control="popup"
data-z-index="1200"
data-request-data="path: '<?= e($item->path) ?>', listId: '<?= $listElementId ?>', type: '<?= $item->type ?>'"
data-handler="<?= $this->getEventHandler('onLoadRenamePopup') ?>"
><i data-rename-control class="icon-terminal"></i></a>
<?php if (!$this->readOnly) : ?>
<a
href="#"
data-rename
data-control="popup"
data-z-index="1200"
data-request-data="path: '<?= e($item->path) ?>', listId: '<?= $listElementId ?>', type: '<?= $item->type ?>'"
data-handler="<?= $this->getEventHandler('onLoadRenamePopup') ?>"
><i data-rename-control class="icon-terminal"></i></a>
<?php endif; ?>
</h4>
<p class="size"><?= e($item->sizeToString()) ?></p>
</div>
@ -57,4 +59,4 @@
<?= e(trans('backend::lang.media.no_files_found')) ?>
</li>
<?php endif ?>
</ul>
</ul>

View File

@ -17,13 +17,13 @@
</tr>
<?php endif ?>
<?php foreach ($items as $item):
<?php foreach ($items as $item):
$itemType = $item->getFileType();
?>
<tr data-type="media-item"
data-item-type="<?= $item->type ?>"
data-path="<?= e($item->path) ?>"
data-title="<?= e(basename($item->path)) ?>"
<tr data-type="media-item"
data-item-type="<?= $item->type ?>"
data-path="<?= e($item->path) ?>"
data-title="<?= e(basename($item->path)) ?>"
data-size="<?= e($item->sizeToString()) ?>"
data-last-modified="<?= e($item->lastModifiedAsString()) ?>"
data-last-modified-ts="<?= $item->lastModified ?>"
@ -36,14 +36,16 @@
<div class="item-title no-wrap-text">
<i class="<?= $this->itemTypeToIconClass($item, $itemType) ?>"></i> <?= e(basename($item->path)) ?>
<a
href="#"
data-rename
data-control="popup"
data-request-data="path: '<?= e($item->path) ?>', listId: '<?= $listElementId ?>', type: '<?= $item->type ?>'"
data-handler="<?= $this->getEventHandler('onLoadRenamePopup') ?>"
data-z-index="1200"
><i data-rename-control class="icon-terminal"></i></a>
<?php if (!$this->readOnly) : ?>
<a
href="#"
data-rename
data-control="popup"
data-request-data="path: '<?= e($item->path) ?>', listId: '<?= $listElementId ?>', type: '<?= $item->type ?>'"
data-handler="<?= $this->getEventHandler('onLoadRenamePopup') ?>"
data-z-index="1200"
><i data-rename-control class="icon-terminal"></i></a>
<?php endif; ?>
</div>
</td>
<td><?= e($item->sizeToString()) ?></td>

View File

@ -2,20 +2,24 @@
<div class="control-toolbar toolbar-padded">
<div class="toolbar-item toolbar-primary">
<div data-control="toolbar">
<div class="btn-group offset-right">
<button type="button" class="btn btn-primary oc-icon-upload" data-control="upload"
><?= e(trans('backend::lang.media.upload')) ?></button>
<button type="button" class="btn btn-primary oc-icon-folder" data-command="create-folder"><?= e(trans('backend::lang.media.add_folder')) ?></button>
</div>
<?php if (!$this->readOnly) : ?>
<div class="btn-group offset-right">
<button type="button" class="btn btn-primary oc-icon-upload" data-control="upload"
><?= e(trans('backend::lang.media.upload')) ?></button>
<button type="button" class="btn btn-primary oc-icon-folder" data-command="create-folder"><?= e(trans('backend::lang.media.add_folder')) ?></button>
</div>
<?php endif; ?>
<button type="button" class="btn btn-default oc-icon-refresh empty offset-right" data-command="refresh"></button>
<div class="btn-group offset-right">
<button type="button" class="btn btn-default oc-icon-reply-all" data-command="move"
><?= e(trans('backend::lang.media.move')) ?></button>
<button type="button" class="btn btn-default oc-icon-trash" data-command="delete"
><?= e(trans('backend::lang.media.delete')) ?></button>
</div>
<?php if (!$this->readOnly) : ?>
<div class="btn-group offset-right">
<button type="button" class="btn btn-default oc-icon-reply-all" data-command="move"
><?= e(trans('backend::lang.media.move')) ?></button>
<button type="button" class="btn btn-default oc-icon-trash" data-command="delete"
><?= e(trans('backend::lang.media.delete')) ?></button>
</div>
<?php endif; ?>
<div class="btn-group offset-right" id="<?= $this->getId('view-mode-buttons') ?>">
<?= $this->makePartial('view-mode-buttons') ?>
@ -38,4 +42,4 @@
</div>
</div>
</div>
</div>
</div>

View File

@ -21,13 +21,17 @@ class MediaLibrary
{
use \October\Rain\Support\Traits\Singleton;
const CACHE_KEY = 'system-media-library-contents';
const SORT_BY_TITLE = 'title';
const SORT_BY_SIZE = 'size';
const SORT_BY_MODIFIED = 'modified';
const SORT_DIRECTION_ASC = 'asc';
const SORT_DIRECTION_DESC = 'desc';
/**
* @var string Cache key
*/
protected $cacheKey = 'system-media-library-contents';
/**
* @var string Relative or absolute URL of the Library root folder.
*/
@ -79,6 +83,26 @@ class MediaLibrary
$this->storageFolderNameLength = strlen($this->storageFolder);
}
/**
* Set the cache key
*
* @param string $cacheKey The key to set as the cache key for this instance
*/
public function setCacheKey($cacheKey)
{
$this->cacheKey = $cacheKey;
}
/**
* Get the cache key
*
* @return string The cache key to set as the cache key for this instance
*/
public function getCacheKey()
{
return $this->cacheKey;
}
/**
* Returns a list of folders and files in a Library folder.
*
@ -99,7 +123,7 @@ class MediaLibrary
* Try to load the contents from cache
*/
$cached = Cache::get(self::CACHE_KEY, false);
$cached = Cache::get($this->cacheKey, false);
$cached = $cached ? @unserialize(@base64_decode($cached)) : [];
if (!is_array($cached)) {
@ -114,7 +138,7 @@ class MediaLibrary
$cached[$fullFolderPath] = $folderContents;
Cache::put(
self::CACHE_KEY,
$this->cacheKey,
base64_encode(serialize($cached)),
Config::get('cms.storage.media.ttl', 10)
);
@ -429,7 +453,7 @@ class MediaLibrary
*/
public function resetCache()
{
Cache::forget(self::CACHE_KEY);
Cache::forget($this->cacheKey);
}
/**