<permissions>admin.content.cms.canManageBox</permissions>
<icon>fa-plus</icon>
</acpmenuitem>
+ <!-- /cms -->
- <acpmenuitem name="wcf.acp.menu.link.cms.media.list">
+ <!-- media -->
+ <acpmenuitem name="wcf.acp.menu.link.media">
+ <parent>wcf.acp.menu.link.content</parent>
+ <showorder>2</showorder>
+ </acpmenuitem>
+ <acpmenuitem name="wcf.acp.menu.link.media.list">
<controller>wcf\acp\page\MediaListPage</controller>
- <parent>wcf.acp.menu.link.cms</parent>
+ <parent>wcf.acp.menu.link.media</parent>
<permissions>admin.content.cms.canManageMedia</permissions>
</acpmenuitem>
- <!-- /cms -->
-
+ <acpmenuitem name="wcf.acp.menu.link.media.category.list">
+ <controller>wcf\acp\page\MediaCategoryListPage</controller>
+ <parent>wcf.acp.menu.link.media</parent>
+ <permissions>admin.content.cms.canManageMedia</permissions>
+ </acpmenuitem>
+ <acpmenuitem name="wcf.acp.menu.link.media.category.add">
+ <controller>wcf\acp\form\MediaCategoryAddForm</controller>
+ <parent>wcf.acp.menu.link.media.category.list</parent>
+ <permissions>admin.content.cms.canManageMedia</permissions>
+ <icon>fa-plus</icon>
+ </acpmenuitem>
+ <!-- /media -->
+
<!-- article -->
<acpmenuitem name="wcf.acp.menu.link.article">
<parent>wcf.acp.menu.link.content</parent>
<options>module_article</options>
- <showorder>2</showorder>
+ <showorder>3</showorder>
</acpmenuitem>
<acpmenuitem name="wcf.acp.menu.link.article.list">
<!-- label -->
<acpmenuitem name="wcf.acp.menu.link.label">
<parent>wcf.acp.menu.link.content</parent>
- <showorder>3</showorder>
+ <showorder>4</showorder>
</acpmenuitem>
<acpmenuitem name="wcf.acp.menu.link.label.list">
<controller>wcf\acp\page\LabelListPage</controller>
<!-- bbcode -->
<acpmenuitem name="wcf.acp.menu.link.bbcode">
<parent>wcf.acp.menu.link.content</parent>
- <showorder>4</showorder>
+ <showorder>5</showorder>
</acpmenuitem>
<acpmenuitem name="wcf.acp.menu.link.bbcode.list">
<controller>wcf\acp\page\BBCodeListPage</controller>
<acpmenuitem name="wcf.acp.menu.link.tag">
<parent>wcf.acp.menu.link.content</parent>
<options>module_tagging</options>
- <showorder>5</showorder>
+ <showorder>6</showorder>
</acpmenuitem>
<acpmenuitem name="wcf.acp.menu.link.tag.list">
<!-- attachment -->
<acpmenuitem name="wcf.acp.menu.link.attachment">
<parent>wcf.acp.menu.link.content</parent>
- <showorder>6</showorder>
+ <showorder>7</showorder>
</acpmenuitem>
<acpmenuitem name="wcf.acp.menu.link.attachment.list">
<name>com.woltlab.wcf.box</name>
<definitionname>com.woltlab.wcf.acl.simple</definitionname>
</type>
- <type>
- <name>com.woltlab.wcf.media</name>
- <definitionname>com.woltlab.wcf.acl.simple</definitionname>
- </type>
<!-- /simple acl -->
<!-- article list box condition -->
</type>
<!-- /recent activity box condition -->
+ <!-- media -->
+ <type>
+ <name>com.woltlab.wcf.media</name>
+ <definitionname>com.woltlab.wcf.acl.simple</definitionname>
+ </type>
+ <type>
+ <name>com.woltlab.wcf.media.category</name>
+ <definitionname>com.woltlab.wcf.category</definitionname>
+ <classname>wcf\system\category\MediaCategoryType</classname>
+ </type>
+ <!-- /media -->
+
<!-- deprecated -->
<type>
<name>com.woltlab.wcf.page.controller</name>
<section class="section">
<h2 class="sectionTitle">{lang}wcf.global.form.data{/lang}</h2>
+ {hascontent}
+ <dl>
+ <dt><label for="categoryID_{@$media->mediaID}">{lang}wcf.media.categoryID{/lang}</label></dt>
+ <dd>
+ <select id="categoryID_{@$media->mediaID}" name="categoryID">
+ <option value="0">{lang}wcf.global.noSelection{/lang}</option>
+
+ {content}
+ {foreach from=$categoryList item=categoryItem}
+ <option value="{$categoryItem->categoryID}">{$categoryItem->getTitle()}</option>
+
+ {if $categoryItem->hasChildren()}
+ {foreach from=$categoryItem item=subCategoryItem}
+ <option value="{$subCategoryItem->categoryID}"> {$subCategoryItem->getTitle()}</option>
+
+ {if $subCategoryItem->hasChildren()}
+ {foreach from=$subCategoryItem item=subSubCategoryItem}
+ <option value="{$subSubCategoryItem->categoryID}"> {$subSubCategoryItem->getTitle()}</option>
+ {/foreach}
+ {/if}
+ {/foreach}
+ {/if}
+ {/foreach}
+ {/content}
+ </select>
+ </dd>
+ </dl>
+ {/hascontent}
+
{if $availableLanguages|count > 1}
<dl>
<dt></dt>
+{hascontent}
+ <div class="mediaManagerCategoryList">
+ <select name="categoryID" class="fullWidth">
+ <option value="0">{lang}wcf.media.category.choose{/lang}</option>
+
+ {content}
+ {foreach from=$categoryList item=categoryItem}
+ <option value="{$categoryItem->categoryID}">{$categoryItem->getTitle()}</option>
+
+ {if $categoryItem->hasChildren()}
+ {foreach from=$categoryItem item=subCategoryItem}
+ <option value="{$subCategoryItem->categoryID}"> {$subCategoryItem->getTitle()}</option>
+
+ {if $subCategoryItem->hasChildren()}
+ {foreach from=$subCategoryItem item=subSubCategoryItem}
+ <option value="{$subSubCategoryItem->categoryID}"> {$subSubCategoryItem->getTitle()}</option>
+ {/foreach}
+ {/if}
+ {/foreach}
+ {/if}
+ {/foreach}
+ {/content}
+ </select>
+ </div>
+{/hascontent}
+
<div class="inputAddon mediaManagerSearch">
<input type="text" class="mediaManagerSearchField" placeholder="{lang}wcf.media.search.placeholder{/lang}">
<span class="inputSuffix">
<section class="section">
<h2 class="sectionTitle">{lang}wcf.global.form.data{/lang}</h2>
-
+
+ {hascontent}
+ <dl>
+ <dt><label for="categoryID_{@$media->mediaID}">{lang}wcf.media.categoryID{/lang}</label></dt>
+ <dd>
+ <select id="categoryID_{@$media->mediaID}" name="categoryID">
+ <option value="0">{lang}wcf.global.noSelection{/lang}</option>
+
+ {content}
+ {foreach from=$categoryList item=categoryItem}
+ <option value="{$categoryItem->categoryID}">{$categoryItem->getTitle()}</option>
+
+ {if $categoryItem->hasChildren()}
+ {foreach from=$categoryItem item=subCategoryItem}
+ <option value="{$subCategoryItem->categoryID}"> {$subCategoryItem->getTitle()}</option>
+
+ {if $subCategoryItem->hasChildren()}
+ {foreach from=$subCategoryItem item=subSubCategoryItem}
+ <option value="{$subSubCategoryItem->categoryID}"> {$subSubCategoryItem->getTitle()}</option>
+ {/foreach}
+ {/if}
+ {/foreach}
+ {/if}
+ {/foreach}
+ {/content}
+ </select>
+ </dd>
+ </dl>
+ {/hascontent}
+
{if $availableLanguages|count > 1}
<dl>
<dt></dt>
<h2 class="sectionTitle">{lang}wcf.global.filter{/lang}</h2>
<div class="row rowColGap formGrid">
+ {hascontent}
+ <dl class="col-xs-12 col-md-4">
+ <dt></dt>
+ <dd>
+ <select id="categoryID" name="categoryID">
+ <option value="0">{lang}wcf.media.category.choose{/lang}</option>
+
+ {content}
+ {foreach from=$categoryList item=categoryItem}
+ <option value="{$categoryItem->categoryID}"{if $categoryItem->categoryID == $categoryID} selected="selected"{/if}>{$categoryItem->getTitle()}</option>
+
+ {if $categoryItem->hasChildren()}
+ {foreach from=$categoryItem item=subCategoryItem}
+ <option value="{$subCategoryItem->categoryID}"{if $subCategoryItem->categoryID == $categoryID} selected="selected"{/if}> {$subCategoryItem->getTitle()}</option>
+
+ {if $subCategoryItem->hasChildren()}
+ {foreach from=$subCategoryItem item=subSubCategoryItem}
+ <option value="{$subSubCategoryItem->categoryID}"{if $subSubCategoryItem->categoryID == $categoryID} selected="selected"{/if}> {$subSubCategoryItem->getTitle()}</option>
+ {/foreach}
+ {/if}
+ {/foreach}
+ {/if}
+ {/foreach}
+ {/content}
+ </select>
+ </dd>
+ </dl>
+ {/hascontent}
+
<dl class="col-xs-12 col-md-4">
<dt></dt>
<dd>
+{hascontent}
+ <div class="mediaManagerCategoryList">
+ <select name="categoryID" class="fullWidth">
+ <option value="0">{lang}wcf.media.category.choose{/lang}</option>
+
+ {content}
+ {foreach from=$categoryList item=categoryItem}
+ <option value="{$categoryItem->categoryID}">{$categoryItem->getTitle()}</option>
+
+ {if $categoryItem->hasChildren()}
+ {foreach from=$categoryItem item=subCategoryItem}
+ <option value="{$subCategoryItem->categoryID}"> {$subCategoryItem->getTitle()}</option>
+
+ {if $subCategoryItem->hasChildren()}
+ {foreach from=$subCategoryItem item=subSubCategoryItem}
+ <option value="{$subSubCategoryItem->categoryID}"> {$subSubCategoryItem->getTitle()}</option>
+ {/foreach}
+ {/if}
+ {/foreach}
+ {/if}
+ {/foreach}
+ {/content}
+ </select>
+ </div>
+{/hascontent}
+
<div class="inputAddon mediaManagerSearch">
<input type="text" class="mediaManagerSearchField" placeholder="{lang}wcf.media.search.placeholder{/lang}">
<span class="inputSuffix">
var deleteAction = new WCF.Action.Delete('wcf\\data\\media\\MediaAction', '.jsMediaRow');
deleteAction.setCallback(Clipboard.reload.bind(Clipboard));
- _mediaEditor = new MediaEditor();
+ _mediaEditor = new MediaEditor({
+ _editorSuccess: function(media, oldCategoryId) {
+ if (media.categoryID != oldCategoryId) {
+ window.setTimeout(function() {
+ window.location.reload();
+ }, 500);
+ }
+ }
+ });
var editButtons = elByClass('jsMediaEditButton');
for (var i = 0, length = editButtons.length; i < length; i++) {
this._media = null;
this._availableLanguageCount = 1;
+ this._categoryIds = [];
+ this._oldCategoryId = 0;
this._dialogs = new Dictionary();
}
UiNotification.show();
if (this._callbackObject._editorSuccess) {
- this._callbackObject._editorSuccess(this._media);
+ this._callbackObject._editorSuccess(this._media, this._oldCategoryId);
+ this._oldCategoryId = 0;
}
UiDialog.close('mediaEditor_' + this._media.mediaID);
_saveData: function() {
var content = UiDialog.getDialog('mediaEditor_' + this._media.mediaID).content;
+ var categoryId = elBySel('select[name=categoryID]', content);
var altText = elBySel('input[name=altText]', content);
var caption = elBySel('textarea[name=caption]', content);
var title = elBySel('input[name=title]', content);
var captionError = (caption ? DomTraverse.childByClass(caption.parentNode.parentNode, 'innerError') : false);
var titleError = DomTraverse.childByClass(title.parentNode.parentNode, 'innerError');
+ // category
+ this._oldCategoryId = this._media.categoryID;
+ if (this._categoryIds.length) {
+ this._media.categoryID = ~~categoryId.value;
+
+ // if the selected category id not valid (manipulated DOM), ignore
+ if (this._categoryIds.indexOf(this._media.categoryID) === -1) {
+ this._media.categoryID = 0;
+ }
+ }
+
+ // language and multilingualism
if (this._availableLanguageCount > 1) {
this._media.isMultilingual = ~~elBySel('input[name=isMultilingual]', content).checked;
this._media.languageID = this._media.isMultilingual ? null : LanguageChooser.getLanguageId('languageID');
this._media.languageID = LANGUAGE_ID;
}
+ // altText, caption and title
this._media.altText = {};
this._media.caption = {};
this._media.title = {};
altText: this._media.altText,
caption: this._media.caption,
data: {
+ categoryID: this._media.categoryID,
isMultilingual: this._media.isMultilingual,
languageID: this._media.languageID
},
source: {
after: (function(content, data) {
this._availableLanguageCount = ~~data.returnValues.availableLanguageCount;
+ this._categoryIds = data.returnValues.categoryIDs.map(function(number) {
+ return ~~number;
+ });
var didLoadMediaData = false;
if (data.returnValues.mediaData) {
LanguageChooser.setLanguageId('languageID', this._media.languageID || LANGUAGE_ID);
}
+ if (this._categoryIds.length) {
+ elBySel('select[name=categoryID]', content).value = ~~this._media.categoryID;
+ }
+
var title = elBySel('input[name=title]', content);
var altText = elBySel('input[name=altText]', content);
var caption = elBySel('textarea[name=caption]', content);
}
},
+ /**
+ * Is called when a new category is selected.
+ */
+ _categoryChange: function() {
+ this._search.search();
+ },
+
/**
* Handles clicks on the media manager button.
*
*/
_dialogShow: function() {
if (!this._mediaManagerMediaList) {
- this._mediaManagerMediaList = elByClass('mediaManagerMediaList', UiDialog.getDialog(this).dialog)[0];
+ var dialog = this.getDialog();
+
+ this._mediaManagerMediaList = elByClass('mediaManagerMediaList', dialog)[0];
+
+ this._mediaCategorySelect = elBySel('.mediaManagerCategoryList > select', dialog);
+ if (this._mediaCategorySelect) {
+ this._mediaCategorySelect.addEventListener('change', this._categoryChange.bind(this));
+ }
// store list items locally
var listItems = DomTraverse.childrenByTag(this._mediaManagerMediaList, 'LI');
* successfully editing a media file.
*
* @param {object} media updated media file data
+ * @param {integer} oldCategoryId old category id
*/
- _editorSuccess: function(media) {
+ _editorSuccess: function(media, oldCategoryId) {
+ // if the category changed of media changed and category
+ // is selected, check if media list needs to be refreshed
+ if (this._mediaCategorySelect) {
+ var selectedCategoryId = ~~this._mediaCategorySelect.value;
+
+ if (selectedCategoryId) {
+ var newCategoryId = ~~media.categoryID;
+
+ if (oldCategoryId != newCategoryId && (oldCategoryId == selectedCategoryId || newCategoryId == selectedCategoryId)) {
+ this._search.search();
+ }
+ }
+ }
+
UiDialog.open(this);
this._media.set(~~media.mediaID, media);
}
},
+ /**
+ * Returns the id of the currently selected category or `0` if no category is selected.
+ *
+ * @return {integer}
+ */
+ getCategoryId: function() {
+ if (this._mediaCategorySelect) {
+ return this._mediaCategorySelect.value;
+ }
+
+ return 0;
+ },
+
/**
* Returns the media manager dialog element.
*
}
},
+ /**
+ * Hides the search string treshold error.
+ */
+ _hideStringThresholdError: function() {
+ var innerInfo = DomTraverse.childByClass(this._input.parentNode.parentNode, 'innerInfo');
+ if (innerInfo) {
+ elHide(innerInfo);
+ }
+ },
+
/**
* Handles the `[ENTER]` key to submit the form.
*
if (EventKey.Enter(event)) {
event.preventDefault();
- var innerInfo = DomTraverse.childByClass(this._input.parentNode.parentNode, 'innerInfo');
-
if (this._input.value.length >= this._mediaManager.getOption('minSearchLength')) {
- if (innerInfo) {
- elHide(innerInfo);
- }
+ this._hideStringThresholdError();
- this._search();
+ this.search();
}
else {
- if (innerInfo) {
- elShow(innerInfo);
- }
- else {
- innerInfo = elCreate('p');
- innerInfo.className = 'innerInfo';
- innerInfo.textContent = Language.get('wcf.media.search.info.searchStringThreshold');
-
- DomUtil.insertAfter(innerInfo, this._input.parentNode);
- }
+ this._showStringThresholdError();
}
}
},
/**
- * Sends an AJAX request to fetch search results.
+ * Shows the search string treshold error.
*/
- _search: function() {
- this._searchMode = true;
-
- Ajax.api(this, {
- parameters: {
- imagesOnly: this._mediaManager.getOption('imagesOnly'),
- mode: this._mediaManager.getMode(),
- searchString: this._input.value
- }
- });
+ _showStringThresholdError: function() {
+ var innerInfo = DomTraverse.childByClass(this._input.parentNode.parentNode, 'innerInfo');
+ if (innerInfo) {
+ elShow(innerInfo);
+ }
+ else {
+ innerInfo = elCreate('p');
+ innerInfo.className = 'innerInfo';
+ innerInfo.textContent = Language.get('wcf.media.search.info.searchStringThreshold');
+
+ DomUtil.insertAfter(innerInfo, this._input.parentNode);
+ }
},
/**
*/
showSearch: function() {
elShow(this._searchContainer);
- }
+ },
+
+ /**
+ * Sends an AJAX request to fetch search results.
+ */
+ search: function() {
+ var searchString = this._input.value;
+ if (searchString && this._input.value.length < this._mediaManager.getOption('minSearchLength')) {
+ this._showStringThresholdError();
+
+ searchString = '';
+ }
+ else {
+ this._hideStringThresholdError();
+ }
+
+ this._searchMode = true;
+
+ Ajax.api(this, {
+ parameters: {
+ categoryID: this._mediaManager.getCategoryId(),
+ imagesOnly: this._mediaManager.getOption('imagesOnly'),
+ mode: this._mediaManager.getMode(),
+ searchString: searchString
+ }
+ });
+ },
};
return MediaManagerSearch;
--- /dev/null
+<?php
+namespace wcf\acp\form;
+
+/**
+ * Shows the media category add form.
+ *
+ * @author Matthias Schmidt
+ * @copyright 2001-2017 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package WoltLabSuite\Core\Acp\Form
+ * @since 3.1
+ */
+class MediaCategoryAddForm extends AbstractCategoryAddForm {
+ /**
+ * @inheritDoc
+ */
+ public $activeMenuItem = 'wcf.acp.menu.link.media.category.add';
+
+ /**
+ * @inheritDoc
+ */
+ public $objectTypeName = 'com.woltlab.wcf.media.category';
+}
--- /dev/null
+<?php
+namespace wcf\acp\form;
+
+/**
+ * Shows the media category edit form.
+ *
+ * @author Matthias Schmidt
+ * @copyright 2001-2017 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package WoltLabSuite\Core\Acp\Form
+ * @since 3.1
+ */
+class MediaCategoryEditForm extends AbstractCategoryEditForm {
+ /**
+ * @inheritDoc
+ */
+ public $activeMenuItem = 'wcf.acp.menu.link.media.category.list';
+
+ /**
+ * @inheritDoc
+ */
+ public $objectTypeName = 'com.woltlab.wcf.media.category';
+}
--- /dev/null
+<?php
+namespace wcf\acp\page;
+
+/**
+ * Shows the list media categories.
+ *
+ * @author Matthias Schmidt
+ * @copyright 2001-2017 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package WoltLabSuite\Core\Acp\Page
+ * @since 3.1
+ */
+class MediaCategoryListPage extends AbstractCategoryListPage {
+ /**
+ * @inheritDoc
+ */
+ public $activeMenuItem = 'wcf.acp.menu.link.media.category.list';
+
+ /**
+ * @inheritDoc
+ */
+ public $objectTypeName = 'com.woltlab.wcf.media.category';
+}
<?php
namespace wcf\acp\page;
+use wcf\data\category\CategoryNodeTree;
use wcf\data\media\ViewableMediaList;
use wcf\page\SortablePage;
use wcf\system\clipboard\ClipboardHandler;
/**
* @inheritDoc
*/
- public $activeMenuItem = 'wcf.acp.menu.link.cms.media.list';
+ public $activeMenuItem = 'wcf.acp.menu.link.media.list';
+
+ /**
+ * id of the selected media category
+ * @var integer
+ */
+ public $categoryID = 0;
+
+ /**
+ * node tree with all available media categories
+ * @var \RecursiveIteratorIterator
+ */
+ public $categoryList;
/**
* @inheritDoc
parent::assignVariables();
WCF::getTPL()->assign([
+ 'categoryID' => $this->categoryID,
+ 'categoryList' => $this->categoryList,
'q' => $this->query,
'hasMarkedItems' => ClipboardHandler::getInstance()->hasMarkedItems(ClipboardHandler::getInstance()->getObjectTypeID('com.woltlab.wcf.media')),
'username' => $this->username
protected function initObjectList() {
parent::initObjectList();
+ if ($this->categoryID) {
+ $this->objectList->getConditionBuilder()->add('media.categoryID = ?', [$this->categoryID]);
+ }
if ($this->query) {
$this->objectList->addSearchConditions($this->query);
}
}
}
+ /**
+ * @inheritDoc
+ */
+ public function readData() {
+ parent::readData();
+
+ $this->categoryList = (new CategoryNodeTree('com.woltlab.wcf.media.category'))->getIterator();
+ $this->categoryList->setMaxDepth(0);
+ }
+
/**
* @inheritDoc
*/
public function readParameters() {
parent::readParameters();
+ if (isset($_REQUEST['categoryID'])) $this->categoryID = intval($_REQUEST['categoryID']);
if (isset($_REQUEST['q'])) $this->query = StringUtil::trim($_REQUEST['q']);
if (isset($_REQUEST['username'])) $this->username = StringUtil::trim($_REQUEST['username']);
* @since 3.0
*
* @property-read integer $mediaID unique id of the media file
+ * @property-read integer $categoryID id of the category the media file belongs to or `null` if it belongs to no category
* @property-read string $filename name of the physical media file
* @property-read integer $filesize size of the physical media file
* @property-read string $fileType type of the physical media file
<?php
namespace wcf\data\media;
use wcf\data\AbstractDatabaseObjectAction;
+use wcf\data\category\CategoryNodeTree;
use wcf\data\ISearchAction;
use wcf\data\IUploadAction;
use wcf\system\acl\simple\SimpleAclHandler;
+use wcf\system\category\CategoryHandler;
use wcf\system\clipboard\ClipboardHandler;
use wcf\system\database\util\PreparedStatementConditionBuilder;
use wcf\system\exception\PermissionDeniedException;
return [
'altText' => $media instanceof ViewableMedia ? $media->altText : [],
'caption' => $media instanceof ViewableMedia ? $media->caption : [],
+ 'categoryID' => $media->categoryID,
'fileHash' => $media->fileHash,
'filename' => $media->filename,
'filesize' => $media->filesize,
$mediaList->sqlLimit = 50;
$mediaList->readObjects();
+ $categoryList = (new CategoryNodeTree('com.woltlab.wcf.media.category'))->getIterator();
+ $categoryList->setMaxDepth(0);
+
return [
'hasMarkedItems' => ClipboardHandler::getInstance()->hasMarkedItems(ClipboardHandler::getInstance()->getObjectTypeID('com.woltlab.wcf.media')),
'media' => $this->getI18nMediaData($mediaList),
'template' => WCF::getTPL()->fetch('mediaManager', 'wcf', [
+ 'categoryList' => $categoryList,
'mediaList' => $mediaList,
'mode' => $this->parameters['mode']
])
I18nHandler::getInstance()->register('altText_' . $media->mediaID);
I18nHandler::getInstance()->assignVariables();
+ $categoryList = (new CategoryNodeTree('com.woltlab.wcf.media.category'))->getIterator();
+ $categoryList->setMaxDepth(0);
+
return [
'availableLanguageCount' => count(LanguageFactory::getInstance()->getLanguages()),
+ 'categoryIDs' => array_keys(CategoryHandler::getInstance()->getCategories('com.woltlab.wcf.media.category')),
'mediaData' => $this->getI18nMediaData($mediaList)[$this->getSingleObject()->mediaID],
'template' => WCF::getTPL()->fetch('mediaEditor', 'wcf', [
'__aclSimplePrefix' => 'mediaEditor_' . $media->mediaID . '_',
'__languageChooserPrefix' => 'mediaEditor_' . $media->mediaID . '_',
'aclValues' => SimpleAclHandler::getInstance()->getValues('com.woltlab.wcf.media', $media->mediaID),
'availableLanguages' => LanguageFactory::getInstance()->getLanguages(),
+ 'categoryList' => $categoryList,
'languageID' => WCF::getUser()->languageID,
'languages' => LanguageFactory::getInstance()->getLanguages(),
'media' => $media
}
}
+ $this->readInteger('categoryID', true, 'data');
$this->readInteger('languageID', true, 'data');
$this->readBoolean('isMultilingual', true, 'data');
if ($this->parameters['data']['languageID'] && !LanguageFactory::getInstance()->getLanguage($this->parameters['data']['languageID'])) {
throw new UserInputException('languageID');
}
+
+ // check category id
+ if ($this->parameters['data']['categoryID']) {
+ $category = CategoryHandler::getInstance()->getCategory($this->parameters['data']['categoryID']);
+ if ($category === null || $category->getObjectType()->objectType !== 'com.woltlab.wcf.media.category') {
+ throw new UserInputException('categoryID');
+ }
+ }
}
/**
* @inheritDoc
*/
public function update() {
+ if (isset($this->parameters['data']['categoryID']) && $this->parameters['data']['categoryID'] === 0) {
+ $this->parameters['data']['categoryID'] = null;
+ }
+
if (empty($this->objects)) {
$this->readObjects();
}
}
$this->readString('searchString', true);
- $this->readString('fileType', true);
-
- if (!$this->parameters['searchString'] && !$this->parameters['fileType']) {
- throw new UserInputException('searchString');
- }
+ $this->readInteger('categoryID', true);
$this->readBoolean('imagesOnly', true);
if ($this->parameters['imagesOnly']) {
$mediaList->getConditionBuilder()->add('media.isImage = ?', [1]);
}
+ if ($this->parameters['categoryID']) {
+ $mediaList->getConditionBuilder()->add('media.categoryID = ?', [$this->parameters['categoryID']]);
+ }
$mediaList->sqlOrderBy = 'media.uploadTime DESC';
$mediaList->sqlLimit = 50;
$mediaList->readObjectIDs();
* @param string $searchString
*/
public function addSearchConditions($searchString) {
+ if ($searchString === '') return;
+
$searchString = '%'.addcslashes($searchString, '_%').'%';
$this->sqlConditionJoins .= ' LEFT JOIN wcf'.WCF_N.'_media_content media_content ON (media_content.mediaID = media.mediaID)';
--- /dev/null
+<?php
+namespace wcf\system\category;
+use wcf\system\WCF;
+
+/**
+ * Category implementation for media files.
+ *
+ * @author Matthias Schmidt
+ * @copyright 2001-2017 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package WoltLabSuite\Core\System\Category
+ * @since 3.1
+ */
+class MediaCategoryType extends AbstractCategoryType {
+ /**
+ * @inheritDoc
+ */
+ protected $langVarPrefix = 'wcf.media.category';
+
+ /**
+ * @inheritDoc
+ */
+ protected $hasDescription = false;
+
+ /**
+ * @inheritDoc
+ */
+ protected $maximumNestingLevel = 2;
+
+ /**
+ * @inheritDoc
+ */
+ public function canAddCategory() {
+ return WCF::getSession()->getPermission('admin.content.cms.canManageMedia');
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function canDeleteCategory() {
+ return WCF::getSession()->getPermission('admin.content.cms.canManageMedia');
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function canEditCategory() {
+ return WCF::getSession()->getPermission('admin.content.cms.canManageMedia');
+ }
+}
\ No newline at end of file
// scrollbar instead. Setting a `max-width` will cause the browser to respect the page
// boundaries and nicely wrap the displayed value instead.
max-width: 100%;
+
+ &.fullWidth {
+ width: 100%;
+ }
}
.formSubmit {
}
}
}
+
+.mediaManagerCategoryList {
+ margin-bottom: 5px;
+}
<item name="wcf.acp.menu.link.cms.menu.add"><![CDATA[Menü hinzufügen]]></item>
<item name="wcf.acp.menu.link.cms.box.list"><![CDATA[Boxen]]></item>
<item name="wcf.acp.menu.link.cms.box.add"><![CDATA[Box hinzufügen]]></item>
- <item name="wcf.acp.menu.link.cms.media.list"><![CDATA[Medien]]></item>
+ <item name="wcf.acp.menu.link.media"><![CDATA[Medien]]></item>
+ <item name="wcf.acp.menu.link.media.list"><![CDATA[Medien]]></item>
+ <item name="wcf.acp.menu.link.media.category.list"><![CDATA[Kategorien]]></item>
+ <item name="wcf.acp.menu.link.media.category.add"><![CDATA[Kategorie hinzufügen]]></item>
<item name="wcf.acp.menu.link.article"><![CDATA[Artikel]]></item>
<item name="wcf.acp.menu.link.article.list"><![CDATA[Artikel]]></item>
<item name="wcf.acp.menu.link.article.add"><![CDATA[Artikel hinzufügen]]></item>
<item name="wcf.media.button.insert"><![CDATA[Einfügen]]></item>
<item name="wcf.media.button.select"><![CDATA[Auswählen]]></item>
<item name="wcf.media.caption"><![CDATA[Bildunterschrift]]></item>
+ <item name="wcf.media.category.choose"><![CDATA[Kategorien]]></item>
+ <item name="wcf.media.categoryID"><![CDATA[Kategorie]]></item>
<item name="wcf.media.chooseImage"><![CDATA[Bild auswählen]]></item>
<item name="wcf.media.delete.confirmMessage"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Möchtest du{else}Möchten Sie{/if} die Datei <span class="confirmationObject">{$title}</span> wirklich löschen?]]></item>
<item name="wcf.media.edit"><![CDATA[Datei bearbeiten]]></item>
<item name="wcf.acp.menu.link.cms.menu.add"><![CDATA[Add Menu]]></item>
<item name="wcf.acp.menu.link.cms.box.list"><![CDATA[Boxes]]></item>
<item name="wcf.acp.menu.link.cms.box.add"><![CDATA[Add Box]]></item>
- <item name="wcf.acp.menu.link.cms.media.list"><![CDATA[Media]]></item>
+ <item name="wcf.acp.menu.link.media"><![CDATA[Media]]></item>
+ <item name="wcf.acp.menu.link.media.list"><![CDATA[Media]]></item>
+ <item name="wcf.acp.menu.link.media.category.list"><![CDATA[Categories]]></item>
+ <item name="wcf.acp.menu.link.media.category.add"><![CDATA[Add Category]]></item>
<item name="wcf.acp.menu.link.article"><![CDATA[Articles]]></item>
<item name="wcf.acp.menu.link.article.list"><![CDATA[Articles]]></item>
<item name="wcf.acp.menu.link.article.add"><![CDATA[Add Article]]></item>
<item name="wcf.media.button.insert"><![CDATA[Insert]]></item>
<item name="wcf.media.button.select"><![CDATA[Select]]></item>
<item name="wcf.media.caption"><![CDATA[Caption]]></item>
+ <item name="wcf.media.category.choose"><![CDATA[Categories]]></item>
+ <item name="wcf.media.categoryID"><![CDATA[Category]]></item>
<item name="wcf.media.chooseImage"><![CDATA[Select Image]]></item>
<item name="wcf.media.delete.confirmMessage"><![CDATA[Do you really want to delete the media file <span class="confirmationObject">{$title}</span>?]]></item>
<item name="wcf.media.edit"><![CDATA[Edit Media File]]></item>
DROP TABLE IF EXISTS wcf1_media;
CREATE TABLE wcf1_media (
mediaID INT(10) NOT NULL AUTO_INCREMENT PRIMARY KEY,
+ categoryID INT(10),
filename VARCHAR(255) NOT NULL DEFAULT '',
filesize INT(10) NOT NULL DEFAULT 0,
ALTER TABLE wcf1_language_item ADD FOREIGN KEY (languageCategoryID) REFERENCES wcf1_language_category (languageCategoryID) ON DELETE CASCADE;
ALTER TABLE wcf1_language_item ADD FOREIGN KEY (packageID) REFERENCES wcf1_package (packageID) ON DELETE CASCADE;
+ALTER TABLE wcf1_media ADD FOREIGN KEY (categoryID) REFERENCES wcf1_category (categoryID) ON DELETE SET NULL;
ALTER TABLE wcf1_media ADD FOREIGN KEY (userID) REFERENCES wcf1_user (userID) ON DELETE SET NULL;
ALTER TABLE wcf1_media ADD FOREIGN KEY (languageID) REFERENCES wcf1_language (languageID) ON DELETE SET NULL;