--- /dev/null
+{if $__wcf->session->getPermission('admin.content.cms.canUseMedia')}
+ require(['Language', 'Permission'], function(Language, Permission) {
+ Language.addObject({
+ 'wcf.global.button.insert': '{lang}wcf.global.button.insert{/lang}',
+
+ 'wcf.media.insert': '{lang}wcf.media.insert{/lang}',
+ 'wcf.media.insert.imageSize': '{lang}wcf.media.insert.imageSize{/lang}',
+ 'wcf.media.insert.imageSize.small': '{lang __literal=true}wcf.media.insert.imageSize.small{/lang}',
+ 'wcf.media.insert.imageSize.medium': '{lang __literal=true}wcf.media.insert.imageSize.medium{/lang}',
+ 'wcf.media.insert.imageSize.large': '{lang __literal=true}wcf.media.insert.imageSize.large{/lang}',
+ 'wcf.media.insert.imageSize.original': '{lang __literal=true}wcf.media.insert.imageSize.original{/lang}',
+ 'wcf.media.manager': '{lang}wcf.media.manager{/lang}',
+ 'wcf.media.edit': '{lang}wcf.media.edit{/lang}',
+ 'wcf.media.imageDimensions.value': '{lang __literal=true}wcf.media.imageDimensions.value{/lang}',
+ 'wcf.media.button.insert': '{lang}wcf.media.button.insert{/lang}',
+ 'wcf.media.search.filetype': '{lang}wcf.media.search.filetype{/lang}',
+ 'wcf.media.search.noResults': '{lang}wcf.media.search.noResults{/lang}'
+ });
+
+ Permission.add('admin.content.cms.canManageMedia', {if $__wcf->session->getPermission('admin.content.cms.canManageMedia')}true{else}false{/if});
+ });
+{/if}
{foreach from=$mediaList item=media}
<li class="jsClipboardObject" data-object-id="{@$media->mediaID}">
<div class="mediaThumbnail">
- {@$media->getElementTag(96)}
+ {@$media->getElementTag(144)}
</div>
<div class="mediaInformation">
<a><span class="icon icon16 fa-times jsTooltip jsMediaDeleteIcon" data-object-id="{@$media->mediaID}" title="{lang}wcf.global.button.delete{/lang}"></span></a>
</li>
{/if}
- <li>
- <a><span class="icon icon16 fa-plus jsTooltip jsMediaInsertIcon" data-object-id="{@$media->mediaID}" title="{lang}wcf.media.button.insert{/lang}"></span></a>
- </li>
+ {if $mode == 'editor'}
+ <li>
+ <a><span class="icon icon16 fa-plus jsTooltip jsMediaInsertIcon" data-object-id="{@$media->mediaID}" title="{lang}wcf.media.button.insert{/lang}"></span></a>
+ </li>
+ {elseif $mode == 'select'}
+ <li>
+ <a><span class="icon icon16 fa-check jsTooltip jsMediaSelectIcon" data-object-id="{@$media->mediaID}" title="{lang}wcf.media.button.select{/lang}"></span></a>
+ </li>
+ {/if}
</ul>
</nav>
</li>
-<div class="inputAddon dropdown" id="mediaManagerSearch">
- <span class="button dropdownToggle inputPrefix">
- <span class="active">{lang}wcf.media.search.filetype{/lang}</span>
- </span>
- <ul class="dropdownMenu">
- <li data-file-type="image"><span>{lang}wcf.media.search.filetype.image{/lang}</span></li>
- <li data-file-type="text"><span>{lang}wcf.media.search.filetype.text{/lang}</span></li>
- <li data-file-type="pdf"><span>{lang}wcf.media.search.filetype.pdf{/lang}</span></li>
- <li data-file-type="other"><span>{lang}wcf.media.search.filetype.other{/lang}</span></li>
- {event name='filetype'}
- <li class="dropdownDivider"></li>
- <li data-file-type="all"><span>{lang}wcf.media.search.filetype.all{/lang}</span></li>
- </ul>
+{if !$showFileTypeFilter|isset}{assign var=showFileTypeFilter value=true}{/if}
+<div class="inputAddon{if $showFileTypeFilter} dropdown{/if}" id="mediaManagerSearch">
+ {if $showFileTypeFilter}
+ <span class="button dropdownToggle inputPrefix">
+ <span class="active">{lang}wcf.media.search.filetype{/lang}</span>
+ </span>
+ <ul class="dropdownMenu">
+ <li data-file-type="image"><span>{lang}wcf.media.search.filetype.image{/lang}</span></li>
+ <li data-file-type="text"><span>{lang}wcf.media.search.filetype.text{/lang}</span></li>
+ <li data-file-type="pdf"><span>{lang}wcf.media.search.filetype.pdf{/lang}</span></li>
+ <li data-file-type="other"><span>{lang}wcf.media.search.filetype.other{/lang}</span></li>
+ {event name='filetype'}
+ <li class="dropdownDivider"></li>
+ <li data-file-type="all"><span>{lang}wcf.media.search.filetype.all{/lang}</span></li>
+ </ul>
+ {/if}
<input type="text" id="mediaManagerSearchField" placeholder="{lang}wcf.media.search.placeholder{/lang}" />
<span class="inputSuffix">
<span id="mediaManagerSearchCancelButton" class="icon icon16 fa-times pointer jsTooltip" title="{lang}wcf.media.search.cancel{/lang}"></span>
WCF.System.Dependency.Manager.setup(callbackIdentifier, function() {
// TODO: Should the media stuff be here?
- {if $__wcf->session->getPermission('admin.content.cms.canUseMedia')}
- require(['Language', 'Permission'], function(Language, Permission) {
- Language.addObject({
- 'wcf.global.button.insert': '{lang}wcf.global.button.insert{/lang}',
-
- 'wcf.media.insert': '{lang}wcf.media.insert{/lang}',
- 'wcf.media.insert.imageSize': '{lang}wcf.media.insert.imageSize{/lang}',
- 'wcf.media.insert.imageSize.small': '{lang __literal=true}wcf.media.insert.imageSize.small{/lang}',
- 'wcf.media.insert.imageSize.medium': '{lang __literal=true}wcf.media.insert.imageSize.medium{/lang}',
- 'wcf.media.insert.imageSize.large': '{lang __literal=true}wcf.media.insert.imageSize.large{/lang}',
- 'wcf.media.insert.imageSize.original': '{lang __literal=true}wcf.media.insert.imageSize.original{/lang}',
- 'wcf.media.manager': '{lang}wcf.media.manager{/lang}',
- 'wcf.media.edit': '{lang}wcf.media.edit{/lang}',
- 'wcf.media.imageDimensions.value': '{lang __literal=true}wcf.media.imageDimensions.value{/lang}',
- 'wcf.media.button.insert': '{lang}wcf.media.button.insert{/lang}',
- 'wcf.media.search.filetype': '{lang}wcf.media.search.filetype{/lang}',
- 'wcf.media.search.noResults': '{lang}wcf.media.search.noResults{/lang}'
- });
-
- Permission.add('admin.content.cms.canManageMedia', {if $__wcf->session->getPermission('admin.content.cms.canManageMedia')}true{else}false{/if});
- });
- {/if}
+ {include file='mediaJavaScript'}
var element = elById(elementId);
var autosave = elData(element, 'autosave') || '';
{include file='header' pageTitle='wcf.acp.box.'|concat:$action}
+{if $__wcf->session->getPermission('admin.content.cms.canUseMedia')}
+ <script data-relocate="true">
+ {include file='mediaJavaScript'}
+
+ require(['WoltLab/WCF/Media/Manager/Select'], function(MediaManagerSelect) {
+ new MediaManagerSelect({
+ dialogTitle: '{lang}wcf.acp.box.image.dialog.title{/lang}',
+ fileTypeFilters: {
+ isImage: 1
+ }
+ });
+ });
+ </script>
+{/if}
+
<header class="boxHeadline">
<h1>{if $action == 'add'}{if $isMultilingual}{lang}wcf.acp.box.addMultilingual{/lang}{else}{lang}wcf.acp.box.add{/lang}{/if}{else}{lang}wcf.acp.box.edit{/lang}{/if}</h1>
</header>
<nav>
<ul>
<li><a href="{link controller='BoxList'}{/link}" class="button"><span class="icon icon16 fa-list"></span> <span>{lang}wcf.acp.menu.link.cms.box.list{/lang}</span></a></li>
-
+
{event name='contentNavigationButtons'}
</ul>
</nav>
<input type="number" id="showOrder" name="showOrder" value="{@$showOrder}" class="tiny" min="0" />
</dd>
</dl>
-
+
<dl{if $errorField == 'cssClassName'} class="formError"{/if}>
<dt><label for="cssClassName">{lang}wcf.acp.box.cssClassName{/lang}</label></dt>
<dd>
<label><input type="checkbox" id="showHeader" name="showHeader" value="1" {if $showHeader}checked="checked" {/if}/> {lang}wcf.acp.box.showHeader{/lang}</label>
</dd>
</dl>
-
+
<dl>
<dt></dt>
<dd>
{event name='dataFields'}
</section>
-
+
{if !$isMultilingual}
<fieldset>
<legend>content</legend>
-
+
+ {if $__wcf->session->getPermission('admin.content.cms.canUseMedia')}
+ <dl{if $errorField == 'image'} class="formError"{/if}>
+ <dt><label for="image">{lang}wcf.acp.box.image{/lang}</label></dt>
+ <dd>
+ <div id="imageDisplay">
+ {if $images[0]|isset}
+ {@$images[0]->getThumbnailTag('small')}
+ {/if}
+ </div>
+ <p class="button jsMediaSelectButton" data-store="imageID0" data-display="imageDisplay">{lang}wcf.acp.box.image.button.chooseImage{/lang}</p>
+ <input type="hidden" name="imageID[0]" id="imageID0"{if $imageID[0]|isset} value="{@$imageID[0]}"{/if} />
+ {if $errorField == 'image'}
+ <small class="innerError">{lang}wcf.acp.box.image.error.{@$errorType}{/lang}</small>
+ {/if}
+ </dd>
+ </dl>
+ {elseif $action == 'edit' && $images[0]|isset}
+ <dl>
+ <dt>{lang}wcf.acp.box.image{/lang}</dt>
+ <dd>
+ <div id="imageDisplay">{@$images[0]->getThumbnailTag('small')}</div>
+ </dd>
+ </dl>
+ {/if}
+
<dl{if $errorField == 'title'} class="formError"{/if}>
<dt><label for="title">{lang}wcf.acp.box.title{/lang}</label></dt>
<dd>
- <input type="text" id="title" name="title[0]" value="{if !$title[0]|empty}{$title[0]}{/if}" class="long" />
+ <input type="text" id="title0" name="title[0]" value="{if !$title[0]|empty}{$title[0]}{/if}" class="long" />
{if $errorField == 'title'}
<small class="innerError">
{if $errorType == 'empty'}
{foreach from=$availableLanguages item=availableLanguage}
<div id="language{@$availableLanguage->languageID}" class="tabMenuContent">
<div>
- <dl{if $errorField == 'title'} class="formError"{/if}>
+ {if $__wcf->session->getPermission('admin.content.cms.canUseMedia')}
+ <dl{if $errorField == 'image'|concat:$availableLanguage->languageID} class="formError"{/if}>
+ <dt><label for="image{@$availableLanguage->languageID}">{lang}wcf.acp.box.image{/lang}</label></dt>
+ <dd>
+ <div id="imageDisplay{@$availableLanguage->languageID}"></div>
+ <p class="button jsMediaSelectButton" data-store="imageID{@$availableLanguage->languageID}" data-display="imageDisplay{@$availableLanguage->languageID}">{lang}wcf.acp.box.image.button.chooseImage{/lang}</p>
+ <input type="hidden" name="imageID[{@$availableLanguage->languageID}]" id="imageID{@$availableLanguage->languageID}"{if $imageID[$availableLanguage->languageID]|isset} value="{@$imageID[$availableLanguage->languageID]}"{/if} />
+ {if $errorField == 'image'|concat:$availableLanguage->languageID}
+ <small class="innerError">{lang}wcf.acp.box.image.error.{@$errorType}{/lang}</small>
+ {/if}
+ </dd>
+ </dl>
+ {elseif $action == 'edit' && $images[$availableLanguage->languageID]|isset}
+ <dl>
+ <dt>{lang}wcf.acp.box.image{/lang}</dt>
+ <dd>
+ <div id="imageDisplay">{@$images[$availableLanguage->languageID]->getThumbnailTag('small')}</div>
+ </dd>
+ </dl>
+ {/if}
+
+ <dl{if $errorField == 'title'|concat:$availableLanguage->languageID} class="formError"{/if}>
<dt><label for="title{@$availableLanguage->languageID}">{lang}wcf.acp.box.title{/lang}</label></dt>
<dd>
<input type="text" id="title{@$availableLanguage->languageID}" name="title[{@$availableLanguage->languageID}]" value="{if !$title[$availableLanguage->languageID]|empty}{$title[$availableLanguage->languageID]}{/if}" class="long" />
- {if $errorField == 'title'}
+ {if $errorField == 'title'|concat:$availableLanguage->languageID}
<small class="innerError">
{if $errorType == 'empty'}
{lang}wcf.global.form.error.empty{/lang}
</dd>
</dl>
- <dl{if $errorField == 'content'} class="formError"{/if}>
+ <dl{if $errorField == 'content'|concat:$availableLanguage->languageID} class="formError"{/if}>
<dt><label for="content{@$availableLanguage->languageID}">{lang}wcf.acp.box.content{/lang}</label></dt>
<dd>
<textarea name="content[{@$availableLanguage->languageID}]" id="content{@$availableLanguage->languageID}">{if !$content[$availableLanguage->languageID]|empty}{$content[$availableLanguage->languageID]}{/if}</textarea>
- {if $errorField == 'content'}
+ {if $errorField == 'content'|concat:$availableLanguage->languageID}
<small class="innerError">
{if $errorType == 'empty'}
{lang}wcf.global.form.error.empty{/lang}
{/foreach}
</div>
{/if}
-
+
{event name='sections'}
<div class="formSubmit">
<dl>
<dt>{lang}wcf.media.file{/lang}</dt>
- <dd>{$media->filename} {*TODO: better output *}</dd>
+ <dd>
+ {if $media->isImage}
+ {@$media->getThumbnailTag('small')}
+ {else}
+ {$media->filename}
+ {/if}
+ </dd>
</dl>
<dl>
--- /dev/null
+<div id="mediaThumbnail" class="framed"></div>
+
+<div class="box48">
+ <span id="mediaFileIcon" class="icon icon48 fa-file-o"></span>
+
+ <dl class="plain dataList">
+ <dt>{lang}wcf.media.filename{/lang}</dt>
+ <dd id="mediaFilename"></dd>
+
+ <dt>{lang}wcf.media.filesize{/lang}</dt>
+ <dd id="mediaFilesize"></dd>
+
+ <dt>{lang}wcf.media.imageDimensions{/lang}</dt>
+ <dd id="mediaImageDimensions"></dd>
+
+ <dt>{lang}wcf.media.uploader{/lang}</dt>
+ <dd id="mediaUploader"></dd>
+ </dl>
+</div>
+
+<fieldset class="marginTop">
+ <legend>{lang}wcf.global.form.data{/lang}</legend>
+
+ <dl>
+ <dt></dt>
+ <dd>
+ <label>
+ <input type="checkbox" id="isMultilingual" name="isMultilingual" value="1" />
+ <span>{lang}wcf.media.isMultilingual{/lang}</span>
+ </label>
+ </dd>
+ </dl>
+
+ {include file='languageChooser' label='wcf.media.languageID'}
+
+ <dl>
+ <dt>{lang}wcf.global.title{/lang}</dt>
+ <dd>
+ <input type="text" id="title" name="title" class="long" />
+ </dd>
+ </dl>
+ {include file='multipleLanguageInputJavascript' elementIdentifier='title' forceSelection=true}
+
+ <dl>
+ <dt>{lang}wcf.media.caption{/lang}</dt>
+ <dd>
+ <textarea id="caption" name="caption" cols="40" rows="3"></textarea>
+ </dd>
+ </dl>
+ {include file='multipleLanguageInputJavascript' elementIdentifier='caption' forceSelection=true}
+
+ <dl>
+ <dt>{lang}wcf.media.altText{/lang}</dt>
+ <dd>
+ <input type="text" id="altText" name="altText" class="long" />
+ </dd>
+ </dl>
+ {include file='multipleLanguageInputJavascript' elementIdentifier='altText' forceSelection=true}
+
+ {event name='dataFields'}
+</fieldset>
+
+<div class="formSubmit">
+ <button data-type="submit" class="buttonPrimary">{lang}wcf.global.button.submit{/lang}</button>
+</div>
--- /dev/null
+{if $__wcf->session->getPermission('admin.content.cms.canUseMedia')}
+ require(['Language', 'Permission'], function(Language, Permission) {
+ Language.addObject({
+ 'wcf.global.button.insert': '{lang}wcf.global.button.insert{/lang}',
+
+ 'wcf.media.insert': '{lang}wcf.media.insert{/lang}',
+ 'wcf.media.insert.imageSize': '{lang}wcf.media.insert.imageSize{/lang}',
+ 'wcf.media.insert.imageSize.small': '{lang __literal=true}wcf.media.insert.imageSize.small{/lang}',
+ 'wcf.media.insert.imageSize.medium': '{lang __literal=true}wcf.media.insert.imageSize.medium{/lang}',
+ 'wcf.media.insert.imageSize.large': '{lang __literal=true}wcf.media.insert.imageSize.large{/lang}',
+ 'wcf.media.insert.imageSize.original': '{lang __literal=true}wcf.media.insert.imageSize.original{/lang}',
+ 'wcf.media.manager': '{lang}wcf.media.manager{/lang}',
+ 'wcf.media.edit': '{lang}wcf.media.edit{/lang}',
+ 'wcf.media.imageDimensions.value': '{lang __literal=true}wcf.media.imageDimensions.value{/lang}',
+ 'wcf.media.button.insert': '{lang}wcf.media.button.insert{/lang}',
+ 'wcf.media.search.filetype': '{lang}wcf.media.search.filetype{/lang}',
+ 'wcf.media.search.noResults': '{lang}wcf.media.search.noResults{/lang}'
+ });
+
+ Permission.add('admin.content.cms.canManageMedia', {if $__wcf->session->getPermission('admin.content.cms.canManageMedia')}true{else}false{/if});
+ });
+{/if}
--- /dev/null
+{foreach from=$mediaList item=media}
+ <li class="jsClipboardObject" data-object-id="{@$media->mediaID}">
+ <div class="mediaThumbnail">
+ {@$media->getElementTag(144)}
+ </div>
+
+ <div class="mediaInformation">
+ <p class="mediaTitle">{if $media->title}{$media->title}{else}{$media->filename}{/if}</p>
+ </div>
+
+ <nav class="buttonGroupNavigation">
+ <ul class="smallButtons buttonGroup">
+ <li>
+ <input type="checkbox" class="jsClipboardItem jsMediaCheckbox" data-object-id="{@$media->mediaID}" />
+ </li>
+ {if $__wcf->session->getPermission('admin.content.cms.canManageMedia')}
+ <li>
+ <a><span class="icon icon16 fa-pencil jsTooltip jsMediaEditIcon" data-object-id="{@$media->mediaID}" title="{lang}wcf.global.button.edit{/lang}"></span></a>
+ </li>
+ <li>
+ <a><span class="icon icon16 fa-times jsTooltip jsMediaDeleteIcon" data-object-id="{@$media->mediaID}" title="{lang}wcf.global.button.delete{/lang}"></span></a>
+ </li>
+ {/if}
+ {if $mode == 'editor'}
+ <li>
+ <a><span class="icon icon16 fa-plus jsTooltip jsMediaInsertIcon" data-object-id="{@$media->mediaID}" title="{lang}wcf.media.button.insert{/lang}"></span></a>
+ </li>
+ {elseif $mode == 'select'}
+ <li>
+ <a><span class="icon icon16 fa-check jsTooltip jsMediaSelectIcon" data-object-id="{@$media->mediaID}" title="{lang}wcf.media.button.select{/lang}"></span></a>
+ </li>
+ {/if}
+ </ul>
+ </nav>
+ </li>
+{/foreach}
--- /dev/null
+{if !$showFileTypeFilter|isset}{assign var=showFileTypeFilter value=true}{/if}
+<div class="inputAddon{if $showFileTypeFilter} dropdown{/if}" id="mediaManagerSearch">
+ {if $showFileTypeFilter}
+ <span class="button dropdownToggle inputPrefix">
+ <span class="active">{lang}wcf.media.search.filetype{/lang}</span>
+ </span>
+ <ul class="dropdownMenu">
+ <li data-file-type="image"><span>{lang}wcf.media.search.filetype.image{/lang}</span></li>
+ <li data-file-type="text"><span>{lang}wcf.media.search.filetype.text{/lang}</span></li>
+ <li data-file-type="pdf"><span>{lang}wcf.media.search.filetype.pdf{/lang}</span></li>
+ <li data-file-type="other"><span>{lang}wcf.media.search.filetype.other{/lang}</span></li>
+ {event name='filetype'}
+ <li class="dropdownDivider"></li>
+ <li data-file-type="all"><span>{lang}wcf.media.search.filetype.all{/lang}</span></li>
+ </ul>
+ {/if}
+ <input type="text" id="mediaManagerSearchField" placeholder="{lang}wcf.media.search.placeholder{/lang}" />
+ <span class="inputSuffix">
+ <span id="mediaManagerSearchCancelButton" class="icon icon16 fa-times pointer jsTooltip" title="{lang}wcf.media.search.cancel{/lang}"></span>
+ </span>
+</div>
+
+{if $__wcf->session->getPermission('admin.content.cms.canManageMedia')}
+ <div id="mediaManagerMediaUploadButton" class="marginTop"></div>
+{/if}
+
+<div class="jsClipboardContainer marginTop" data-type="com.woltlab.wcf.media">
+ <input type="checkbox" class="jsClipboardMarkAll" style="display: none;" />
+ <ul id="mediaManagerMediaList">
+ {include file='mediaListItems'}
+ </ul>
+
+ <div class="contentNavigation">
+ <nav class="jsClipboardEditor" data-types="[ 'com.woltlab.wcf.media' ]"></nav>
+ </div>
+</div>
return {
init: function() {
var button = this.button.add('woltlabMedia', 'Media');
- $(button).attr('id', 'mediaManagerButton');
+ $(button).addClass('jsMediaEditorButton');
- require(['WoltLab/WCF/Media/Manager'], function(MediaManager) {
- new MediaManager();
+ require(['WoltLab/WCF/Media/Manager/Editor'], function(MediaManagerEditor) {
+ new MediaManagerEditor();
});
},
};
options.pinData = true;
options.callbackObject = callbackObject;
- if (!options.url) options.url = 'index.php/AJAXProxy/?t=' + SECURITY_TOKEN;
+ if (!options.url) options.url = 'index.php/AJAXProxy/?t=' + SECURITY_TOKEN + SID_ARG_2ND;
request = new AjaxRequest(options);
+++ /dev/null
-/**
- * Provides the media manager dialog.
- *
- * @author Matthias Schmidt
- * @copyright 2001-2015 WoltLab GmbH
- * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @module WoltLab/WCF/Controller/Media/Manager
- */
-define(
- [
- 'Core', 'Dictionary', 'Dom/ChangeListener', 'Dom/Traverse',
- 'Dom/Util', 'EventHandler', 'Language', 'List',
- 'Permission', 'Ui/Dialog', 'Ui/Notification', 'WoltLab/WCF/Controller/Clipboard',
- 'WoltLab/WCF/Media/Editor', 'WoltLab/WCF/Media/Upload', 'WoltLab/WCF/Media/Search'
-
-
- ],
- function(
- Core, Dictionary, DomChangeListener, DomTraverse,
- DomUtil, EventHandler, Language, List,
- Permission, UiDialog, UiNotification, Clipboard,
- MediaEditor, MediaUpload, MediaSearch
- )
-{
- "use strict";
-
- /**
- * @constructor
- */
- function MediaManager() {
- this._media = new Dictionary();
- this._mediaData = new Dictionary();
- this._mediaCache = null;
- this._mediaManagerMediaList = null;
- this._search = null;
-
- if (Permission.get('admin.content.cms.canManageMedia')) {
- this._mediaEditor = new MediaEditor(this);
- }
-
- elById('mediaManagerButton').addEventListener('click', this._click.bind(this));
-
- DomChangeListener.add('WoltLab/WCF/Controller/Media/Manager', this._addButtonEventListeners.bind(this));
- };
- MediaManager.prototype = {
- /**
- * Adds click event listeners to media buttons.
- */
- _addButtonEventListeners: function() {
- if (!this._mediaManagerMediaList) return;
-
- var listItems = DomTraverse.childrenByTag(this._mediaManagerMediaList, 'LI');
- for (var i = 0, length = listItems.length; i < length; i++) {
- var listItem = listItems[i];
-
- if (Permission.get('admin.content.cms.canManageMedia')) {
- var editIcon = elByClass('jsMediaEditIcon', listItem)[0];
- if (editIcon) {
- editIcon.classList.remove('jsMediaEditIcon');
- editIcon.addEventListener('click', this._editMedia.bind(this));
- }
- }
-
- var insertIcon = elByClass('jsMediaInsertIcon', listItem)[0];
- if (insertIcon) {
- insertIcon.classList.remove('jsMediaInsertIcon');
- insertIcon.addEventListener('click', this._openInsertDialog.bind(this));
- }
- }
- },
-
- /**
- * Handles clicks on the media manager button.
- *
- * @param {object} event event object
- */
- _click: function(event) {
- event.preventDefault();
-
- UiDialog.open(this);
- },
-
- /**
- * Reacts to executed clipboard actions.
- *
- * @param {object<string, *>} actionData data of the executed clipboard action
- */
- _clipboardAction: function(actionData) {
- // only consider events if the action has been executed
- if (actionData.responseData === null) {
- return;
- }
-
- switch (actionData.data.actionName) {
- case 'com.woltlab.wcf.media.delete':
- var mediaIds = actionData.responseData.objectIDs;
- for (var i = 0, length = mediaIds.length; i < length; i++) {
- this.removeMedia(~~mediaIds[i], true);
- }
-
- UiNotification.show();
-
- break;
- case 'com.woltlab.wcf.media.insert':
- // TODO
- break;
- }
- },
-
- /**
- * Returns all data to setup the media manager dialog.
- *
- * @return {object} dialog setup data
- */
- _dialogSetup: function() {
- return {
- id: 'mediaManager',
- options: {
- title: Language.get('wcf.media.manager')
- },
- source: {
- after: this._initDialog.bind(this),
- data: {
- actionName: 'getManagementDialog',
- className: 'wcf\\data\\media\\MediaAction'
- }
- }
- };
- },
-
- /**
- * Opens the media editor for a media file.
- *
- * @param {Event} event event object for clicks on edit icons
- */
- _editMedia: function(event) {
- if (!Permission.get('admin.content.cms.canManageMedia')) {
- throw new Error("You are not allowed to edit media files.");
- }
-
- UiDialog.close('mediaManager');
-
- this._mediaEditor.edit(this._mediaData.get(~~elData(event.currentTarget, 'object-id')));
- },
-
- /**
- * Re-opens the manager dialog after closing the editor dialog.
- */
- _editorClose: function() {
- UiDialog.open(this);
- },
-
- /**
- * Re-opens the manager dialog and updates the media data after
- * successfully editing a media file.
- *
- * @param {object} media updated media file data
- */
- _editorSuccess: function(media) {
- UiDialog.open(this);
-
- this._mediaData.set(~~media.mediaID, media);
-
- var listItem = this._media.get(~~media.mediaID);
- var p = elByClass('mediaTitle', listItem)[0];
- if (media.isMultilingual) {
- p.textContent = media.title[LANGUAGE_ID] || media.filename;
- }
- else {
- p.textContent = media.title[media.languageID] || media.filename;
- }
- },
-
- /**
- * Initializes the dialog when first loaded.
- *
- * @param {string} content dialog content
- * @param {object} data AJAX request's response data
- */
- _initDialog: function(content, data) {
- // store media data locally
- var media = data.returnValues.media || { };
- for (var mediaId in media) {
- if (media.hasOwnProperty(mediaId)) {
- this._mediaData.set(~~mediaId, media[mediaId]);
- }
- }
-
- this._mediaManagerMediaList = elById('mediaManagerMediaList');
-
- // store list items locally
- var listItems = DomTraverse.childrenByTag(this._mediaManagerMediaList, 'LI');
- for (var i = 0, length = listItems.length; i < length; i++) {
- var listItem = listItems[i];
-
- this._media.set(~~elData(listItem, 'object-id'), listItem);
- }
-
- if (Permission.get('admin.content.cms.canManageMedia')) {
- new MediaUpload('mediaManagerMediaUploadButton', 'mediaManagerMediaList', {
- mediaManager: this
- });
-
- Clipboard.setup({
- hasMarkedItems: data.returnValues.hasMarkedItems ? true : false,
- pageClassName: '*'
- });
-
- EventHandler.add('com.woltlab.wcf.clipboard', 'com.woltlab.wcf.media', this._clipboardAction.bind(this));
- }
-
- this._search = new MediaSearch(this);
-
- if (!listItems.length) {
- this._search.hideSearch();
-
- if (true) {
- elById('mediaManagerMediaUploadButton').classList.remove('marginTop');
- }
- }
- },
-
- _insertMedia: function() {
- // TODO
- },
-
- _openInsertDialog: function(event) {
- var media = this._mediaData.get(~~elData(event.currentTarget, 'object-id'));
-
- // check if media file is image and has at least small thumbnail
- // to show insertion options
- if (media.isImage && media.smallThumbnailType) {
- UiDialog.close(this);
- var dialogId = 'mediaInsert' + media.mediaID;
- if (UiDialog.getDialog(dialogId)) {
- UiDialog.openStatic(dialogId);
- }
- else {
- var dialog = elCreate('div');
-
- var fieldset = elCreate('fieldset');
- dialog.appendChild(fieldset);
-
- var dl = elCreate('dl');
- fieldset.appendChild(dl);
-
- var dt = elCreate('dt');
- dt.textContent = Language.get('wcf.media.insert.imageSize');
- dl.appendChild(dt);
-
- var dd = elCreate('dd');
- dl.appendChild(dd);
-
- var select = elCreate('select');
- dd.appendChild(select);
-
- var sizes = ['small', 'medium', 'large'];
- var size, option;
- for (var i = 0, length = sizes.length; i < length; i++) {
- size = sizes[i];
-
- if (media[size + 'ThumbnailType']) {
- option = elCreate('option');
- elAttr(option, 'value', size);
- option.textContent = Language.get('wcf.media.insert.imageSize.' + size, {
- height: media[size + 'ThumbnailHeight'],
- width: media[size + 'ThumbnailWidth']
- });
- select.appendChild(option);
- }
- }
-
- option = elCreate('option');
- elAttr(option, 'value', 'original');
- option.textContent = Language.get('wcf.media.insert.imageSize.original', {
- height: media.height,
- width: media.width
- });
- select.appendChild(option);
-
- var formSubmit = elCreate('div');
- formSubmit.className = 'formSubmit';
- dialog.appendChild(formSubmit);
-
- var submitButton = elCreate('button');
- submitButton.className = 'buttonPrimary';
- submitButton.textContent = Language.get('wcf.global.button.insert');
- elData(submitButton, 'object-id', media.mediaID);
- submitButton.addEventListener('click', this._insertMedia.bind(this));
- formSubmit.appendChild(submitButton);
-
- UiDialog.open({
- _dialogSetup: (function() {
- return {
- id: dialogId,
- options: {
- onClose: this._editorClose.bind(this),
- title: Language.get('wcf.media.insert')
- },
- source: dialog.outerHTML
- }
- }).bind(this)
- });
- }
- }
- else {
- // insert media
- // TODO
- }
- },
-
- _setMedia: function(media, listItems) {
- if (Core.isPlainObject(media)) {
- this._media = Dictionary.fromObject(media);
- }
- else {
- this._media = media;
- }
-
- var info = DomTraverse.nextByClass(this._mediaManagerMediaList, 'info');
-
- if (this._media.size) {
- if (info) {
- elHide(info);
- }
- }
- else {
- if (info === null) {
- info = elCreate('p');
- info.className = 'info';
- info.textContent = Language.get('wcf.media.search.noResults');
- }
-
- elShow(info);
- DomUtil.insertAfter(info, this._mediaManagerMediaList);
- }
-
- var mediaListItems = DomTraverse.childrenByTag(this._mediaManagerMediaList, 'LI');
- for (var i = 0, length = mediaListItems.length; i < length; i++) {
- var listItem = mediaListItems[i];
-
- if (!this._media.has(elData(listItem, 'object-id'))) {
- elHide(listItem);
- }
- else {
- elShow(listItem);
- }
- }
-
- DomChangeListener.trigger();
-
- Clipboard.reload();
- },
-
- /**
- * Adds a media file to the manager.
- *
- * @param {object} media data of the media file
- * @param {Element} listItem list item representing the file
- */
- addMedia: function(media, listItem) {
- if (!media.languageID) media.isMultilingual = 1;
-
- this._mediaData.set(~~media.mediaID, media);
- this._media.set(~~media.mediaID, listItem);
-
- if (this._media.size === 1) {
- this._search.showSearch();
-
- if (true) {
- elById('mediaManagerMediaUploadButton').classList.add('marginTop');
- }
- }
- },
-
- /**
- * Removes a media file.
- *
- * @param {int} mediaId id of the removed media file
- * @param {boolean|undefined} checkCache media file will also be removed from the local cache if true
- */
- removeMedia: function(mediaId, checkCache) {
- if (this._media.has(mediaId)) {
- // remove list item
- elRemove(this._media.get(mediaId));
-
- this._media.delete(mediaId);
- this._mediaData.delete(mediaId);
- }
-
- if (checkCache && this._mediaCache && this._mediaCache.has(mediaId)) {
- this._mediaCache.delete(mediaId);
- }
- },
-
- /**
- * Changes the displayed media to the previously displayed media.
- */
- resetMedia: function() {
- if (this._mediaCache !== null) {
- this._setMedia(this._mediaCache);
-
- this._mediaCache = null;
-
- this._search.resetSearch();
- }
- },
-
- /**
- * Sets the media files currently displayed.
- *
- * @param {object} media media data
- * @param {string} template
- */
- setMedia: function(media, template) {
- if (!this._mediaCache) {
- this._mediaCache = this._media;
- }
-
- var hasMedia = false;
- for (var mediaId in media) {
- if (media.hasOwnProperty(mediaId)) {
- hasMedia = true;
- }
- }
-
- var newListItems = [];
- if (hasMedia) {
- var ul = elCreate('ul');
- ul.innerHTML = template;
-
- var listItems = DomTraverse.childrenByTag(ul, 'LI');
- for (var i = 0, length = listItems.length; i < length; i++) {
- var listItem = listItems[i];
- if (!this._mediaData.has(~~elData(listItem, 'object-id'))) {
- this._mediaData.set(elData(listItem, 'object-id'), listItem);
-
- this._mediaManagerMediaList.appendChild(listItem);
- }
- }
- }
-
- this._setMedia(media);
- }
- };
-
- return MediaManager;
-});
--- /dev/null
+/**
+ * Provides the media manager dialog.
+ *
+ * @author Matthias Schmidt
+ * @copyright 2001-2015 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @module WoltLab/WCF/Media/Manager/Base
+ */
+define(
+ [
+ 'Core', 'Dictionary', 'Dom/ChangeListener', 'Dom/Traverse',
+ 'Dom/Util', 'EventHandler', 'Language', 'List',
+ 'Permission', 'Ui/Dialog', 'Ui/Notification', 'WoltLab/WCF/Controller/Clipboard',
+ 'WoltLab/WCF/Media/Editor', 'WoltLab/WCF/Media/Upload', 'WoltLab/WCF/Media/Search'
+ ],
+ function(
+ Core, Dictionary, DomChangeListener, DomTraverse,
+ DomUtil, EventHandler, Language, List,
+ Permission, UiDialog, UiNotification, Clipboard,
+ MediaEditor, MediaUpload, MediaSearch
+ )
+{
+ "use strict";
+
+ /**
+ * @constructor
+ */
+ function MediaManagerBase(options) {
+ this._options = Core.extend({
+ dialogTitle: Language.get('wcf.media.manager'),
+ fileTypeFilters: {}
+ }, options);
+
+ this._media = new Dictionary();
+ this._mediaData = new Dictionary();
+ this._mediaCache = null;
+ this._mediaManagerMediaList = null;
+ this._search = null;
+
+ if (Permission.get('admin.content.cms.canManageMedia')) {
+ this._mediaEditor = new MediaEditor(this);
+ }
+
+ DomChangeListener.add('WoltLab/WCF/Media/Manager', this._addButtonEventListeners.bind(this));
+ };
+ MediaManagerBase.prototype = {
+ /**
+ * Adds click event listeners to media buttons.
+ */
+ _addButtonEventListeners: function() {
+ if (!this._mediaManagerMediaList) return;
+
+ var listItems = DomTraverse.childrenByTag(this._mediaManagerMediaList, 'LI');
+ for (var i = 0, length = listItems.length; i < length; i++) {
+ var listItem = listItems[i];
+
+ if (Permission.get('admin.content.cms.canManageMedia')) {
+ var editIcon = elByClass('jsMediaEditIcon', listItem)[0];
+ if (editIcon) {
+ editIcon.classList.remove('jsMediaEditIcon');
+ editIcon.addEventListener('click', this._editMedia.bind(this));
+ }
+ }
+ }
+ },
+
+ /**
+ * Handles clicks on the media manager button.
+ *
+ * @param {object} event event object
+ */
+ _click: function(event) {
+ event.preventDefault();
+
+ UiDialog.open(this);
+ },
+
+ /**
+ * Reacts to executed clipboard actions.
+ *
+ * @param {object<string, *>} actionData data of the executed clipboard action
+ */
+ _clipboardAction: function(actionData) {
+ // only consider events if the action has been executed
+ if (actionData.responseData === null) {
+ return;
+ }
+
+ switch (actionData.data.actionName) {
+ case 'com.woltlab.wcf.media.delete':
+ var mediaIds = actionData.responseData.objectIDs;
+ for (var i = 0, length = mediaIds.length; i < length; i++) {
+ this.removeMedia(~~mediaIds[i], true);
+ }
+
+ UiNotification.show();
+ break;
+ }
+ },
+
+ /**
+ * Returns all data to setup the media manager dialog.
+ *
+ * @return {object} dialog setup data
+ */
+ _dialogSetup: function() {
+ return {
+ id: 'mediaManager',
+ options: {
+ title: this._options.dialogTitle
+ },
+ source: {
+ after: this._initDialog.bind(this),
+ data: {
+ actionName: 'getManagementDialog',
+ className: 'wcf\\data\\media\\MediaAction',
+ parameters: {
+ mode: this.getMode(),
+ fileTypeFilters: this._options.fileTypeFilters
+ }
+ }
+ }
+ };
+ },
+
+ /**
+ * Opens the media editor for a media file.
+ *
+ * @param {Event} event event object for clicks on edit icons
+ */
+ _editMedia: function(event) {
+ if (!Permission.get('admin.content.cms.canManageMedia')) {
+ throw new Error("You are not allowed to edit media files.");
+ }
+
+ UiDialog.close('mediaManager');
+
+ this._mediaEditor.edit(this._mediaData.get(~~elData(event.currentTarget, 'object-id')));
+ },
+
+ /**
+ * Re-opens the manager dialog after closing the editor dialog.
+ */
+ _editorClose: function() {
+ UiDialog.open(this);
+ },
+
+ /**
+ * Re-opens the manager dialog and updates the media data after
+ * successfully editing a media file.
+ *
+ * @param {object} media updated media file data
+ */
+ _editorSuccess: function(media) {
+ UiDialog.open(this);
+
+ this._mediaData.set(~~media.mediaID, media);
+
+ var listItem = this._media.get(~~media.mediaID);
+ var p = elByClass('mediaTitle', listItem)[0];
+ if (media.isMultilingual) {
+ p.textContent = media.title[LANGUAGE_ID] || media.filename;
+ }
+ else {
+ p.textContent = media.title[media.languageID] || media.filename;
+ }
+ },
+
+ /**
+ * Initializes the dialog when first loaded.
+ *
+ * @param {string} content dialog content
+ * @param {object} data AJAX request's response data
+ */
+ _initDialog: function(content, data) {
+ // store media data locally
+ var media = data.returnValues.media || { };
+ for (var mediaId in media) {
+ if (media.hasOwnProperty(mediaId)) {
+ this._mediaData.set(~~mediaId, media[mediaId]);
+ }
+ }
+
+ this._mediaManagerMediaList = elById('mediaManagerMediaList');
+
+ // store list items locally
+ var listItems = DomTraverse.childrenByTag(this._mediaManagerMediaList, 'LI');
+ for (var i = 0, length = listItems.length; i < length; i++) {
+ var listItem = listItems[i];
+
+ this._media.set(~~elData(listItem, 'object-id'), listItem);
+ }
+
+ if (Permission.get('admin.content.cms.canManageMedia')) {
+ new MediaUpload('mediaManagerMediaUploadButton', 'mediaManagerMediaList', {
+ mediaManager: this
+ });
+
+ Clipboard.setup({
+ hasMarkedItems: data.returnValues.hasMarkedItems ? true : false,
+ pageClassName: '*'
+ });
+
+ EventHandler.add('com.woltlab.wcf.clipboard', 'com.woltlab.wcf.media', this._clipboardAction.bind(this));
+ }
+
+ this._search = new MediaSearch(this);
+
+ if (!listItems.length) {
+ this._search.hideSearch();
+
+ if (true) {
+ elById('mediaManagerMediaUploadButton').classList.remove('marginTop');
+ }
+ }
+ },
+
+ /**
+ * Sets the displayed media (after a search).
+ *
+ * @param {Dictionary} media media to be set as active
+ */
+ _setMedia: function(media) {
+ if (Core.isPlainObject(media)) {
+ this._media = Dictionary.fromObject(media);
+ }
+ else {
+ this._media = media;
+ }
+
+ var info = DomTraverse.nextByClass(this._mediaManagerMediaList, 'info');
+
+ if (this._media.size) {
+ if (info) {
+ elHide(info);
+ }
+ }
+ else {
+ if (info === null) {
+ info = elCreate('p');
+ info.className = 'info';
+ info.textContent = Language.get('wcf.media.search.noResults');
+ }
+
+ elShow(info);
+ DomUtil.insertAfter(info, this._mediaManagerMediaList);
+ }
+
+ var mediaListItems = DomTraverse.childrenByTag(this._mediaManagerMediaList, 'LI');
+ for (var i = 0, length = mediaListItems.length; i < length; i++) {
+ var listItem = mediaListItems[i];
+
+ if (!this._media.has(elData(listItem, 'object-id'))) {
+ elHide(listItem);
+ }
+ else {
+ elShow(listItem);
+ }
+ }
+
+ DomChangeListener.trigger();
+
+ Clipboard.reload();
+ },
+
+ /**
+ * Adds a media file to the manager.
+ *
+ * @param {object} media data of the media file
+ * @param {Element} listItem list item representing the file
+ */
+ addMedia: function(media, listItem) {
+ if (!media.languageID) media.isMultilingual = 1;
+
+ this._mediaData.set(~~media.mediaID, media);
+ this._media.set(~~media.mediaID, listItem);
+
+ if (this._media.size === 1) {
+ this._search.showSearch();
+
+ if (true) {
+ elById('mediaManagerMediaUploadButton').classList.add('marginTop');
+ }
+ }
+ },
+
+ /**
+ * Returns the mode of the media manager.
+ *
+ * @return {string}
+ */
+ getMode: function() {
+ return '';
+ },
+
+ /**
+ * Returns the media manager option with the given name.
+ *
+ * @param {string} name option name
+ * @return {mixed} option value or null
+ */
+ getOption: function(name) {
+ if (this._options[name]) {
+ return this._options[name];
+ }
+
+ return null;
+ },
+
+ /**
+ * Removes a media file.
+ *
+ * @param {int} mediaId id of the removed media file
+ * @param {boolean|undefined} checkCache media file will also be removed from the local cache if true
+ */
+ removeMedia: function(mediaId, checkCache) {
+ if (this._media.has(mediaId)) {
+ // remove list item
+ elRemove(this._media.get(mediaId));
+
+ this._media.delete(mediaId);
+ this._mediaData.delete(mediaId);
+ }
+
+ if (checkCache && this._mediaCache && this._mediaCache.has(mediaId)) {
+ this._mediaCache.delete(mediaId);
+ }
+ },
+
+ /**
+ * Changes the displayed media to the previously displayed media.
+ */
+ resetMedia: function() {
+ if (this._mediaCache !== null) {
+ this._setMedia(this._mediaCache);
+
+ this._mediaCache = null;
+
+ this._search.resetSearch();
+ }
+ },
+
+ /**
+ * Sets the media files currently displayed.
+ *
+ * @param {object} media media data
+ * @param {string} template
+ */
+ setMedia: function(media, template) {
+ if (!this._mediaCache) {
+ this._mediaCache = this._media;
+ }
+
+ var hasMedia = false;
+ for (var mediaId in media) {
+ if (media.hasOwnProperty(mediaId)) {
+ hasMedia = true;
+ }
+ }
+
+ var newListItems = [];
+ if (hasMedia) {
+ var ul = elCreate('ul');
+ ul.innerHTML = template;
+
+ var listItems = DomTraverse.childrenByTag(ul, 'LI');
+ for (var i = 0, length = listItems.length; i < length; i++) {
+ var listItem = listItems[i];
+ if (!this._mediaData.has(~~elData(listItem, 'object-id'))) {
+ this._mediaData.set(elData(listItem, 'object-id'), listItem);
+
+ this._mediaManagerMediaList.appendChild(listItem);
+ }
+ }
+ }
+
+ this._setMedia(media);
+ },
+
+ /**
+ * Sets up a new media element.
+ *
+ * @param {object} media data of the media file
+ * @param {HTMLElement} mediaElement element representing the media file
+ */
+ setupMediaElement: function(media, mediaElement) {
+ var mediaInformation = DomTraverse.childByClass(mediaElement, 'mediaInformation');
+
+ var buttonGroupNavigation = elCreate('nav');
+ buttonGroupNavigation.className = 'buttonGroupNavigation';
+ mediaInformation.parentNode.appendChild(buttonGroupNavigation);
+
+ var smallButtons = elCreate('ul');
+ smallButtons.className = 'smallButtons buttonGroup';
+ buttonGroupNavigation.appendChild(smallButtons);
+
+ var listItem = elCreate('li');
+ smallButtons.appendChild(listItem);
+
+ var checkbox = elCreate('input');
+ checkbox.className = 'jsClipboardItem jsMediaCheckbox';
+ elAttr(checkbox, 'type', 'checkbox');
+ elData(checkbox, 'object-id', media.mediaID);
+ listItem.appendChild(checkbox);
+
+ if (Permission.get('admin.content.cms.canManageMedia')) {
+ listItem = elCreate('li');
+ smallButtons.appendChild(listItem);
+
+ var a = elCreate('a');
+ listItem.appendChild(a);
+
+ var icon = elCreate('span');
+ icon.className = 'icon icon16 fa-pencil jsTooltip jsMediaEditIcon';
+ elData(icon, 'object-id', media.mediaID);
+ elAttr(icon, 'title', Language.get('wcf.global.button.edit'));
+ a.appendChild(icon);
+
+ listItem = elCreate('li');
+ smallButtons.appendChild(listItem);
+
+ a = elCreate('a');
+ listItem.appendChild(a);
+
+ icon = elCreate('span');
+ icon.className = 'icon icon16 fa-times jsTooltip jsMediaDeleteIcon';
+ elData(icon, 'object-id', media.mediaID);
+ elAttr(icon, 'title', Language.get('wcf.global.button.delete'));
+ a.appendChild(icon);
+ }
+ }
+ };
+
+ return MediaManagerBase;
+});
--- /dev/null
+/**
+ * Provides the media manager dialog for selecting media for input elements.
+ *
+ * @author Matthias Schmidt
+ * @copyright 2001-2015 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @module WoltLab/WCF/Media/Manager/Editor
+ */
+define(['Core', 'Dom/Traverse', 'Language', 'Ui/Dialog', 'WoltLab/WCF/Media/Manager/Base'], function(Core, DomTraverse, Language, UiDialog, MediaManagerBase) {
+ "use strict";
+
+ /**
+ * @constructor
+ */
+ function MediaManagerEditor(options) {
+ MediaManagerBase.call(this, options);
+
+ this._activeButton = null;
+ this._buttons = elByClass(this._options.buttonClass || 'jsMediaEditorButton');
+ for (var i = 0, length = this._buttons.length; i < length; i++) {
+ this._buttons[i].addEventListener('click', this._click.bind(this));
+ }
+
+ this._activeButton = null;
+ };
+ Core.inherit(MediaManagerEditor, MediaManagerBase, {
+ /**
+ * @see WoltLab/WCF/Media/Manager/base#_addButtonEventListeners
+ */
+ _addButtonEventListeners: function() {
+ MediaManagerEditor._super.prototype._addButtonEventListeners.call(this);
+
+ if (!this._mediaManagerMediaList) return;
+
+ var listItems = DomTraverse.childrenByTag(this._mediaManagerMediaList, 'LI');
+ for (var i = 0, length = listItems.length; i < length; i++) {
+ var listItem = listItems[i];
+
+ var insertIcon = elByClass('jsMediaInsertIcon', listItem)[0];
+ if (insertIcon) {
+ insertIcon.classList.remove('jsMediaInsertIcon');
+ insertIcon.addEventListener('click', this._openInsertDialog.bind(this));
+ }
+ }
+ },
+
+ /**
+ * @see WoltLab/WCF/Media/Manager/base#_click
+ */
+ _click: function(event) {
+ this._activeButton = event.currentTarget;
+
+ MediaManagerEditor._super.prototype._click.call(this, event);
+ },
+
+ _insertMedia: function() {
+ // TODO
+ },
+
+ _openInsertDialog: function(event) {
+ var media = this._mediaData.get(~~elData(event.currentTarget, 'object-id'));
+
+ // check if media file is image and has at least small thumbnail
+ // to show insertion options
+ if (media.isImage && media.smallThumbnailType) {
+ UiDialog.close(this);
+ var dialogId = 'mediaInsert' + media.mediaID;
+ if (UiDialog.getDialog(dialogId)) {
+ UiDialog.openStatic(dialogId);
+ }
+ else {
+ var dialog = elCreate('div');
+
+ var fieldset = elCreate('fieldset');
+ dialog.appendChild(fieldset);
+
+ var dl = elCreate('dl');
+ fieldset.appendChild(dl);
+
+ var dt = elCreate('dt');
+ dt.textContent = Language.get('wcf.media.insert.imageSize');
+ dl.appendChild(dt);
+
+ var dd = elCreate('dd');
+ dl.appendChild(dd);
+
+ var select = elCreate('select');
+ dd.appendChild(select);
+
+ var sizes = ['small', 'medium', 'large'];
+ var size, option;
+ for (var i = 0, length = sizes.length; i < length; i++) {
+ size = sizes[i];
+
+ if (media[size + 'ThumbnailType']) {
+ option = elCreate('option');
+ elAttr(option, 'value', size);
+ option.textContent = Language.get('wcf.media.insert.imageSize.' + size, {
+ height: media[size + 'ThumbnailHeight'],
+ width: media[size + 'ThumbnailWidth']
+ });
+ select.appendChild(option);
+ }
+ }
+
+ option = elCreate('option');
+ elAttr(option, 'value', 'original');
+ option.textContent = Language.get('wcf.media.insert.imageSize.original', {
+ height: media.height,
+ width: media.width
+ });
+ select.appendChild(option);
+
+ var formSubmit = elCreate('div');
+ formSubmit.className = 'formSubmit';
+ dialog.appendChild(formSubmit);
+
+ var submitButton = elCreate('button');
+ submitButton.className = 'buttonPrimary';
+ submitButton.textContent = Language.get('wcf.global.button.insert');
+ elData(submitButton, 'object-id', media.mediaID);
+ submitButton.addEventListener('click', this._insertMedia.bind(this));
+ formSubmit.appendChild(submitButton);
+
+ UiDialog.open({
+ _dialogSetup: (function() {
+ return {
+ id: dialogId,
+ options: {
+ onClose: this._editorClose.bind(this),
+ title: Language.get('wcf.media.insert')
+ },
+ source: dialog.outerHTML
+ }
+ }).bind(this)
+ });
+ }
+ }
+ else {
+ // insert media
+ // TODO
+ }
+ },
+
+ /**
+ * @see WoltLab/WCF/Media/Manager/Base#getMode
+ */
+ getMode: function() {
+ return 'editor';
+ },
+
+ /**
+ * @see WoltLab/WCF/Media/Manager/Base#setupMediaElement
+ */
+ setupMediaElement: function(media, mediaElement) {
+ MediaManagerEditor._super.prototype.setupMediaElement.call(this, media, mediaElement);
+
+ // add media insertion icon
+ var smallButtons = elBySel('> nav.buttonGroupNavigation > ul.smallButtons', mediaElement);
+
+ var listItem = elCreate('li');
+ smallButtons.appendChild(listItem);
+
+ var a = elCreate('a');
+ listItem.appendChild(a);
+
+ var icon = elCreate('span');
+ icon.className = 'icon icon16 fa-plus jsTooltip jsMediaInsertIcon';
+ elData(icon, 'object-id', media.mediaID);
+ elAttr(icon, 'title', Language.get('wcf.media.button.insert'));
+ a.appendChild(icon);
+ }
+ });
+
+ return MediaManagerEditor;
+});
--- /dev/null
+/**
+ * Provides the media manager dialog for selecting media for input elements.
+ *
+ * @author Matthias Schmidt
+ * @copyright 2001-2015 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @module WoltLab/WCF/Media/Manager/Select
+ */
+define(['Core', 'Dom/Traverse', 'Language', 'Ui/Dialog', 'WoltLab/WCF/Media/Manager/Base'], function(Core, DomTraverse, Language, UiDialog, MediaManagerBase) {
+ "use strict";
+
+ /**
+ * @constructor
+ */
+ function MediaManagerSelect(options) {
+ MediaManagerBase.call(this, options);
+
+ this._activeButton = null;
+ this._buttons = elByClass(this._options.buttonClass || 'jsMediaSelectButton');
+ for (var i = 0, length = this._buttons.length; i < length; i++) {
+ var button = this._buttons[i];
+
+ // only consider buttons with a proper store specified
+ var store = elData(button, 'store');
+ if (store) {
+ var storeElement = elById(store);
+ if (storeElement && storeElement.tagName === 'INPUT') {
+ this._buttons[i].addEventListener('click', this._click.bind(this));
+ }
+ }
+ }
+ };
+ Core.inherit(MediaManagerSelect, MediaManagerBase, {
+ /**
+ * @see WoltLab/WCF/Media/Manager/base#_addButtonEventListeners
+ */
+ _addButtonEventListeners: function() {
+ MediaManagerSelect._super.prototype._addButtonEventListeners.call(this);
+
+ if (!this._mediaManagerMediaList) return;
+
+ var listItems = DomTraverse.childrenByTag(this._mediaManagerMediaList, 'LI');
+ for (var i = 0, length = listItems.length; i < length; i++) {
+ var listItem = listItems[i];
+
+ var chooseIcon = elByClass('jsMediaSelectIcon', listItem)[0];
+ if (chooseIcon) {
+ chooseIcon.classList.remove('jsMediaSelectIcon');
+ chooseIcon.addEventListener('click', this._chooseMedia.bind(this));
+ }
+ }
+ },
+
+ /**
+ * Handles clicking on a media choose icon.
+ *
+ * @param {Event} event click event
+ */
+ _chooseMedia: function(event) {
+ if (this._activeButton === null) {
+ throw new Error("Media cannot be chosen if no button is active.");
+ }
+
+ var media = this._mediaData.get(~~elData(event.currentTarget, 'object-id'));
+
+ // save selected media in store element
+ elById(elData(this._activeButton, 'store')).value = media.mediaID;
+
+ // display selected media
+ var display = elData(this._activeButton, 'display');
+ if (display) {
+ var displayElement = elById(display);
+ if (displayElement) {
+ // TODO: add visual representation of the media file to display element
+
+ if (media.isImage) {
+ displayElement.innerHTML = '<img src="' + media.smallThumbnailLink + '" alt="' + media.altText + '" />';
+ }
+ }
+ }
+
+ UiDialog.close('mediaManager');
+ },
+
+ /**
+ * @see WoltLab/WCF/Media/Manager/Base#_click
+ */
+ _click: function(event) {
+ this._activeButton = event.currentTarget;
+
+ MediaManagerSelect._super.prototype._click.call(this, event);
+
+ // TODO: highlight selected medium?
+ },
+
+ /**
+ * @see WoltLab/WCF/Media/Manager/Base#getMode
+ */
+ getMode: function() {
+ return 'select';
+ },
+
+ /**
+ * @see WoltLab/WCF/Media/Manager/Base#setupMediaElement
+ */
+ setupMediaElement: function(media, mediaElement) {
+ MediaManagerSelect._super.prototype.setupMediaElement.call(this, media, mediaElement);
+
+ // add media insertion icon
+ var smallButtons = elBySel('nav.buttonGroupNavigation > ul.smallButtons', mediaElement);
+
+ var listItem = elCreate('li');
+ smallButtons.appendChild(listItem);
+
+ var a = elCreate('a');
+ listItem.appendChild(a);
+
+ var icon = elCreate('span');
+ icon.className = 'icon icon16 fa-check jsTooltip jsMediaSelectIcon';
+ elData(icon, 'object-id', media.mediaID);
+ elAttr(icon, 'title', Language.get('wcf.media.button.choose'));
+ a.appendChild(icon);
+ }
+ });
+
+ return MediaManagerSelect;
+});
* @author Matthias Schmidt
* @copyright 2001-2015 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @module WoltLab/WCF/Controller/Media/Search
+ * @module WoltLab/WCF/Media/Search
*/
define(['Ajax', 'Dom/Traverse', 'Dom/Util', 'Language', 'Ui/SimpleDropdown'], function(Ajax, DomTraverse, DomUtil, Language, UiSimpleDropdown) {
"use strict";
this._cancelButton = elById('mediaManagerSearchCancelButton');
this._cancelButton.addEventListener('click', this._cancelSearch.bind(this));
- this._fileTypes = DomTraverse.childrenBySel(UiSimpleDropdown.getDropdownMenu('mediaManagerSearch'), 'li:not(.dropdownDivider)');
- var selectFileType = this._selectFileType.bind(this);
- for (var i = 0, length = this._fileTypes.length; i < length; i++) {
- this._fileTypes[i].addEventListener('click', selectFileType);
+ var dropdown = UiSimpleDropdown.getDropdownMenu('mediaManagerSearch');
+ if (dropdown) {
+ this._fileTypes = DomTraverse.childrenBySel(dropdown, 'li:not(.dropdownDivider)');
+ var selectFileType = this._selectFileType.bind(this);
+ for (var i = 0, length = this._fileTypes.length; i < length; i++) {
+ this._fileTypes[i].addEventListener('click', selectFileType);
+ }
+
+ UiSimpleDropdown.registerCallback('mediaManagerSearch', this._updateFileTypeDropdown.bind(this));
+ }
+ else {
+ this._fileType = null;
}
-
- UiSimpleDropdown.registerCallback('mediaManagerSearch', this._updateFileTypeDropdown.bind(this));
};
MediaSearch.prototype = {
/**
/**
* Handles the `[ENTER]` key to submit the form.
*
- * @param {Event} event event object
+ * @param {Event} event event object
*/
_keyPress: function(event) {
// 13 = [ENTER]
if (event.charCode === 13) {
event.preventDefault();
-
- var innerInfo = DomTraverse.childByClass(this._input.parentNode, '.innerInfo');
+
+ var innerInfo = DomTraverse.childByClass(this._input.parentNode.parentNode, 'innerInfo');
// TODO: treshold option?
if (this._input.value.length >= 3) {
if (innerInfo) {
elHide(innerInfo);
}
-
+
this._search();
}
else {
innerInfo = elCreate('p');
innerInfo.className = 'innerInfo';
innerInfo.textContent = Language.get('wcf.media.search.info.searchStringTreshold');
-
- this._input.parentNode.appendChild(innerInfo);
+
+ DomUtil.insertAfter(innerInfo, this._input.parentNode);
}
}
}
Ajax.api(this, {
parameters: {
- data: {
- fileType: this._fileType,
- // TODO: treshold option?
- searchString: this._input.value.length > 3 ? this._input.value : ''
- }
+ fileType: this._fileType,
+ fileTypeFilters: this._mediaManager.getOption('fileTypeFilters'),
+ mode: this._mediaManager.getMode(),
+ searchString: this._input.value
}
});
},
-
+
/**
* Selects a certain file type after clicking on it in the dropdown menu.
*
- * @param {Event} event
- */
+ * @param {Event} event
+ */
_selectFileType: function(event) {
this._fileType = elData(event.currentTarget, 'file-type');
this._search();
},
-
+
/**
* Updates the label of the dropdown button based on the currently selected file type.
- */
+ */
_updateDropdownButtonLabel: function() {
var dropdown = UiSimpleDropdown.getDropdown('mediaManagerSearch');
var buttonLabel = DomTraverse.childBySel(DomTraverse.childByClass(dropdown, 'dropdownToggle'), 'SPAN');
buttonLabel.textContent = Language.get('wcf.media.search.filetype');
}
},
-
+
/**
* Updates the file type dropdown by correctly marking the currently selected file type.
- */
+ */
_updateFileTypeDropdown: function() {
for (var i = 0, length = this._fileTypes.length; i < length; i++) {
var listItem = this._fileTypes[i];
-
+
listItem.classList[elData(listItem, 'file-type') === this._fileType ? 'add' : 'remove']('active');
}
},
hideSearch: function() {
elHide(elById('mediaManagerSearch'));
},
-
+
/**
* Resets the media search.
*/
* @author Matthias Schmidt
* @copyright 2001-2015 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @module WoltLab/WCF/Controller/Media/Upload
+ * @module WoltLab/WCF/Media/Upload
*/
define(
[
fileElement.appendChild(thumbnail);
var fileIcon = elCreate('span');
- fileIcon.className = 'icon icon96 fa-spinner';
+ fileIcon.className = 'icon icon144 fa-spinner';
thumbnail.appendChild(fileIcon);
var mediaInformation = elCreate('div');
return fileElement;
},
+ /**
+ * @see WoltLab/WCF/Upload#_getParameters
+ */
+ _getParameters: function() {
+ if (this._mediaManager) {
+ return Core.extend(MediaUpload._super.prototype._getParameters.call(this), {
+ fileTypeFilters: this._mediaManager.getOption('fileTypeFilters')
+ });
+ }
+
+ return MediaUpload._super.prototype._getParameters.call(this);
+ },
+
/**
* @see WoltLab/WCF/Upload#_success
*/
var internalFileId = elData(file, 'internal-file-id');
var media = data.returnValues.media[internalFileId];
+ elRemove(DomTraverse.childByTag(DomTraverse.childByClass(file, 'mediaInformation'), 'PROGRESS'));
+
if (media) {
var fileIcon = DomTraverse.childByTag(DomTraverse.childByClass(file, 'mediaThumbnail'), 'SPAN');
if (media.tinyThumbnailType) {
var img = elCreate('img');
elAttr(img, 'src', media.tinyThumbnailLink);
elAttr(img, 'alt', '');
- img.style.setProperty('width', '96px');
- img.style.setProperty('height', '96px');
+ img.style.setProperty('width', '144px');
+ img.style.setProperty('height', '144px');
parentNode.appendChild(img);
}
else {
file.className = 'jsClipboardObject';
elData(file, 'object-id', media.mediaID);
- var mediaInformation = DomTraverse.childByClass(file, 'mediaInformation');
-
- elRemove(DomTraverse.childByTag(mediaInformation, 'PROGRESS'));
-
if (this._mediaManager) {
- var buttonGroupNavigation = elCreate('nav');
- buttonGroupNavigation.className = 'buttonGroupNavigation';
- mediaInformation.parentNode.appendChild(buttonGroupNavigation);
-
- var smallButtons = elCreate('ul');
- smallButtons.className = 'smallButtons buttonGroup';
- buttonGroupNavigation.appendChild(smallButtons);
-
- var listItem = elCreate('li');
- smallButtons.appendChild(listItem);
-
- var checkbox = elCreate('input');
- checkbox.className = 'jsClipboardItem jsMediaCheckbox';
- elAttr(checkbox, 'type', 'checkbox');
- elData(checkbox, 'object-id', media.mediaID);
- listItem.appendChild(checkbox);
-
- if (Permission.get('admin.content.cms.canManageMedia')) {
- listItem = elCreate('li');
- smallButtons.appendChild(listItem);
-
- var a = elCreate('a');
- listItem.appendChild(a);
-
- var icon = elCreate('span');
- icon.className = 'icon icon16 fa-pencil jsTooltip jsMediaEditIcon';
- elData(icon, 'object-id', media.mediaID);
- elAttr(icon, 'title', Language.get('wcf.global.button.edit'));
- a.appendChild(icon);
-
- listItem = elCreate('li');
- smallButtons.appendChild(listItem);
-
- a = elCreate('a');
- listItem.appendChild(a);
-
- icon = elCreate('span');
- icon.className = 'icon icon16 fa-times jsTooltip jsMediaDeleteIcon';
- elData(icon, 'object-id', media.mediaID);
- elAttr(icon, 'title', Language.get('wcf.global.button.delete'));
- a.appendChild(icon);
- }
-
- listItem = elCreate('li');
- smallButtons.appendChild(listItem);
-
- var a = elCreate('a');
- listItem.appendChild(a);
-
- var icon = elCreate('span');
- icon.className = 'icon icon16 fa-plus jsTooltip jsMediaInsertIcon';
- elData(icon, 'object-id', media.mediaID);
- elAttr(icon, 'title', Language.get('wcf.media.button.insert'));
- a.appendChild(icon);
-
+ this._mediaManager.setupMediaElement(media, file);
this._mediaManager.resetMedia();
this._mediaManager.addMedia(media, file);
}
-
- DomChangeListener.trigger();
}
else {
- // error: TODO
+ var error = data.returnValues.errors[internalFileId];
+ if (!error) {
+ error = {
+ errorType: 'uploadFailed',
+ filename: elData(file, 'filename')
+ };
+ }
+
+ var fileIcon = DomTraverse.childByTag(DomTraverse.childByClass(file, 'mediaThumbnail'), 'SPAN');
+ fileIcon.classList.remove('fa-spinner');
+ fileIcon.classList.add('fa-remove');
+ fileIcon.classList.add('pointer');
+
+ file.classList.add('uploadFailed');
+ file.addEventListener('click', function() {
+ elRemove(this);
+ });
+
+ var title = DomTraverse.childByClass(DomTraverse.childByClass(file, 'mediaInformation'), 'mediaTitle');
+ title.innerText = Language.get('wcf.media.upload.error.' + error.errorType, {
+ filename: error.filename
+ });
}
+
+ DomChangeListener.trigger();
}
EventHandler.fire('com.woltlab.wcf.media.upload', 'success', {
var right = horizontal.right;
var vertical = this._tryAlignmentVertical(options.vertical, elDimensions, refDimensions, refOffsets, windowHeight, options.verticalOffset);
- console.debug(vertical);
if (!vertical.result && (options.allowFlip === 'both' || options.allowFlip === 'vertical')) {
var verticalFlipped = this._tryAlignmentVertical((options.vertical === 'top' ? 'bottom' : 'top'), elDimensions, refDimensions, refOffsets, windowHeight, options.verticalOffset);
// only use these results if it fits into the boundaries, otherwise both directions exceed and we honor the demanded direction
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
* @module WoltLab/WCF/Upload
*/
-define(['AjaxRequest', 'Core', 'Dom/ChangeListener', 'Language', 'Dom/Util'], function(AjaxRequest, Core, DomChangeListener, Language, DomUtil) {
+define(['AjaxRequest', 'Core', 'Dom/ChangeListener', 'Language', 'Dom/Util', 'Dom/Traverse'], function(AjaxRequest, Core, DomChangeListener, Language, DomUtil, DomTraverse) {
"use strict";
/**
else {
var p = elCreate('p');
p.appendChild(progress);
-
+
this._target.appendChild(p);
-
+
return p;
}
},
var fileElement = this._createFileElement(file);
if (!fileElement.classList.contains('uploadFailed')) {
- elAttr(fileElement, 'data-filename', file.name);
- elAttr(fileElement, 'data-internal-file-id', this._internalFileId++);
+ elData(fileElement, 'filename', file.name);
+ elData(fileElement, 'internal-file-id', this._internalFileId++);
this._fileElements[uploadId][i] = fileElement;
}
}
* @return {(integer|Array.<integer>|null)} identifier(s) for the uploaded files
*/
_upload: function(event, file, blob) {
+ // remove failed upload elements first
+ var failedUploads = DomTraverse.childrenByClass(this._target, 'uploadFailed');
+ for (var i = 0, length = failedUploads.length; i < length; i++) {
+ elRemove(failedUploads[i]);
+ }
+
var uploadId = null;
var files = [];
formData.append('actionName', this._options.action);
formData.append('className', this._options.className);
formData.append('interfaceName', 'wcf\\data\\IUploadAction');
- var additionalParameters = this._getParameters();
- for (var name in additionalParameters) {
- formData.append('parameters[' + name + ']', additionalParameters[name]);
- }
+
+ // recursively append additional parameters to form data
+ var appendFormData = function(parameters, prefix) {
+ prefix = prefix || '';
+
+ for (var name in parameters) {
+ if (typeof parameters[name] === 'object') {
+ appendFormData(parameters[name], prefix + '[' + name + ']');
+ }
+ else {
+ formData.append('parameters' + prefix + '[' + name + ']', parameters[name]);
+ }
+ }
+ };
+
+ appendFormData(this._getParameters());
var request = new AjaxRequest({
data: formData,
use wcf\data\box\Box;
use wcf\data\box\BoxAction;
use wcf\data\box\BoxEditor;
+use wcf\data\media\Media;
+use wcf\data\media\ViewableMediaList;
use wcf\form\AbstractForm;
use wcf\system\exception\UserInputException;
use wcf\system\language\LanguageFactory;
/**
* true if created box is multi-lingual
- * @var boolean
+ * @var boolean
*/
public $isMultilingual = 0;
/**
* box type
- * @var string
+ * @var string
*/
public $boxType = '';
/**
* box position
- * @var string
+ * @var string
*/
public $position = '';
/**
* show order
- * @var integer
+ * @var integer
*/
public $showOrder = 0;
/**
* true if created box is visible everywhere
- * @var boolean
+ * @var boolean
*/
public $visibleEverywhere = 1;
/**
* css class name of created box
- * @var string
+ * @var string
*/
public $cssClassName = '';
/**
* true if box header is visible
- * @var boolean
+ * @var boolean
*/
public $showHeader = 1;
/**
* php class name
- * @var string
+ * @var string
*/
public $className = '';
/**
* box name
- * @var string
+ * @var string
*/
public $name = '';
/**
* page titles
- * @var array<string>
+ * @var string[]
*/
public $title = [];
/**
* page contents
- * @var array<string>
+ * @var string[]
*/
public $content = [];
+ /**
+ * image ids
+ * @var integer[]
+ */
+ public $imageID = [];
+
+ /**
+ * images
+ * @var Media[]
+ */
+ public $images = [];
+
/**
* @inheritDoc
*/
if (isset($_POST['title']) && is_array($_POST['title'])) $this->title = ArrayUtil::trim($_POST['title']);
if (isset($_POST['content']) && is_array($_POST['content'])) $this->content = ArrayUtil::trim($_POST['content']);
+ if (WCF::getSession()->getPermission('admin.content.cms.canUseMedia')) {
+ if (isset($_POST['imageID']) && is_array($_POST['imageID'])) $this->imageID = ArrayUtil::toIntegerArray($_POST['imageID']);
+
+ $this->readBoxImages();
+ }
+ }
+
+ /**
+ * Reads the box images.
+ */
+ protected function readBoxImages() {
+ if (!empty($this->imageID)) {
+ $mediaList = new ViewableMediaList();
+ $mediaList->setObjectIDs($this->imageID);
+ $mediaList->readObjects();
+
+ foreach ($this->imageID as $languageID => $imageID) {
+ $image = $mediaList->search($imageID);
+ if ($image !== null && $image->isImage) {
+ $this->images[$languageID] = $image;
+ }
+ }
+ }
}
/**
}
// @todo check class
-
+ }
+
+ // validate images
+ if (WCF::getSession()->getPermission('admin.content.cms.canUseMedia')) {
+ foreach ($this->imageID as $languageID => $imageID) {
+ if (!isset($this->imageID[$languageID])) {
+ throw new UserInputException('imageID' . $languageID);
+ }
+ }
}
}
if ($this->isMultilingual) {
foreach (LanguageFactory::getInstance()->getLanguages() as $language) {
$content[$language->languageID] = [
- 'title' => (!empty($_POST['title'][$language->languageID]) ? $_POST['title'][$language->languageID] : ''),
- 'content' => (!empty($_POST['content'][$language->languageID]) ? $_POST['content'][$language->languageID] : '')
+ 'title' => (!empty($this->title[$language->languageID]) ? $this->title[$language->languageID] : ''),
+ 'content' => (!empty($this->content[$language->languageID]) ? $this->content[$language->languageID] : ''),
+ 'imageID' => (!empty($this->imageID[$language->languageID]) ? $this->imageID[$language->languageID] : null)
];
}
}
else {
$content[0] = [
- 'title' => (!empty($_POST['title'][0]) ? $_POST['title'][0] : ''),
- 'content' => (!empty($_POST['content'][0]) ? $_POST['content'][0] : '')
+ 'title' => (!empty($this->title[0]) ? $this->title[0] : ''),
+ 'content' => (!empty($this->content[0]) ? $this->content[0] : ''),
+ 'imageID' => (!empty($this->imageID[0]) ? $this->imageID[0] : null)
];
}
'showOrder' => $this->showOrder,
'visibleEverywhere' => $this->visibleEverywhere,
'cssClassName' => $this->cssClassName,
- 'showHeader' => $this->showHeader,
+ 'showHeader' => $this->showHeader,
'className' => $this->className,
'identifier' => ''
]), 'content' => $content]);
$returnValues = $this->objectAction->executeAction();
+
// set generic box identifier
$boxEditor = new BoxEditor($returnValues['returnValues']);
$boxEditor->update([
$this->boxType = $this->position = $this->cssClassName = $this->className = $this->name = '';
$this->showOrder = 0;
$this->visibleEverywhere = $this->showHeader = 1;
- $this->title = $this->content = [];
+ $this->title = $this->content = $this->images = $this->imageID = [];
}
/**
'showHeader' => $this->showHeader,
'title' => $this->title,
'content' => $this->content,
+ 'imageID' => $this->imageID,
+ 'images' => $this->images,
'availableLanguages' => LanguageFactory::getInstance()->getLanguages(),
'availableBoxTypes' => Box::$availableBoxTypes,
'availablePositions' => Box::$availablePositions
/**
* box id
- * @var integer
+ * @var integer
*/
public $boxID = 0;
/**
* box object
- * @var Box
+ * @var Box
*/
public $box = null;
$content[$language->languageID] = [
'title' => (!empty($_POST['title'][$language->languageID]) ? $_POST['title'][$language->languageID] : ''),
'content' => (!empty($_POST['content'][$language->languageID]) ? $_POST['content'][$language->languageID] : ''),
+ 'imageID' => (!empty($this->imageID[$language->languageID]) ? $this->imageID[$language->languageID] : null)
];
}
}
$content[0] = [
'title' => (!empty($_POST['title'][0]) ? $_POST['title'][0] : ''),
'content' => (!empty($_POST['content'][0]) ? $_POST['content'][0] : ''),
+ 'imageID' => (!empty($this->imageID[0]) ? $this->imageID[0] : null)
];
}
* @inheritDoc
*/
public function readData() {
+ if (!empty($_POST) && !WCF::getSession()->getPermission('admin.content.cms.canUseMedia')) {
+ foreach ($this->box->getBoxContent() as $languageID => $content) {
+ $this->imageID[$languageID] = $content['imageID'];
+ }
+
+ $this->readBoxImages();
+ }
+
parent::readData();
-
+
if (empty($_POST)) {
$this->name = $this->box->name;
$this->boxType = $this->box->boxType;
foreach ($this->box->getBoxContent() as $languageID => $content) {
$this->title[$languageID] = $content['title'];
$this->content[$languageID] = $content['content'];
+ $this->imageID[$languageID] = $content['imageID'];
}
+
+ $this->readBoxImages();
}
}
<?php
namespace wcf\acp\form;
-use wcf\data\media\Media;
use wcf\data\media\MediaAction;
+use wcf\data\media\ViewableMedia;
use wcf\form\AbstractForm;
use wcf\system\exception\IllegalLinkException;
use wcf\system\exception\UserInputException;
/**
* edited media
- * @var Media
+ * @var ViewableMedia
*/
public $media = null;
if (isset($_REQUEST['id'])) $this->mediaID = intval($_REQUEST['id']);
- $this->media = new Media($this->mediaID);
- if (!$this->media->mediaID) {
+ $this->media = ViewableMedia::getMedia($this->mediaID);
+ if ($this->media === null) {
throw new IllegalLinkException();
}
public function save() {
parent::save();
- $this->objectAction = new MediaAction([$this->media], 'update', [
+ $this->objectAction = new MediaAction([$this->media->getDecoratedObject()], 'update', array_merge($this->additionalFields, [
'data' => [
'isMultilingual' => $this->isMultilingual,
'languageID' => $this->languageID ?: null
'altText' => I18nHandler::getInstance()->getValues('altText'),
'caption' => I18nHandler::getInstance()->getValues('caption'),
'title' => I18nHandler::getInstance()->getValues('title')
- ]);
+ ]));
$this->objectAction->executeAction();
$this->saved();
if (!is_array($target[$variableName])) {
throw new UserInputException($variableName);
}
-
+
for ($i = 0, $length = count($target[$variableName]); $i < $length; $i++) {
if (empty($target[$variableName][$i])) {
throw new UserInputException($variableName);
<?php
namespace wcf\data\box;
+use wcf\data\media\ViewableMedia;
use wcf\data\DatabaseObject;
use wcf\data\menu\Menu;
use wcf\data\menu\MenuCache;
* @since 2.2
*/
class Box extends DatabaseObject {
+ /**
+ * box content grouped by language id
+ * @var string[][]
+ */
+ protected $boxContent = null;
+
+ /**
+ * image media object
+ * @var Media
+ */
+ protected $image = null;
+
/**
* @inheritDoc
*/
/**
* available box types
- * @var string[]
+ * @var string[]
*/
public static $availableBoxTypes = ['text', 'html', 'system', 'menu'];
/**
* available box positions
- * @var string[]
+ * @var string[]
*/
public static $availablePositions = ['hero', 'headerBoxes', 'top', 'sidebarLeft', 'contentTop', 'sidebarRight', 'contentBottom', 'bottom', 'footerBoxes', 'footer'];
/**
* Returns true if the active user can delete this box.
*
- * @return boolean
+ * @return boolean
*/
public function canDelete() {
if (WCF::getSession()->getPermission('admin.content.cms.canManageBox') && !$this->originIsSystem) {
return true;
}
-
+
return false;
}
/**
* Returns the box content.
- *
- * @return array
+ *
+ * @return string[][]
*/
public function getBoxContent() {
- $content = array();
- $sql = "SELECT *
- FROM wcf".WCF_N."_box_content
- WHERE boxID = ?";
- $statement = WCF::getDB()->prepareStatement($sql);
- $statement->execute(array($this->boxID));
- while ($row = $statement->fetchArray()) {
- $content[($row['languageID'] ?: 0)] = [
- 'title' => $row['title'],
- 'content' => $row['content']
- ];
+ if ($this->boxContent === null) {
+ $this->boxContent = [];
+
+ $sql = "SELECT *
+ FROM wcf" . WCF_N . "_box_content
+ WHERE boxID = ?";
+ $statement = WCF::getDB()->prepareStatement($sql);
+ $statement->execute([$this->boxID]);
+ while ($row = $statement->fetchArray()) {
+ $this->boxContent[($row['languageID'] ?: 0)] = [
+ 'title' => $row['title'],
+ 'content' => $row['content'],
+ 'imageID' => $row['imageID']
+ ];
+ }
}
-
- return $content;
+
+ return $this->boxContent;
}
/**
- * Gets the title for the rendered version of this box.
- *
- * @return string
+ * Returns the title for the rendered version of this box.
+ *
+ * @return string
*/
public function getTitle() {
if ($this->boxType == 'system') {
}
/**
- * Gets the content for the rendered version of this box.
+ * Returns the content for the rendered version of this box.
*
- * @return string
+ * @return string
*/
public function getContent() {
if ($this->boxType == 'system') {
/**
* Returns the rendered version of this box.
*
- * @return string
+ * @return string
*/
public function __toString() {
if (!$this->hasContent()) return '';
/**
* Returns false if this box has no content.
*
- * @return boolean
+ * @return boolean
*/
public function hasContent() {
if ($this->boxType == 'system') {
/**
* Returns the image of this box.
*
- * @return \wcf\data\media\Media
+ * @return ViewableMedia
*/
public function getImage() {
if ($this->boxType == 'system') {
else if ($this->boxType == 'menu') {
return null;
}
- else {
- // @todo
+
+ if ($this->image !== null) {
+ return $this->image;
}
- return null;
+ $boxContent = $this->getBoxContent();
+ if ($this->isMultilingual) {
+ if (isset($boxContent[WCF::getLanguage()->languageID]) && $boxContent[WCF::getLanguage()->languageID]['imageID']) {
+ $this->image = ViewableMedia::getMedia($boxContent[WCF::getLanguage()->languageID]['imageID']);
+ }
+ }
+ else if (isset($boxContent[0]) && $boxContent[0]['imageID']) {
+ $this->image = ViewableMedia::getMedia($boxContent[0]['imageID']);
+ }
+
+ return $this->image;
}
/**
* Returns true if this box has an image.
- *
- * @return boolean
+ *
+ * @return boolean
*/
public function hasImage() {
if ($this->boxType == 'system') {
else if ($this->boxType == 'menu') {
return false;
}
- else {
- // @todo
+
+ $boxContent = $this->getBoxContent();
+ if ($this->isMultilingual) {
+ return (isset($boxContent[WCF::getLanguage()->languageID]) && $boxContent[WCF::getLanguage()->languageID]['imageID']);
}
- return false;
+ return (isset($boxContent[0]) && $boxContent[0]['imageID']);
}
public function getLink() {
// save box content
if (!empty($this->parameters['content'])) {
$sql = "INSERT INTO wcf".WCF_N."_box_content
- (boxID, languageID, title, content)
- VALUES (?, ?, ?, ?)";
+ (boxID, languageID, title, content, imageID)
+ VALUES (?, ?, ?, ?, ?)";
$statement = WCF::getDB()->prepareStatement($sql);
-
+
foreach ($this->parameters['content'] as $languageID => $content) {
$statement->execute([
$box->boxID,
($languageID ?: null),
$content['title'],
- $content['content']
+ $content['content'],
+ $content['imageID']
]);
}
}
-
+
return $box;
}
*/
public function update() {
parent::update();
-
+
// update box content
if (!empty($this->parameters['content'])) {
$sql = "DELETE FROM wcf".WCF_N."_box_content
WHERE boxID = ?";
$deleteStatement = WCF::getDB()->prepareStatement($sql);
-
+
$sql = "INSERT INTO wcf".WCF_N."_box_content
- (boxID, languageID, title, content)
- VALUES (?, ?, ?, ?)";
+ (boxID, languageID, title, content, imageID)
+ VALUES (?, ?, ?, ?, ?)";
$insertStatement = WCF::getDB()->prepareStatement($sql);
-
+
foreach ($this->objects as $box) {
- $deleteStatement->execute(array($box->boxID));
-
+ $deleteStatement->execute([$box->boxID]);
+
foreach ($this->parameters['content'] as $languageID => $content) {
$insertStatement->execute([
$box->boxID,
($languageID ?: null),
$content['title'],
- $content['content']
+ $content['content'],
+ $content['imageID']
]);
}
}
}
-
+
return $box;
}
<?php
namespace wcf\data\media;
use wcf\data\DatabaseObject;
+use wcf\data\ILinkableObject;
use wcf\data\IThumbnailFile;
use wcf\system\request\IRouteController;
use wcf\system\request\LinkHandler;
* @category Community Framework
* @since 2.2
*/
-class Media extends DatabaseObject implements IRouteController, IThumbnailFile {
+class Media extends DatabaseObject implements ILinkableObject, IRouteController, IThumbnailFile {
/**
* i18n media data grouped by language id for all language
* @var string[][]
];
/**
- * @inheritcoc
+ * @inheritDoc
+ */
+ public function getLink() {
+ return LinkHandler::getInstance()->getLink('Media', [
+ 'forceFrontend' => true,
+ 'object' => $this
+ ]);
+ }
+
+ /**
+ * @inheritDoc
*/
public function getLocation() {
return self::getStorage().substr($this->fileHash, 0, 2).'/'.$this->mediaID.'-'.$this->fileHash;
}
/**
- * @inheritcoc
+ * @inheritDoc
*/
public function getThumbnailLink($size) {
if (!isset(self::$thumbnailSizes[$size])) {
}
/**
- * @inheritcoc
+ * @inheritDoc
*/
public function getThumbnailLocation($size) {
if (!isset(self::$thumbnailSizes[$size])) {
}
/**
- * @inheritcoc
+ * @inheritDoc
*/
public function getTitle() {
return $this->filename;
}
/**
- * @inheritcoc
+ * @inheritDoc
*/
public static function getThumbnailSizes() {
return static::$thumbnailSizes;
use wcf\system\clipboard\ClipboardHandler;
use wcf\system\database\util\PreparedStatementConditionBuilder;
use wcf\system\exception\PermissionDeniedException;
+use wcf\system\exception\UserInputException;
use wcf\system\language\I18nHandler;
use wcf\system\language\LanguageFactory;
use wcf\system\request\Linkhandler;
use wcf\system\upload\DefaultUploadFileSaveStrategy;
+use wcf\system\upload\MediaUploadFileValidationStrategy;
use wcf\system\WCF;
use wcf\util\FileUtil;
public function validateUpload() {
WCF::getSession()->checkPermissions(['admin.content.cms.canManageMedia']);
- // TODO
+ if (isset($this->parameters['fileTypeFilters']) && !is_array($this->parameters['fileTypeFilters'])) {
+ throw new UserInputException('fileTypeFilters');
+ }
+
+ $this->parameters['__files']->validateFiles(new MediaUploadFileValidationStrategy(isset($this->parameters['fileTypeFilters']) ? $this->parameters['fileTypeFilters'] : []));
}
/**
'largeThumbnailLink' => $media->largeThumbnailType ? $media->getThumbnailLink('large') : '',
'largeThumbnailType' => $media->largeThumbnailType,
'largeThumbnailWidth' => $media->largeThumbnailWidth,
+ 'link' => $media->getLink(),
'mediaID' => $media->mediaID,
'mediumThumbnailHeight' => $media->mediumThumbnailHeight,
'mediumThumbnailLink' => $media->mediumThumbnailType ? $media->getThumbnailLink('medium') : '',
if (!WCF::getSession()->getPermission('admin.content.cms.canManageMedia') && !WCF::getSession()->getPermission('admin.content.cms.canUseMedia')) {
throw new PermissionDeniedException();
}
+
+ if (isset($this->parameters['fileTypeFilters']) && !is_array($this->parameters['fileTypeFilters'])) {
+ throw new UserInputException('fileTypeFilters');
+ }
+
+ $this->readString('mode');
+ if ($this->parameters['mode'] != 'editor' && $this->parameters['mode'] != 'select') {
+ throw new UserInputException('mode');
+ }
}
/**
*/
public function getManagementDialog() {
$mediaList = new ViewableMediaList();
+ if (!empty($this->parameters['fileTypeFilters'])) {
+ $mediaList->addFileTypeFilters($this->parameters['fileTypeFilters']);
+ }
$mediaList->readObjects();
return [
'hasMarkedItems' => ClipboardHandler::getInstance()->hasMarkedItems(ClipboardHandler::getInstance()->getObjectTypeID('com.woltlab.wcf.media')),
'media' => $this->getI18nMediaData($mediaList),
'template' => WCF::getTPL()->fetch('mediaManager', 'wcf', [
- 'mediaList' => $mediaList
+ 'mediaList' => $mediaList,
+ 'mode' => $this->parameters['mode'],
+ 'showFileTypeFilter' => empty($this->parameters['fileTypeFilters'])
])
];
}
throw new PermissionDeniedException();
}
- $this->readString('searchString', true, 'data');
- $this->readString('fileType', true, 'data');
+ $this->readString('searchString', true);
+ $this->readString('fileType', true);
- if (!$this->parameters['data']['searchString'] && !$this->parameters['data']['fileType']) {
+ if (!$this->parameters['searchString'] && !$this->parameters['fileType']) {
throw new UserInputException('searchString');
}
$this->fileTypeConditionBuilder = new PreparedStatementConditionBuilder(false);
- switch ($this->parameters['data']['fileType']) {
+ switch ($this->parameters['fileType']) {
case 'other':
$this->fileTypeConditionBuilder->add('media.fileType NOT LIKE ?', ['image/%']);
$this->fileTypeConditionBuilder->add('media.fileType <> ?', ['application/pdf']);
$this->fileTypeConditionBuilder->add('media.fileType LIKE ?', ['text/%']);
break;
}
+
+ if (isset($this->parameters['fileTypeFilters']) && !is_array($this->parameters['fileTypeFilters'])) {
+ throw new UserInputException('fileTypeFilters');
+ }
+
+ $this->readString('mode');
+ if ($this->parameters['mode'] != 'editor' && $this->parameters['mode'] != 'select') {
+ throw new UserInputException('mode');
+ }
}
/**
* @inheritdoc
*/
public function getSearchResultList() {
- $searchString = '%'.addcslashes($this->parameters['data']['searchString'], '_%').'%';
-
- $sql = "SELECT media.mediaID
- FROM wcf".WCF_N."_media media
- LEFT JOIN wcf".WCF_N."_media_content media_content
- ON (media_content.mediaID = media.mediaID)
- WHERE (media_content.title LIKE ?
- OR media_content.caption LIKE ?
- OR media_content.altText LIKE ?
- OR media.filename LIKE ?)";
+ $searchString = '%'.addcslashes($this->parameters['searchString'], '_%').'%';
+
+ $mediaList = new MediaList();
+ $mediaList->sqlConditionJoins = 'LEFT JOIN wcf'.WCF_N.'_media_content media_content ON (media_content.mediaID = media.mediaID)';
+
+ $searchConditionBuilder = new PreparedStatementConditionBuilder(false, 'OR');
+ $searchConditionBuilder->add('media_content.title LIKE ?', [$searchString]);
+ $searchConditionBuilder->add('media_content.caption LIKE ?', [$searchString]);
+ $searchConditionBuilder->add('media_content.altText LIKE ?', [$searchString]);
+ $searchConditionBuilder->add('media.filename LIKE ?', [$searchString]);
+ $mediaList->getConditionBuilder()->add($searchConditionBuilder->__toString(), $searchConditionBuilder->getParameters());
+
if (!empty($this->fileTypeConditionBuilder->__toString())) {
- $sql .= " AND ".$this->fileTypeConditionBuilder;
+ $mediaList->getConditionBuilder()->add($this->fileTypeConditionBuilder->__toString(), $this->fileTypeConditionBuilder->getParameters());
}
- $statement = WCF::getDB()->prepareStatement($sql, 0, 10);
- $statement->execute(array_merge([
- $searchString,
- $searchString,
- $searchString,
- $searchString
- ], $this->fileTypeConditionBuilder->getParameters()));
-
- $mediaIDs = [];
- while ($mediaID = $statement->fetchColumn()) {
- $mediaIDs[] = $mediaID;
+ if (!empty($this->parameters['fileTypeFilters'])) {
+ $mediaList->addFileTypeFilters($this->parameters['fileTypeFilters']);
}
- if (empty($mediaIDs)) {
+ $mediaList->readObjectIDs();
+
+ if (empty($mediaList->getObjectIDs())) {
return [
'template' => WCF::getLanguage()->getDynamicVariable('wcf.media.search.noResults')
];
}
- $mediaList = new ViewableMediaList();
- $mediaList->setObjectIDs($mediaIDs);
- $mediaList->readObjects();
+ $viewableMediaList = new ViewableMediaList();
+ $viewableMediaList->setObjectIDs($mediaList->getObjectIDs());
+ $viewableMediaList->readObjects();
return [
- 'media' => $this->getI18nMediaData($mediaList),
+ 'media' => $this->getI18nMediaData($viewableMediaList),
'template' => WCF::getTPL()->fetch('mediaListItems', 'wcf', [
- 'mediaList' => $mediaList
+ 'mediaList' => $viewableMediaList,
+ 'mode' => $this->parameters['mode']
])
];
}
*/
public function deleteFiles() {
@unlink($this->getLocation());
-
+
// delete thumbnails
if ($this->isImage) {
foreach (Media::getThumbnailSizes() as $size => $data) {
<?php
namespace wcf\data\media;
use wcf\data\DatabaseObjectList;
+use wcf\system\database\util\PreparedStatementConditionBuilder;
/**
* Represents a list of madia files.
* @inheritdoc
*/
public $className = Media::class;
+
+ /**
+ * Adds filters for the media files based on their file type.
+ *
+ * @param array $filters
+ */
+ public function addFileTypeFilters(array $filters) {
+ if (isset($filters['isImage'])) {
+ $this->getConditionBuilder()->add('isImage = ?', [$filters['isImage'] ? 1 : 0]);
+ }
+
+ if (isset($filters['fileTypes'])) {
+ $conditionBuilder = new PreparedStatementConditionBuilder(false, 'OR');
+ foreach ($filters['fileTypes'] as $fileType) {
+ if (substr($fileType, -1) == '*') {
+ $conditionBuilder->add('fileType LIKE ?', [substr($fileType, 0, -1).'%']);
+ }
+ else {
+ $conditionBuilder->add('fileType = ?', [$fileType]);
+ }
+ }
+
+ $this->getConditionBuilder()->add($conditionBuilder->__toString(), $conditionBuilder->getParameters());
+ }
+ }
}
<?php
namespace wcf\data\media;
use wcf\data\DatabaseObjectDecorator;
+use wcf\system\exception\SystemException;
use wcf\util\StringUtil;
use wcf\util\FileUtil;
*/
protected static $baseClass = Media::class;
+ /**
+ * Returns a textual representation of the media file to be used in templates.
+ *
+ * @return string
+ */
+ public function __toString() {
+ if ($this->isImage) {
+ return '<img src="'.$this->getLink().'" alt="'.StringUtil::encodeHTML($this->altText).'" />';
+ }
+
+ return '<a href="'.$this->getLink().'>'.$this->getTitle().'</a>';
+ }
+
/**
* Returns a tag to display the media element.
*
public function getElementTag($size) {
// todo: validate $size
if ($this->isImage && $this->tinyThumbnailType) {
- return '<img src="'.$this->getThumbnailLink('tiny').'" alt="" style="width: '.$size.'px; height: '.$size.'px;" />';
+ return '<img src="'.$this->getThumbnailLink('tiny').'" alt="'.StringUtil::encodeHTML($this->altText).'" style="width: '.$size.'px; height: '.$size.'px;" />';
}
return '<span class="icon icon'.$size.' '.FileUtil::getIconClassByMimeType($this->fileType).'"></span>';
}
+
+ /**
+ * Returns a tag to display a certain thumbnail.
+ *
+ * @param string $size thumbnail size
+ * @return string
+ */
+ public function getThumbnailTag($size = '') {
+ if (!isset(Media::getThumbnailSizes()[$size])) {
+ throw new SystemException("Unknown thumbnail size '".$size."'");
+ }
+
+ return '<img src="'.$this->getThumbnailLink($size).'" alt="'.StringUtil::encodeHTML($this->altText).'" />';
+ }
+
+ /**
+ * Returns the viewable media file with the given id.
+ *
+ * @param integer $mediaID
+ * @return Media|null
+ */
+ public static function getMedia($mediaID) {
+ $mediaList = new ViewableMediaList();
+ $mediaList->setObjectIDs([$mediaID]);
+ $mediaList->readObjects();
+
+ return $mediaList->search($mediaID);
+ }
}
// fetch content data
$this->sqlSelects .= "media_content.*";
- $this->sqlJoins .= " LEFT JOIN wcf".WCF_N."_media_content media_content ON (media_content.mediaID = media.mediaID AND media_content.languageID = COALESCE(media.languageID, ".WCF::getUser()->languageID."))";
+ $this->sqlJoins .= " LEFT JOIN wcf".WCF_N."_media_content media_content ON (media_content.mediaID = media.mediaID AND media_content.languageID = COALESCE(media.languageID, ".WCF::getLanguage()->languageID."))";
}
}
/**
* Returns true if the active user can delete this menu.
*
- * @return boolean
+ * @return boolean
*/
public function canDelete() {
if (WCF::getSession()->getPermission('admin.content.cms.canManageMenu') && !$this->originIsSystem) {
return true;
}
-
+
return false;
}
}
--- /dev/null
+<?php
+namespace wcf\system\upload;
+
+/**
+ * Upload file validation strategy implementation for media files.
+ *
+ * @author Matthias Schmidt
+ * @copyright 2001-2015 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package com.woltlab.wcf
+ * @subpackage system.upload
+ * @category Community Framework
+ * @since 2.2
+ */
+class MediaUploadFileValidationStrategy implements IUploadFileValidationStrategy {
+ /**
+ * file type filters
+ * @var array
+ */
+ protected $fileTypeFilters = [];
+
+ /**
+ * Creates a new instance of MediaUploadFileValidationStrategy.
+ *
+ * @param array $fileTypeFilters
+ */
+ public function __construct(array $fileTypeFilters) {
+ $this->fileTypeFilters = $fileTypeFilters;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function validate(UploadFile $uploadFile) {
+ if ($uploadFile->getErrorCode()) {
+ $uploadFile->setValidationErrorType('uploadFailed');
+ return false;
+ }
+
+ if (!empty($this->fileTypeFilters['isImage']) && ($uploadFile->getImageData() === null || !preg_match('~^image/(gif|jpe?g|png)$~i', $uploadFile->getMimeType()))) {
+ $uploadFile->setValidationErrorType('noImage');
+ return false;
+ }
+
+ if (isset($this->fileTypeFilters['fileTypes'])) {
+ foreach ($this->fileTypeFilters['fileTypes'] as $fileType) {
+ if (substr($fileType, -1) == '*') {
+ if (!preg_match('~^'.preg_quote(substr($fileType, 0, -1), '~').'~', $uploadFile->getMimeType())) {
+ return false;
+ }
+ }
+ else {
+ if ($uploadFile->getMimeType() != $fileType) {
+ $uploadFile->setValidationErrorType('noImage');
+ return false;
+ }
+ }
+ }
+ }
+
+ return true;
+ }
+}
width: 96px;
}
+.icon144 {
+ font-size: 130px; // TODO
+ height: 144px;
+ width: 144px;
+}
+
// spinner animation
.fa-spinner {
animation: wcfSpinner .6s linear infinite;
> li {
float: left;
- height: 120px;
- width: 120px;
+ height: 160px;
+ width: 160px;
position: relative;
border: 1px solid #aaa;
overflow: hidden;
}
}
+ &.uploadFailed {
+ cursor: pointer;
+
+ > .mediaInformation {
+ background-color: rgba(242, 222, 222, 0.6); // todo
+ color: rgb(169, 68, 66); // todo
+ }
+ }
+
> .mediaThumbnail {
- height: 96px;
- width: 96px;
- padding: 12px;
+ height: 144px;
+ width: 144px;
+ padding: 8px;
}
> .mediaInformation {
position: absolute;
bottom: 0;
- background: rgba(0,0,0,0.6);
+ background: rgba(0,0,0,0.6); // TOOD
color: #fff;
width: 100%;
padding: $wcfGapSmall;
position: absolute;
top: 0;
right: 0;
- background: rgba(0,0,0,0.6);
+ background: rgba(0,0,0,0.6); // TOOD
height: 0;
overflow: hidden;
languageID INT(10),
title VARCHAR(255) NOT NULL,
content MEDIUMTEXT,
+ imageID INT(10),
KEY (boxID, languageID)
);
ALTER TABLE wcf1_box ADD FOREIGN KEY (menuID) REFERENCES wcf1_menu (menuID) ON DELETE CASCADE;
ALTER TABLE wcf1_box_content ADD FOREIGN KEY (boxID) REFERENCES wcf1_box (boxID) ON DELETE CASCADE;
-ALTER TABLE wcf1_box_content ADD FOREIGN KEY (languageID) REFERENCES wcf1_language (languageID) ON DELETE CASCADE;
+ALTER TABLE wcf1_box_content ADD FOREIGN KEY (languageID) REFERENCES wcf1_language (languageID) ON DELETE CASCADE;
+ALTER TABLE wcf1_box_content ADD FOREIGN KEY (imageID) REFERENCES wcf1_media (mediaID) ON DELETE SET NULL;
ALTER TABLE wcf1_category ADD FOREIGN KEY (objectTypeID) REFERENCES wcf1_object_type (objectTypeID) ON DELETE CASCADE;