<showorder>1</showorder>
</acpmenuitem>
- <acpmenuitem name="wcf.acp.menu.link.package.database">
- <controller><![CDATA[wcf\acp\form\PackageUpdateSearchForm]]></controller>
- <parent>wcf.acp.menu.link.package.update</parent>
- <permissions>admin.system.package.canInstallPackage,admin.system.package.canUpdatePackage</permissions>
- <showorder>2</showorder>
- </acpmenuitem>
-
<acpmenuitem name="wcf.acp.menu.link.package.server">
<parent>wcf.acp.menu.link.package</parent>
- <showorder>3</showorder>
+ <showorder>2</showorder>
</acpmenuitem>
<acpmenuitem name="wcf.acp.menu.link.package.server.list">
- <controller><![CDATA[wcf\acp\page\UpdateServerListPage]]></controller>
+ <controller><![CDATA[wcf\acp\page\PackageUpdateServerListPage]]></controller>
<parent>wcf.acp.menu.link.package.server</parent>
<permissions>admin.system.package.canEditServer</permissions>
<showorder>1</showorder>
</acpmenuitem>
-
- <acpmenuitem name="wcf.acp.menu.link.package.server.add">
- <controller><![CDATA[wcf\acp\form\UpdateServerAddForm]]></controller>
- <parent>wcf.acp.menu.link.package.server</parent>
- <permissions>admin.system.package.canEditServer</permissions>
- <showorder>2</showorder>
- </acpmenuitem>
<!-- /packages -->
<!-- application -->
}
});
+/**
+ * Manages package search.
+ */
+WCF.ACP.Package.Search = Class.extend({
+ /**
+ * search button
+ * @var jQuery
+ */
+ _button: null,
+
+ /**
+ * list of cached pages
+ * @var object
+ */
+ _cache: { },
+
+ /**
+ * search container
+ * @var jQuery
+ */
+ _container: null,
+
+ /**
+ * package input field
+ * @var jQuery
+ */
+ _package: null,
+
+ /**
+ * package description input field
+ * @var jQuery
+ */
+ _packageDescription: null,
+
+ /**
+ * package name input field
+ * @var jQuery
+ */
+ _packageName: null,
+
+ /**
+ * package search result container
+ * @var jQuery
+ */
+ _packageSearchResultContainer: null,
+
+ /**
+ * package search result list
+ * @var jQuery
+ */
+ _packageSearchResultList: null,
+
+ /**
+ * number of pages
+ * @var integer
+ */
+ _pageCount: 0,
+
+ /**
+ * current page
+ * @var integer
+ */
+ _pageNo: 1,
+
+ /**
+ * action proxy
+ * @var WCF.Action:proxy
+ */
+ _proxy: null,
+
+ /**
+ * search id
+ * @var integer
+ */
+ _searchID: 0,
+
+ /**
+ * Initializes the WCF.ACP.Package.Seach class.
+ */
+ init: function() {
+ this._button = null;
+ this._cache = { };
+ this._container = $('#packageSearch');
+ this._package = null;
+ this._packageName = null;
+ this._packageSearchResultContainer = $('#packageSearchResultContainer');
+ this._packageSearchResultList = $('#packageSearchResultList');
+ this._pageCount = 0;
+ this._pageNo = 1;
+ this._searchDescription = null;
+ this._searchID = 0;
+
+ this._proxy = new WCF.Action.Proxy({
+ success: $.proxy(this._success, this)
+ });
+
+ this._initElements();
+ },
+
+ /**
+ * Initializes search elements.
+ */
+ _initElements: function() {
+ this._button = this._container.find('.formSubmit > button.jsButtonPackageSearch').disable().click($.proxy(this._search, this));
+
+ this._package = $('#package').keyup($.proxy(this._keyUp, this));
+ this._packageDescription = $('#packageDescription').keyup($.proxy(this._keyUp, this));
+ this._packageName = $('#packageName').keyup($.proxy(this._keyUp, this));
+ },
+
+ /**
+ * Handles the 'keyup' event.
+ */
+ _keyUp: function(event) {
+ if (this._package.val() === '' && this._packageDescription.val() === '' && this._packageName.val() === '') {
+ this._button.disable();
+ }
+ else {
+ this._button.enable();
+
+ // submit on [Enter]
+ if (event.which === 13) {
+ this._button.trigger('click');
+ }
+ }
+ },
+
+ /**
+ * Performs a new search.
+ */
+ _search: function() {
+ var $values = this._getSearchValues();
+ if (!this._validate($values)) {
+ return false;
+ }
+
+ $values.pageNo = this._pageNo;
+ this._proxy.setOption('data', {
+ actionName: 'search',
+ className: 'wcf\\data\\package\\update\\PackageUpdateAction',
+ parameters: $values
+ });
+ this._proxy.sendRequest();
+ },
+
+ /**
+ * Returns search values.
+ *
+ * @return object
+ */
+ _getSearchValues: function() {
+ return {
+ 'package': $.trim(this._package.val()),
+ packageDescription: $.trim(this._packageDescription.val()),
+ packageName: $.trim(this._packageName.val())
+ };
+ },
+
+ /**
+ * Validates search values.
+ *
+ * @param object values
+ * @return boolean
+ */
+ _validate: function(values) {
+ if (values['package'] === '' && values['packageDescription'] === '' && values['packageName'] === '') {
+ return false;
+ }
+
+ return true;
+ },
+
+ /**
+ * Handles successful AJAX requests.
+ *
+ * @param object data
+ * @param string textStatus
+ * @param jQuery jqXHR
+ */
+ _success: function(data, textStatus, jqXHR) {
+ switch (data.actionName) {
+ case 'getResultList':
+ this._insertTemplate(data.returnValues.template);
+ break;
+
+ case 'search':
+ this._pageCount = data.returnValues.pageCount;
+ this._searchID = data.returnValues.searchID;
+
+ this._insertTemplate(data.returnValues.template, (data.returnValues.count === undefined ? undefined : data.returnValues.count));
+ this._setupPagination();
+ break;
+ }
+ },
+
+ /**
+ * Inserts search result list template.
+ *
+ * @param string template
+ * @param integer count
+ */
+ _insertTemplate: function(template, count) {
+ this._packageSearchResultContainer.show();
+
+ this._packageSearchResultList.html(template);
+ if (count === undefined) {
+ this._content[this._pageNo] = template;
+ }
+
+ // update badge count
+ if (count !== undefined) {
+ this._content = { 1: template };
+ this._packageSearchResultContainer.find('> header > hgroup > h1 > .badge').html(count);
+ }
+ },
+
+ /**
+ * Setups pagination for current search.
+ */
+ _setupPagination: function() {
+ // remove previous instances
+ this._content = { 1: this._packageSearchResultList.html() };
+ this._packageSearchResultContainer.find('.pageNavigation').wcfPages('destroy').remove();
+
+ if (this._pageCount > 1) {
+ var $topNavigation = $('<div class="contentNavigation" />').insertBefore(this._packageSearchResultList).wcfPages({
+ activePage: this._pageNo,
+ maxPage: this._pageCount
+ }).bind('wcfpagesswitched', $.proxy(this._showPage, this));
+
+ var $bottomNavigation = $('<div class="contentNavigation" />').insertAfter(this._packageSearchResultList).wcfPages({
+ activePage: this._pageNo,
+ maxPage: this._pageCount
+ }).bind('wcfpagesswitched', $.proxy(this._showPage, this));
+ }
+ },
+
+ /**
+ * Displays requested pages or loads it.
+ *
+ * @param object event
+ * @param object data
+ */
+ _showPage: function(event, data) {
+ if (data && data.activePage) {
+ this._pageNo = data.activePage;
+ }
+
+ // validate page no
+ if (this._pageNo < 1 || this._pageNo > this._pageCount) {
+ console.debug("[WCF.ACP.Package.Search] Cannot access page " + this._pageNo + " of " + this._pageCount);
+ return;
+ }
+
+ // load content
+ if (this._content[this._pageNo] === undefined) {
+ this._proxy.setOption('data', {
+ actionName: 'getResultList',
+ className: 'wcf\\data\\package\\update\\PackageUpdateAction',
+ parameters: {
+ pageNo: this._pageNo,
+ searchID: this._searchID
+ }
+ });
+ this._proxy.sendRequest();
+ }
+ else {
+ WCF.DOMNodeInsertedHandler.enable();
+
+ // show cached content
+ this._packageSearchResultList.html(this._content[this._pageNo]);
+
+ WCF.DOMNodeInsertedHandler.disable();
+ }
+ }
+});
+
/**
* Handles option selection.
*/
--- /dev/null
+{hascontent}
+ <div class="tabularBox marginTop">
+ <table class="table">
+ <thead>
+ <tr>
+ <th colspan="2" class="columnTitle">{lang}wcf.acp.package.name{/lang}</th>
+ <th class="columnText">{lang}wcf.acp.package.author{/lang}</a></th>
+ <th class="columnText">{lang}wcf.acp.package.version{/lang}</th>
+ <th class="columnText">{lang}wcf.acp.package.license{/lang}</th>
+ <th class="columnDate">{lang}wcf.acp.package.packageDate{/lang}</a></th>
+
+ {event name='headColumns'}
+ </tr>
+ </thead>
+
+ <tbody>
+ {content}
+ {foreach from=$packageUpdates item=$package}
+ <tr class="jsPackageRow">
+ <td class="columnIcon">
+ <img src="{@$__wcf->getPath()}icon/add.svg" alt="" title="{lang}wcf.acp.package.button.install{/lang}" class="icon16 pointer jsTooltip">
+
+ {event name='buttons'}
+ </td>
+ <td class="columnTitle" title="{$package->packageDescription}"><p>{$package->packageName}</p></td>
+ <td class="columnText"><p>{if $package->authorURL}<a href="{@$__wcf->getPath()}acp/dereferrer.php?url={$package->authorURL|rawurlencode}" class="externalURL">{$package->author}</a>{else}{$package->author}{/if}</p></td>
+ <td class="columnText"><p>
+ {$package->getAccessibleVersion()->packageVersion}
+ {if $package->getAccessibleVersion()->packageUpdateVersionID != $package->getLatestVersion()->packageUpdateVersionID}
+ <img src="{@$__wcf->getPath()}icon/info.svg" alt="" title="{lang packageVersion=$package->getLatestVersion()->packageVersion}wcf.acp.package.newerVersionAvailable{/lang}" class="icon16 jsTooltip" />
+ {/if}
+ </p></td>
+ <td class="columnText"><p>{if $package->getAccessibleVersion()->licenseURL}<a href="{@$__wcf->getPath()}acp/dereferrer.php?url={$package->getAccessibleVersion()->licenseURL|rawurlencode}" class="externalURL">{$package->getAccessibleVersion()->license}</a>{else}{$package->getAccessibleVersion()->license}{/if}</p></td>
+ <td class="columnDate"><p>{@$package->getAccessibleVersion()->packageDate|time}</p></td>
+
+ {event name='columns'}
+ </tr>
+ {/foreach}
+ {/content}
+ </tbody>
+ </table>
+ </div>
+{hascontentelse}
+ <p class="info">{lang}wcf.acp.package.search.error.noMatches{/lang}</p>
+{/hascontent}
\ No newline at end of file
{/if}
{include file='header'}
+<script type="text/javascript">
+ //<![CDATA[
+ $(function() {
+ WCF.TabMenu.init();
+
+ new WCF.ACP.Package.Search();
+ });
+ //]]>
+</script>
+
<header class="boxHeadline">
<hgroup>
<h1>{lang}{@$pageTitle}{/lang}</h1>
</nav>
</div>
-<form method="post" action="{link controller='PackageStartInstall'}{/link}" enctype="multipart/form-data">
- <div class="container containerPadding marginTop">
+<div class="tabMenuContainer">
+ <nav class="tabMenu">
+ <ul>
+ <li><a href="{@$__wcf->getAnchor('packageSearch')}">{lang}wcf.acp.package.search{/lang}</a></li>
+ <li><a href="{@$__wcf->getAnchor('upload')}">{lang}wcf.acp.package.upload{/lang}</a></li>
+ </ul>
+ </nav>
+
+ <div id="packageSearch" class="container containerPadding tabMenuContent">
<fieldset>
- <legend>{lang}wcf.acp.package.source{/lang}</legend>
+ <legend>{lang}wcf.acp.package.search.conditions{/lang}</legend>
- <dl{if $errorField == 'uploadPackage'} class="formError"{/if}>
- <dt><label for="uploadPackage">{lang}wcf.acp.package.source.upload{/lang}</label></dt>
- <dd>
- <input type="file" id="uploadPackage" name="uploadPackage" value="" />
- {if $errorField == 'uploadPackage'}
- <small class="innerError">
- {if $errorType == 'empty'}
- {lang}wcf.global.form.error.empty{/lang}
- {elseif $errorType == 'phpRequirements'}
- {* todo: use language variable (-> else) *}
- <pre>{$phpRequirements|print_r}</pre>
- {else}
- {lang}wcf.acp.package.error.{@$errorType}{/lang}
- {/if}
- </small>
- {/if}
- <small>{lang}wcf.acp.package.source.upload.description{/lang}</small>
- </dd>
+ <dl>
+ <dt><label for="packageName">{lang}wcf.acp.package.search.packageName{/lang}</label></dt>
+ <dd><input type="text" id="packageName" value="" class="long" data-search-name="packageName" /></dd>
</dl>
-
- <dl{if $errorField == 'downloadPackage'} class="formError"{/if}>
- <dt><label for="downloadPackage">{lang}wcf.acp.package.source.download{/lang}</label></dt>
+ <dl>
+ <dt><label for="packageDescription">{lang}wcf.acp.package.search.packageDescription{/lang}</label></dt>
+ <dd><input type="text" id="packageDescription" value="" class="long" data-search-name="packageDescription" /></dd>
+ </dl>
+ <dl>
+ <dt><label for="package">{lang}wcf.acp.package.search.package{/lang}</label></dt>
<dd>
- <input type="text" id="downloadPackage" name="downloadPackage" value="" class="long" />
- {if $errorField == 'downloadPackage'}
- <small class="innerError">
- {lang}wcf.acp.package.error.{@$errorType}{/lang}
- </small>
- {/if}
- <small>{lang}wcf.acp.package.source.download.description{/lang}</small>
+ <input type="text" id="package" value="" class="medium" data-search-name="package" />
+ <small>{lang}wcf.acp.package.search.package.description{/lang}</small>
</dd>
</dl>
-
- {event name='sourceFields'}
</fieldset>
- {event name='fieldsets'}
+ <div class="formSubmit">
+ <button class="jsButtonPackageSearch">{lang}wcf.global.button.submit{/lang}</button>
+ </div>
+
+ <div id="packageSearchResultContainer" style="display: none;">
+ <header class="boxHeadline boxSubHeadline">
+ <hgroup>
+ <h1>{lang}wcf.acp.package.search.resultList{/lang} <span class="badge">0</span></h1>
+ </hgroup>
+ </header>
+
+ <div id="packageSearchResultList"></div>
+ </div>
</div>
- <div class="formSubmit">
- <input type="submit" name="submitButton" value="{lang}wcf.global.button.submit{/lang}" accesskey="s" />
- <input type="hidden" name="action" value="{$action}" />
- {if $packageID != 0}<input type="hidden" name="id" value="{@$packageID}" />{/if}
+ <div id="upload" class="container containerPadding tabMenuContent">
+ <form method="post" action="{link controller='PackageStartInstall'}{/link}" enctype="multipart/form-data">
+ <fieldset>
+ <legend>{lang}wcf.acp.package.source{/lang}</legend>
+
+ <dl{if $errorField == 'uploadPackage'} class="formError"{/if}>
+ <dt><label for="uploadPackage">{lang}wcf.acp.package.source.upload{/lang}</label></dt>
+ <dd>
+ <input type="file" id="uploadPackage" name="uploadPackage" value="" />
+ {if $errorField == 'uploadPackage'}
+ <small class="innerError">
+ {if $errorType == 'empty'}
+ {lang}wcf.global.form.error.empty{/lang}
+ {elseif $errorType == 'phpRequirements'}
+ {* todo: use language variable (-> else) *}
+ <pre>{$phpRequirements|print_r}</pre>
+ {else}
+ {lang}wcf.acp.package.error.{@$errorType}{/lang}
+ {/if}
+ </small>
+ {/if}
+ <small>{lang}wcf.acp.package.source.upload.description{/lang}</small>
+ </dd>
+ </dl>
+
+ <dl{if $errorField == 'downloadPackage'} class="formError"{/if}>
+ <dt><label for="downloadPackage">{lang}wcf.acp.package.source.download{/lang}</label></dt>
+ <dd>
+ <input type="text" id="downloadPackage" name="downloadPackage" value="" class="long" />
+ {if $errorField == 'downloadPackage'}
+ <small class="innerError">
+ {lang}wcf.acp.package.error.{@$errorType}{/lang}
+ </small>
+ {/if}
+ <small>{lang}wcf.acp.package.source.download.description{/lang}</small>
+ </dd>
+ </dl>
+
+ {event name='sourceFields'}
+ </fieldset>
+
+ {event name='fieldsets'}
+
+ <div class="formSubmit">
+ <input type="submit" name="submitButton" value="{lang}wcf.global.button.submit{/lang}" accesskey="s" />
+ <input type="hidden" name="action" value="{$action}" />
+ {if $packageID != 0}<input type="hidden" name="id" value="{@$packageID}" />{/if}
+ </div>
+ </form>
</div>
-</form>
+</div>
{include file='footer'}
+++ /dev/null
-{include file='header' pageTitle='wcf.acp.packageUpdate.search'}
-
-<script type="text/javascript">
- //<![CDATA[
- $(function() {
- // count checkboxes and those already checked (faster than retrieving that number with every change)
- var $checked = $('input[name="packageUpdateServerIDs[]"]:checked').length;
- var $count = $('input[name="packageUpdateServerIDs[]"]').length;
-
- // handle clicks on 'seach all'
- $('input[name="checkUncheck"]').change(function() {
- if ($(this).attr('checked')) {
- $('input[name="packageUpdateServerIDs[]"]').attr('checked', 'checked');
- $checked = $count;
- }
- else {
- $('input[name="packageUpdateServerIDs[]"]').removeAttr('checked');
- $checked = 0;
- }
- });
-
- // handle clicks on each other checkbox (literally each server)
- $('input[name="packageUpdateServerIDs[]"]').change(function() {
- if ($(this).attr('checked')) {
- $checked++;
-
- if ($checked === $count) {
- $('input[name="checkUncheck"]').attr('checked', 'checked');
- }
- }
- else {
- $('input[name="checkUncheck"]').removeAttr('checked');
- $checked--;
- }
- });
- });
- //]]>
-</script>
-
-<header class="boxHeadline">
- <hgroup>
- <h1>{lang}wcf.acp.packageUpdate.search{/lang}</h1>
- </hgroup>
-</header>
-
-{if $errorField}
- <p class="error">{lang}wcf.acp.packageUpdate.noneAvailable{/lang}</p>
-{/if}
-
-{if $updateServers|count}
- <form method="post" action="{link controller='PackageUpdateSearch'}{/link}">
- <div class="container containerPadding marginTop">
- <fieldset>
- <legend>{lang}wcf.acp.packageUpdate.search.server{/lang}</legend>
-
- <dl>
- <dt></dt>
- <dd>
- <label><input type="checkbox" name="checkUncheck" value="" /> {lang}wcf.acp.packageUpdate.search.server.all{/lang}</label>
- </dd>
- </dl>
-
- <dl id="updateServerList">
- <dt></dt>
- {foreach from=$updateServers item=updateServer}
- <dd>
- <label><input type="checkbox" name="packageUpdateServerIDs[]" value="{@$updateServer->packageUpdateServerID}" {if $updateServer->packageUpdateServerID|in_array:$packageUpdateServerIDs}checked="checked" {/if}/> {$updateServer->serverURL}</label>
- </dd>
- {/foreach}
- </dl>
-
- {event name='serverFields'}
- </fieldset>
-
- <fieldset>
- <legend>{lang}wcf.acp.packageUpdate.search.conditions{/lang}</legend>
-
- <dl>
- <dt><label for="packageName">{lang}wcf.acp.packageUpdate.search.packageName{/lang}</label></dt>
- <dd>
- <input type="text" id="packageName" name="packageName" value="{$packageName}" class="long" />
- </dd>
- <dd>
- <label><input type="checkbox" name="searchDescription" value="1" {if $searchDescription == 1}checked="checked" {/if}/> {lang}wcf.acp.packageUpdate.search.searchDescription{/lang}</label>
- </dd>
- </dl>
-
- <dl>
- <dt><label for="author">{lang}wcf.acp.packageUpdate.search.author{/lang}</label></dt>
- <dd>
- <input type="text" id="author" name="author" value="{$author}" class="medium" />
- </dd>
- </dl>
-
- <dl>
- <dt>{lang}wcf.acp.packageUpdate.search.type{/lang}</dt>
- <dd>
- <label><input type="checkbox" name="isApplication" value="1" {if $isApplication == 1}checked="checked" {/if}/> {lang}wcf.acp.packageUpdate.search.type.isApplication{/lang}</label>
- </dd>
- <dd>
- <label><input type="checkbox" name="plugin" value="1" {if $plugin == 1}checked="checked" {/if}/> {lang}wcf.acp.packageUpdate.search.type.plugin{/lang}</label>
- </dd>
- <dd>
- <label><input type="checkbox" name="other" value="1" {if $other == 1}checked="checked" {/if}/> {lang}wcf.acp.packageUpdate.search.type.other{/lang}</label>
- </dd>
- </dl>
-
- {event name='conditionFields'}
- </fieldset>
-
- {event name='fieldsets'}
- </div>
-
- <div class="formSubmit">
- <input type="submit" value="{lang}wcf.global.button.submit{/lang}" accesskey="s" />
- </div>
- </form>
-{else}
- <p class="warning">{lang}wcf.acp.updateServer.view.noneAvailable{/lang}</p>
-{/if}
-
-{include file='footer'}
+++ /dev/null
-{include file='header' pageTitle='wcf.acp.packageUpdate.search'}
-
-<header class="boxHeadline">
- <hgroup>
- <h1>{lang}wcf.acp.packageUpdate.search{/lang}</h1>
- </hgroup>
-</header>
-
-<div class="contentNavigation">
- {pages print=true assign=pagesLinks controller="PackageUpdateSearchResult" id=$searchID link="pageNo=%d&sortField=$sortField&sortOrder=$sortOrder"}
-
- {hascontent}
- <nav>
- <ul>
- {content}
- {event name='contentNavigationButtonsTop'}
- {/content}
- </ul>
- </nav>
- {/hascontent}
-</div>
-
-<form method="post" action="{link controller='PackageUpdate'}{/link}">
- {foreach from=$packages item=package}
- <article class="message"><!-- ToDo! -->
- <div>
- <hgroup class="messageHeader">
- <h1>
- {if $package[isApplication] == 1}
- <img src="{@$__wcf->getPath()}icon/window.svg" alt="" title="{lang}wcf.acp.package.list.isApplication{/lang}" class="jsTooltip" />
- {elseif $package[plugin] != ''}
- <img src="{@$__wcf->getPath()}icon/plugin.svg" alt="" title="{lang}wcf.acp.package.list.plugin{/lang}" class="jsTooltip" />
- {else}
- <img src="{@$__wcf->getPath()}icon/package.svg" alt="" title="{lang}wcf.acp.package.list.other{/lang}" class="jsTooltip" />
- {/if}
- {$package[packageName]}
- </h1>
- <hgroup>
-
- <div class="messageBody">
- <dl>
- <dt><label for="packageVersion-{$package[package]}">{lang}wcf.acp.package.list.version{/lang}</label></dt>
- <dd>
- <select id="packageVersion-{$package[package]}">
- {foreach from=$package[packageVersions] item=$packageVersion}
- <option value="{$packageVersion}"{if $packageVersion == $package[packageVersion]} selected="selected"{/if}>{$packageVersion}</option>
- {/foreach}
- </select>
- <script type="text/javascript">
- //<![CDATA[
- onloadEvents.push(function() {
- document.getElementById('packageVersion-{$package[package]|encodeJS}').onchange = function() {
- // get value
- var select = document.getElementById('packageVersion-{$package[package]|encodeJS}');
- var packageVersion = select.options[select.selectedIndex].value;
-
- // set value
- document.getElementById('updates-{$package[package]}').value = packageVersion;
- {foreach from=$package[updatableInstances] item=updatableInstance}
- document.getElementById('updates-{$updatableInstance[packageID]}').value = packageVersion;
- {/foreach}
- }
- });
- //]]>
- </script>
- </dd>
- </dl>
-
- {if $package[author] != ''}
- <dl>
- <dt><label>{lang}wcf.acp.package.list.author{/lang}</label></dt>
- <dd>
- <span>{if $package[authorURL]}<a href="{@$__wcf->getPath()}acp/dereferrer.php?url={$package[authorURL]|rawurlencode}" class="wcf-externalURL">{$package[author]}</a>{else}{$package[author]}{/if}</span>
- </dd>
- </dl>
- {/if}
-
- {if $package[packageDescription]}
- <dl>
- <dt>{lang}wcf.acp.package.description{/lang}</dt>
- <dd>{$package[packageDescription]}</dd>
- </dl>
- {/if}
-
- <fieldset>
- <legend>{lang}wcf.acp.packageUpdate.options{/lang}</legend>
-
- <dl>
- <dt></dt>
- <dd><label><input type="checkbox" id="updates-{$package[package]}" name="updates[{$package[package]}]" value="{$package[packageVersion]}" {if $selectedPackages[$package[packageID]]|isset}checked="checked" {/if}/> {if $package[instances]}{lang}wcf.acp.packageUpdate.options.installAlreadyInstalled{/lang}{else}{lang}wcf.acp.packageUpdate.options.install{/lang}{/if}</label></dd>
-
- {* update *}
- {foreach from=$package[updatableInstances] item=updatableInstance}
- <dt></dt>
- <dd><label><input type="checkbox" id="updates-{$updatableInstance[packageID]}" name="updates[{$updatableInstance[packageID]}]" value="{$package[packageVersion]}" {if $selectedPackages[$updatableInstance[packageID]]|isset}checked="checked" {/if}/> {lang}wcf.acp.packageUpdate.options.update{/lang}</label></dd>
- {/foreach}
- </dl>
- </fieldset>
- </div>
- <hr />
- </div>
- </article>
- {/foreach}
-
- <div class="formSubmit">
- <input type="submit" value="{lang}wcf.global.button.submit{/lang}" accesskey="s" />
- <input type="hidden" name="id" value="{@$searchID}" />
- </div>
-</form>
-
-<div class="contentNavigation">
- {@$pagesLinks}
-
- {hascontent}
- <nav>
- <ul>
- {content}
- {event name='contentNavigationButtonsBottom'}
- {/content}
- </ul>
- </nav>
- {/hascontent}
-</div>
-
-{include file='footer'}
--- /dev/null
+{include file='header' pageTitle='wcf.acp.updateServer.'|concat:$action}
+
+<header class="boxHeadline">
+ <hgroup>
+ <h1>{lang}wcf.acp.updateServer.{$action}{/lang}</h1>
+ </hgroup>
+</header>
+
+{if $errorField}
+ <p class="error">{lang}wcf.global.form.error{/lang}</p>
+{/if}
+
+{if $packageUpdateServer|isset && $packageUpdateServer->errorMessage}
+ <p class="warning">{lang}wcf.acp.updateServer.lastErrorMessage{/lang}<br />{$packageUpdateServer->errorMessage}</p>
+{/if}
+
+{if $success|isset}
+ <p class="success">{lang}wcf.global.form.{$action}.success{/lang}</p>
+{/if}
+
+<div class="contentNavigation">
+ <nav>
+ <ul>
+ <li><a href="{link controller='PackageUpdateServerList'}{/link}" title="{lang}wcf.acp.menu.link.package.server.list{/lang}" class="button"><img src="{@$__wcf->getPath()}icon/list.svg" alt="" class="icon24" /> <span>{lang}wcf.acp.menu.link.package.server.list{/lang}</span></a></li>
+
+ {event name='contentNavigationButtons'}
+ </ul>
+ </nav>
+</div>
+
+<form method="post" action="{if $action == 'add'}{link controller='PackageUpdateServerAdd'}{/link}{else}{link controller='PackageUpdateServerEdit' id=$packageUpdateServerID}{/link}{/if}">
+ <div class="container containerPadding marginTop">
+ <fieldset>
+ <legend>{lang}wcf.acp.updateServer.data{/lang}</legend>
+
+ <dl{if $errorField == 'serverURL'} class="formError"{/if}>
+ <dt><label for="serverURL">{lang}wcf.acp.updateServer.serverURL{/lang}</label></dt>
+ <dd>
+ <input type="url" id="serverURL" name="serverURL" value="{$serverURL}" required="required" autofocus="autofocus" class="long" />
+ {if $errorField == 'serverURL'}
+ <small class="innerError">
+ {if $errorType == 'empty'}
+ {lang}wcf.global.form.error.empty{/lang}
+ {else}
+ {lang}wcf.acp.updateServer.serverURL.error.{@$errorType}{/lang}
+ {/if}
+ </small>
+ {/if}
+ </dd>
+ </dl>
+
+ <dl>
+ <dt><label for="loginUsername">{lang}wcf.acp.updateServer.loginUsername{/lang}</label></dt>
+ <dd>
+ <input type="text" id="loginUsername" name="loginUsername" value="{$loginUsername}" class="medium" />
+ <small>{lang}wcf.acp.updateServer.loginUsername.description{/lang}</small>
+ </dd>
+ </dl>
+
+ <dl>
+ <dt><label for="loginPassword">{lang}wcf.acp.updateServer.loginPassword{/lang}</label></dt>
+ <dd>
+ <input type="password" id="loginPassword" name="loginPassword" value="{$loginPassword}" class="medium" />
+ <small><p>{lang}wcf.acp.updateServer.loginPassword.description{/lang}</p></small>
+ </dd>
+ </dl>
+
+ {event name='dataFields'}
+ </fieldset>
+
+ {event name='fieldsets'}
+ </div>
+
+ <div class="formSubmit">
+ <input type="submit" value="{lang}wcf.global.button.submit{/lang}" accesskey="s" />
+ </div>
+</form>
+
+{include file='footer'}
--- /dev/null
+{include file='header' pageTitle='wcf.acp.updateServer.list'}
+
+<script type="text/javascript">
+ //<![CDATA[
+ $(function() {
+ new WCF.Action.Delete('wcf\\data\\package\\update\\server\\PackageUpdateServerAction', '.jsUpdateServerRow');
+ new WCF.Action.Toggle('wcf\\data\\package\\update\\server\\PackageUpdateServerAction', '.jsUpdateServerRow');
+ });
+ //]]>
+</script>
+
+<header class="boxHeadline">
+ <hgroup>
+ <h1>{lang}wcf.acp.updateServer.list{/lang}</h1>
+ </hgroup>
+</header>
+
+{if $deletedPackageUpdateServerID}
+ <p class="success">{lang}wcf.acp.updateServer.delete.success{/lang}</p>
+{/if}
+
+<div class="contentNavigation">
+ {pages print=true assign=pagesLinks controller="PackageUpdateServerList" link="pageNo=%d&sortField=$sortField&sortOrder=$sortOrder"}
+
+ <nav>
+ <ul>
+ <li><a href="{link controller='PackageUpdateServerAdd'}{/link}" title="{lang}wcf.acp.updateServer.add{/lang}" class="button"><img src="{@$__wcf->getPath()}icon/add.svg" alt="" class="icon24" /> <span>{lang}wcf.acp.updateServer.add{/lang}</span></a></li>
+
+ {event name='contentNavigationButtonsTop'}
+ </ul>
+ </nav>
+</div>
+
+{hascontent}
+ <div class="tabularBox tabularBoxTitle marginTop">
+ <hgroup>
+ <h1>{lang}wcf.acp.updateServer.list{/lang} <span class="badge badgeInverse" title="{lang}wcf.acp.updateServer.list.count{/lang}">{#$items}</span></h1>
+ </hgroup>
+
+ <table class="table">
+ <thead>
+ <tr>
+ <th class="columnID columnPackageUpdateServerID{if $sortField == 'packageUpdateServerID'} active{/if}" colspan="2"><a href="{link controller='PackageUpdateServerList'}pageNo={@$pageNo}&sortField=packageUpdateServerID&sortOrder={if $sortField == 'packageUpdateServerID' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.global.objectID{/lang}{if $sortField == 'packageUpdateServerID'} <img src="{@$__wcf->getPath()}icon/sort{@$sortOrder}.svg" alt="" />{/if}</a></th>
+ <th class="columnTitle columnURL columnServer{if $sortField == 'serverURL'} active{/if}"><a href="{link controller='PackageUpdateServerList'}pageNo={@$pageNo}&sortField=serverURL&sortOrder={if $sortField == 'serverURL' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.acp.updateServer.serverURL{/lang}{if $sortField == 'serverURL'} <img src="{@$__wcf->getPath()}icon/sort{@$sortOrder}.svg" alt="" />{/if}</a></th>
+ <th class="columnDigits columnPackages{if $sortField == 'packages'} active{/if}"><a href="{link controller='PackageUpdateServerList'}pageNo={@$pageNo}&sortField=packages&sortOrder={if $sortField == 'packages' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.acp.updateServer.packages{/lang}{if $sortField == 'packages'} <img src="{@$__wcf->getPath()}icon/sort{@$sortOrder}.svg" alt="" />{/if}</a></th>
+ <th class="columnStatus{if $sortField == 'status'} active{/if}"><a href="{link controller='PackageUpdateServerList'}pageNo={@$pageNo}&sortField=status&sortOrder={if $sortField == 'status' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.acp.updateServer.status{/lang}{if $sortField == 'status'} <img src="{@$__wcf->getPath()}icon/sort{@$sortOrder}.svg" alt="" />{/if}</a></th>
+ <th class="columnText columnErrorText{if $sortField == 'errorMessage'} active{/if}"><a href="{link controller='PackageUpdateServerList'}pageNo={@$pageNo}&sortField=errorMessage&sortOrder={if $sortField == 'errorMessage' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.acp.updateServer.errorMessage{/lang}{if $sortField == 'errorMessage'} <img src="{@$__wcf->getPath()}icon/sort{@$sortOrder}.svg" alt="" />{/if}</a></th>
+ <th class="columnDate columnTimestamp{if $sortField == 'lastUpdateTime'} active{/if}"><a href="{link controller='PackageUpdateServerList'}pageNo={@$pageNo}&sortField=lastUpdateTime&sortOrder={if $sortField == 'lastUpdateTime' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.acp.updateServer.lastUpdateTime{/lang}{if $sortField == 'lastUpdateTime'} <img src="{@$__wcf->getPath()}icon/sort{@$sortOrder}.svg" alt="" />{/if}</a></th>
+
+ {event name='columnHeads'}
+ </tr>
+ </thead>
+
+ <tbody>
+ {content}
+ {foreach from=$objects item=updateServer}
+ <tr class="jsUpdateServerRow">
+ <td class="columnIcon">
+ <img src="{@$__wcf->getPath()}icon/{if !$updateServer->isDisabled}enabled{else}disabled{/if}.svg" alt="" title="{lang}wcf.global.button.{if !$updateServer->isDisabled}disable{else}enable{/if}{/lang}" class="icon16 jsToggleButton jsTooltip pointer" data-object-id="{@$updateServer->packageUpdateServerID}" data-disable-message="{lang}wcf.global.button.disable{/lang}" data-enable-message="{lang}wcf.global.button.enable{/lang}" />
+ <a href="{link controller='PackageUpdateServerEdit' id=$updateServer->packageUpdateServerID}{/link}"><img src="{@$__wcf->getPath()}icon/edit.svg" alt="" title="{lang}wcf.global.button.edit{/lang}" class="icon16 jsTooltip" /></a>
+ <img src="{@$__wcf->getPath()}icon/delete.svg" alt="" title="{lang}wcf.global.button.delete{/lang}" class="icon16 jsDeleteButton jsTooltip pointer" data-object-id="{@$updateServer->packageUpdateServerID}" data-confirm-message="{lang}wcf.acp.updateServer.delete.sure{/lang}" />
+
+ {event name='itemButtons'}
+ </td>
+ <td class="columnID"><p>{@$updateServer->packageUpdateServerID}</p></td>
+ <td class="columnText columnTitle"><p><a href="{link controller='PackageUpdateServerEdit' id=$updateServer->packageUpdateServerID}{/link}" title="{lang}wcf.acp.updateServer.edit{/lang}">{$updateServer->serverURL}</a></p></td>
+ <td class="columnDigits"><p>{#$updateServer->packages}</p></td>
+ <td class="columnStatus"><p class="badge{if $updateServer->status == 'online'} green{else} red{/if}">{@$updateServer->status}</p></td>
+ <td class="columnText"><p title="{@$updateServer->errorMessage}">{@$updateServer->errorMessage|truncate:"30"}</p></td>
+ <td class="columnDate"><p>{if $updateServer->lastUpdateTime}{@$updateServer->lastUpdateTime|time}{/if}</p></td>
+
+ {event name='columns'}
+ </tr>
+ {/foreach}
+ {/content}
+ </tbody>
+ </table>
+
+ </div>
+
+ <div class="contentNavigation">
+ {@$pagesLinks}
+
+ <nav>
+ <ul>
+ <li><a href="{link controller='PackageUpdateServerAdd'}{/link}" title="{lang}wcf.acp.updateServer.add{/lang}" class="button"><img src="{@$__wcf->getPath()}icon/add.svg" alt="" class="icon24" /> <span>{lang}wcf.acp.updateServer.add{/lang}</span></a></li>
+
+ {event name='contentNavigationButtonsBottom'}
+ </ul>
+ </nav>
+ </div>
+{hascontentelse}
+ <p class="warning">{lang}wcf.acp.updateServer.list.noneAvailable{/lang}</p>
+{/hascontent}
+
+{include file='footer'}
+++ /dev/null
-{include file='header' pageTitle='wcf.acp.updateServer.'|concat:$action}
-
-<header class="boxHeadline">
- <hgroup>
- <h1>{lang}wcf.acp.updateServer.{$action}{/lang}</h1>
- </hgroup>
-</header>
-
-{if $errorField}
- <p class="error">{lang}wcf.global.form.error{/lang}</p>
-{/if}
-
-{if $packageUpdateServer|isset && $packageUpdateServer->errorMessage}
- <p class="warning">{lang}wcf.acp.updateServer.lastErrorMessage{/lang}<br />{$packageUpdateServer->errorMessage}</p>
-{/if}
-
-{if $success|isset}
- <p class="success">{lang}wcf.global.form.{$action}.success{/lang}</p>
-{/if}
-
-<div class="contentNavigation">
- <nav>
- <ul>
- <li><a href="{link controller='UpdateServerList'}{/link}" title="{lang}wcf.acp.menu.link.package.server.list{/lang}" class="button"><img src="{@$__wcf->getPath()}icon/list.svg" alt="" class="icon24" /> <span>{lang}wcf.acp.menu.link.package.server.list{/lang}</span></a></li>
-
- {event name='contentNavigationButtons'}
- </ul>
- </nav>
-</div>
-
-<form method="post" action="{if $action == 'add'}{link controller='UpdateServerAdd'}{/link}{else}{link controller='UpdateServerEdit' id=$packageUpdateServerID}{/link}{/if}">
- <div class="container containerPadding marginTop">
- <fieldset>
- <legend>{lang}wcf.acp.updateServer.data{/lang}</legend>
-
- <dl{if $errorField == 'serverURL'} class="formError"{/if}>
- <dt><label for="serverURL">{lang}wcf.acp.updateServer.serverURL{/lang}</label></dt>
- <dd>
- <input type="url" id="serverURL" name="serverURL" value="{$serverURL}" required="required" autofocus="autofocus" class="long" />
- {if $errorField == 'serverURL'}
- <small class="innerError">
- {if $errorType == 'empty'}
- {lang}wcf.global.form.error.empty{/lang}
- {else}
- {lang}wcf.acp.updateServer.serverURL.error.{@$errorType}{/lang}
- {/if}
- </small>
- {/if}
- </dd>
- </dl>
-
- <dl>
- <dt><label for="loginUsername">{lang}wcf.acp.updateServer.loginUsername{/lang}</label></dt>
- <dd>
- <input type="text" id="loginUsername" name="loginUsername" value="{$loginUsername}" class="medium" />
- <small>{lang}wcf.acp.updateServer.loginUsername.description{/lang}</small>
- </dd>
- </dl>
-
- <dl>
- <dt><label for="loginPassword">{lang}wcf.acp.updateServer.loginPassword{/lang}</label></dt>
- <dd>
- <input type="password" id="loginPassword" name="loginPassword" value="{$loginPassword}" class="medium" />
- <small><p>{lang}wcf.acp.updateServer.loginPassword.description{/lang}</p></small>
- </dd>
- </dl>
-
- {event name='dataFields'}
- </fieldset>
-
- {event name='fieldsets'}
- </div>
-
- <div class="formSubmit">
- <input type="submit" value="{lang}wcf.global.button.submit{/lang}" accesskey="s" />
- </div>
-</form>
-
-{include file='footer'}
+++ /dev/null
-{include file='header' pageTitle='wcf.acp.updateServer.list'}
-
-<script type="text/javascript">
- //<![CDATA[
- $(function() {
- new WCF.Action.Delete('wcf\\data\\package\\update\\server\\PackageUpdateServerAction', '.jsUpdateServerRow');
- new WCF.Action.Toggle('wcf\\data\\package\\update\\server\\PackageUpdateServerAction', '.jsUpdateServerRow');
- });
- //]]>
-</script>
-
-<header class="boxHeadline">
- <hgroup>
- <h1>{lang}wcf.acp.updateServer.list{/lang}</h1>
- </hgroup>
-</header>
-
-{if $deletedPackageUpdateServerID}
- <p class="success">{lang}wcf.acp.updateServer.delete.success{/lang}</p>
-{/if}
-
-<div class="contentNavigation">
- {pages print=true assign=pagesLinks controller="UpdateServerList" link="pageNo=%d&sortField=$sortField&sortOrder=$sortOrder"}
-
- <nav>
- <ul>
- <li><a href="{link controller='UpdateServerAdd'}{/link}" title="{lang}wcf.acp.updateServer.add{/lang}" class="button"><img src="{@$__wcf->getPath()}icon/add.svg" alt="" class="icon24" /> <span>{lang}wcf.acp.updateServer.add{/lang}</span></a></li>
-
- {event name='contentNavigationButtonsTop'}
- </ul>
- </nav>
-</div>
-
-{hascontent}
- <div class="tabularBox tabularBoxTitle marginTop">
- <hgroup>
- <h1>{lang}wcf.acp.updateServer.list{/lang} <span class="badge badgeInverse" title="{lang}wcf.acp.updateServer.list.count{/lang}">{#$items}</span></h1>
- </hgroup>
-
- <table class="table">
- <thead>
- <tr>
- <th class="columnID columnPackageUpdateServerID{if $sortField == 'packageUpdateServerID'} active{/if}" colspan="2"><a href="{link controller='UpdateServerList'}pageNo={@$pageNo}&sortField=packageUpdateServerID&sortOrder={if $sortField == 'packageUpdateServerID' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.global.objectID{/lang}{if $sortField == 'packageUpdateServerID'} <img src="{@$__wcf->getPath()}icon/sort{@$sortOrder}.svg" alt="" />{/if}</a></th>
- <th class="columnTitle columnURL columnServer{if $sortField == 'serverURL'} active{/if}"><a href="{link controller='UpdateServerList'}pageNo={@$pageNo}&sortField=serverURL&sortOrder={if $sortField == 'serverURL' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.acp.updateServer.serverURL{/lang}{if $sortField == 'serverURL'} <img src="{@$__wcf->getPath()}icon/sort{@$sortOrder}.svg" alt="" />{/if}</a></th>
- <th class="columnDigits columnPackages{if $sortField == 'packages'} active{/if}"><a href="{link controller='UpdateServerList'}pageNo={@$pageNo}&sortField=packages&sortOrder={if $sortField == 'packages' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.acp.updateServer.packages{/lang}{if $sortField == 'packages'} <img src="{@$__wcf->getPath()}icon/sort{@$sortOrder}.svg" alt="" />{/if}</a></th>
- <th class="columnStatus{if $sortField == 'status'} active{/if}"><a href="{link controller='UpdateServerList'}pageNo={@$pageNo}&sortField=status&sortOrder={if $sortField == 'status' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.acp.updateServer.status{/lang}{if $sortField == 'status'} <img src="{@$__wcf->getPath()}icon/sort{@$sortOrder}.svg" alt="" />{/if}</a></th>
- <th class="columnText columnErrorText{if $sortField == 'errorMessage'} active{/if}"><a href="{link controller='UpdateServerList'}pageNo={@$pageNo}&sortField=errorMessage&sortOrder={if $sortField == 'errorMessage' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.acp.updateServer.errorMessage{/lang}{if $sortField == 'errorMessage'} <img src="{@$__wcf->getPath()}icon/sort{@$sortOrder}.svg" alt="" />{/if}</a></th>
- <th class="columnDate columnTimestamp{if $sortField == 'lastUpdateTime'} active{/if}"><a href="{link controller='UpdateServerList'}pageNo={@$pageNo}&sortField=lastUpdateTime&sortOrder={if $sortField == 'lastUpdateTime' && $sortOrder == 'ASC'}DESC{else}ASC{/if}{/link}">{lang}wcf.acp.updateServer.lastUpdateTime{/lang}{if $sortField == 'lastUpdateTime'} <img src="{@$__wcf->getPath()}icon/sort{@$sortOrder}.svg" alt="" />{/if}</a></th>
-
- {event name='columnHeads'}
- </tr>
- </thead>
-
- <tbody>
- {content}
- {foreach from=$objects item=updateServer}
- <tr class="jsUpdateServerRow">
- <td class="columnIcon">
- <img src="{@$__wcf->getPath()}icon/{if !$updateServer->isDisabled}enabled{else}disabled{/if}.svg" alt="" title="{lang}wcf.global.button.{if !$updateServer->isDisabled}disable{else}enable{/if}{/lang}" class="icon16 jsToggleButton jsTooltip pointer" data-object-id="{@$updateServer->packageUpdateServerID}" data-disable-message="{lang}wcf.global.button.disable{/lang}" data-enable-message="{lang}wcf.global.button.enable{/lang}" />
- <a href="{link controller='UpdateServerEdit' id=$updateServer->packageUpdateServerID}{/link}"><img src="{@$__wcf->getPath()}icon/edit.svg" alt="" title="{lang}wcf.global.button.edit{/lang}" class="icon16 jsTooltip" /></a>
- <img src="{@$__wcf->getPath()}icon/delete.svg" alt="" title="{lang}wcf.global.button.delete{/lang}" class="icon16 jsDeleteButton jsTooltip pointer" data-object-id="{@$updateServer->packageUpdateServerID}" data-confirm-message="{lang}wcf.acp.updateServer.delete.sure{/lang}" />
-
- {event name='itemButtons'}
- </td>
- <td class="columnID"><p>{@$updateServer->packageUpdateServerID}</p></td>
- <td class="columnText columnTitle"><p><a href="{link controller='UpdateServerEdit' id=$updateServer->packageUpdateServerID}{/link}" title="{lang}wcf.acp.updateServer.edit{/lang}">{$updateServer->serverURL}</a></p></td>
- <td class="columnDigits"><p>{#$updateServer->packages}</p></td>
- <td class="columnStatus"><p class="badge{if $updateServer->status == 'online'} green{else} red{/if}">{@$updateServer->status}</p></td>
- <td class="columnText"><p title="{@$updateServer->errorMessage}">{@$updateServer->errorMessage|truncate:"30"}</p></td>
- <td class="columnDate"><p>{if $updateServer->lastUpdateTime}{@$updateServer->lastUpdateTime|time}{/if}</p></td>
-
- {event name='columns'}
- </tr>
- {/foreach}
- {/content}
- </tbody>
- </table>
-
- </div>
-
- <div class="contentNavigation">
- {@$pagesLinks}
-
- <nav>
- <ul>
- <li><a href="{link controller='UpdateServerAdd'}{/link}" title="{lang}wcf.acp.updateServer.add{/lang}" class="button"><img src="{@$__wcf->getPath()}icon/add.svg" alt="" class="icon24" /> <span>{lang}wcf.acp.updateServer.add{/lang}</span></a></li>
-
- {event name='contentNavigationButtonsBottom'}
- </ul>
- </nav>
- </div>
-{hascontentelse}
- <p class="warning">{lang}wcf.acp.updateServer.list.noneAvailable{/lang}</p>
-{/hascontent}
-
-{include file='footer'}
var self = this;
elements.each(function(index, element) {
var $element = $(element);
- console.debug($element.data());
var $elementID = $element.wcfIdentify();
+
if (self._elements[$elementID] === undefined) {
self._elements[$elementID] = $element;
$element.find('li.jumpTo').data('elementID', $elementID).click($.proxy(self._click, self));
+++ /dev/null
-<?php
-namespace wcf\acp\form;
-use wcf\data\package\update\server\PackageUpdateServer;
-use wcf\data\search\SearchEditor;
-use wcf\form\AbstractForm;
-use wcf\system\database\util\PreparedStatementConditionBuilder;
-use wcf\system\exception\UserInputException;
-use wcf\system\package\PackageUpdateDispatcher;
-use wcf\system\request\LinkHandler;
-use wcf\system\WCF;
-use wcf\system\WCFACP;
-use wcf\util\ArrayUtil;
-use wcf\util\HeaderUtil;
-use wcf\util\StringUtil;
-
-/**
- * Shows the package update search form.
- *
- * @author Marcel Werk
- * @copyright 2001-2012 WoltLab GmbH
- * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package com.woltlab.wcf
- * @subpackage acp.form
- * @category Community Framework
- */
-class PackageUpdateSearchForm extends AbstractForm {
- /**
- * @see wcf\page\AbstractPage::$activeMenuItem
- */
- public $activeMenuItem = 'wcf.acp.menu.link.package.database';
-
- /**
- * @see wcf\page\AbstractPage::$neededPermissions
- */
- public $neededPermissions = array('admin.system.package.canUpdatePackage', 'admin.system.package.canInstallPackage');
-
- /**
- * list of package update server ids which are searched
- * @var array<integer>
- */
- public $packageUpdateServerIDs = array();
-
- /**
- * searched package name
- * @var string
- */
- public $packageName = '';
-
- /**
- * searched package author
- * @var string
- */
- public $author = '';
-
- /**
- * indicates if package description is searched
- * @var integer
- */
- public $searchDescription = 0;
-
- /**
- * indicates if plugins for already installed packages are searched
- * @var integer
- */
- public $plugin = 1;
-
- /**
- * indicates if applications are searched
- * @var integer
- */
- public $isApplication = 1;
-
- /**
- * indicates if packages that aren't plugins or applications are searched
- * @var integer
- */
- public $other = 0;
-
- /**
- * list of available update servers
- * @var array<wcf\data\package\update\server\PackageUpdateServer>
- */
- public $updateServers = array();
-
- /**
- * ids of package updates
- * @var string
- */
- public $packageUpdateIDs = '';
-
- /**
- * @see wcf\form\IForm::readFormParameters()
- */
- public function readFormParameters() {
- parent::readFormParameters();
-
- $this->plugin = $this->isApplication = 0;
- if (isset($_POST['packageUpdateServerIDs']) && is_array($_POST['packageUpdateServerIDs'])) $this->packageUpdateServerIDs = ArrayUtil::toIntegerArray($_POST['packageUpdateServerIDs']);
- if (isset($_POST['packageName'])) $this->packageName = StringUtil::trim($_POST['packageName']);
- if (isset($_POST['author'])) $this->author = StringUtil::trim($_POST['author']);
- if (isset($_POST['searchDescription'])) $this->searchDescription = intval($_POST['searchDescription']);
- if (isset($_POST['plugin'])) $this->plugin = intval($_POST['plugin']);
- if (isset($_POST['isApplication'])) $this->isApplication = intval($_POST['isApplication']);
- if (isset($_POST['other'])) $this->other = intval($_POST['other']);
- }
-
- /**
- * @see wcf\form\IForm::validate()
- */
- public function validate() {
- parent::validate();
-
- // refresh package database
- PackageUpdateDispatcher::getInstance()->refreshPackageDatabase($this->packageUpdateServerIDs);
-
- // build conditions
- $conditions = new PreparedStatementConditionBuilder();
-
- // update servers
- if (!empty($this->packageUpdateServerIDs)) {
- $conditions->add("packageUpdateServerID IN (?)", array($this->packageUpdateServerIDs));
- }
-
- // name
- if (!empty($this->packageName)) {
- $condition = "packageName LIKE ?";
- $parameters = array('%'.$this->packageName.'%');
-
- if ($this->searchDescription) {
- $condition .= " OR packageDescription LIKE ?";
- $parameters[] = '%'.$this->packageName.'%';
- }
-
- $conditions->add('('.$condition.')', $parameters);
- }
-
- // author
- if (!empty($this->author)) $conditions->add("author LIKE ?", array($this->author));
-
- // package type
- if (($this->plugin == 0 || $this->isApplication == 0 || $this->other == 0) && ($this->plugin == 1 || $this->isApplication == 1 || $this->other == 1)) {
- if ($this->isApplication == 1) {
- $condition = 'isApplication = 1';
- if ($this->plugin == 1) {
- $condition .= " OR plugin IN (SELECT package FROM wcf".WCF_N."_package)";
- }
- else if ($this->other == 1) {
- $condition .= " OR plugin = ''";
- }
-
- $conditions->add('('.$condition.')');
- }
- else if ($this->plugin == 1) {
- $condition = "plugin IN (SELECT package FROM wcf".WCF_N."_package)";
- if ($this->other == 1) {
- $condition .= " OR isApplication = 0";
- }
-
- $conditions->add('('.$condition.')');
- }
- else if ($this->other) {
- $conditions->add("(isApplication = 0 AND plugin = '')");
- }
- }
-
- // search package database
- $packages = array();
- $packageUpdateIDs = array();
- $sql = "SELECT package, packageUpdateID
- FROM wcf".WCF_N."_package_update
- ".$conditions;
- $statement = WCF::getDB()->prepareStatement($sql, 1000);
- $statement->execute($conditions->getParameters());
- while ($row = $statement->fetchArray()) {
- $packageUpdateIDs[] = $row['packageUpdateID'];
-
- if (!isset($packages[$row['package']])) $packages[$row['package']] = array();
- $packages[$row['package']][$row['packageUpdateID']] = array();
- }
-
- if (empty($packageUpdateIDs)) {
- throw new UserInputException('packageName');
- }
-
- // remove duplicates
- $condition = '';
- $statementParameters = array();
- foreach ($packageUpdateIDs as $packageUpdateID) {
- if (!empty($condition)) $condition .= ',';
- $condition .= '?';
- $statementParameters[] = $packageUpdateID;
- }
-
- $sql = "SELECT puv.packageVersion, pu.package, pu.packageUpdateID
- FROM wcf".WCF_N."_package_update_version puv
- LEFT JOIN wcf".WCF_N."_package_update pu
- ON (pu.packageUpdateID = puv.packageUpdateID)
- WHERE puv.packageUpdateID IN (".$condition.")";
- $statement = WCF::getDB()->prepareStatement($sql);
- $statement->execute($statementParameters);
- while ($row = $statement->fetchArray()) {
- $packages[$row['package']][$row['packageUpdateID']][] = $row['packageVersion'];
- }
-
- foreach ($packages as $packageUpdates) {
- if (count($packageUpdates) > 1) {
- foreach ($packageUpdates as $packageUpdateID => $versions) {
- usort($versions, array('wcf\data\package\Package', 'compareVersion'));
- $packageUpdates[$packageUpdateID] = array_pop($versions);
- }
-
- uasort($packageUpdates, array('wcf\data\package\Package', 'compareVersion'));
- }
-
- $keys = array_keys($packageUpdates);
- if (!empty($this->packageUpdateIDs)) $this->packageUpdateIDs .= ',';
- $this->packageUpdateIDs .= array_pop($keys);
- }
- }
-
- /**
- * @see wcf\form\IForm::save()
- */
- public function save() {
- parent::save();
-
- // save search
- $search = SearchEditor::create(array(
- 'userID' => WCF::getUser()->userID,
- 'searchData' => $this->packageUpdateServerIDs,
- 'searchTime' => TIME_NOW,
- 'searchType' => 'packages'
- ));
-
- $this->saved();
-
- // forward
- $url = LinkHandler::getInstance()->getLink('PackageUpdateSearchResult', array('id' => $search->searchID));
- HeaderUtil::redirect($url);
- exit;
- }
-
- /**
- * @see wcf\page\IPage::readData()
- */
- public function readData() {
- parent::readData();
-
- $this->updateServers = PackageUpdateServer::getActiveUpdateServers();
- }
-
- /**
- * @see wcf\page\IPage::assignVariables()
- */
- public function assignVariables() {
- parent::assignVariables();
-
- WCF::getTPL()->assign(array(
- 'updateServers' => $this->updateServers,
- 'packageName' => $this->packageName,
- 'searchDescription' => $this->searchDescription,
- 'author' => $this->author,
- 'isApplication' => $this->isApplication,
- 'plugin' => $this->plugin,
- 'other' => $this->other,
- 'packageUpdateServerIDs' => $this->packageUpdateServerIDs
- ));
- }
-
- /**
- * @see wcf\page\IPage::assignVariables()
- */
- public function show() {
- // check master password
- WCFACP::checkMasterPassword();
-
- parent::show();
- }
-}
--- /dev/null
+<?php
+namespace wcf\acp\form;
+use wcf\data\package\update\server\PackageUpdateServer;
+use wcf\data\package\update\server\PackageUpdateServerAction;
+use wcf\form\AbstractForm;
+use wcf\system\exception\UserInputException;
+use wcf\system\WCF;
+use wcf\system\WCFACP;
+use wcf\util\StringUtil;
+
+/**
+ * Shows the server add form.
+ *
+ * @author Marcel Werk
+ * @copyright 2001-2013 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package com.woltlab.wcf
+ * @subpackage acp.form
+ * @category Community Framework
+ */
+class PackageUpdateServerAddForm extends AbstractForm {
+ /**
+ * @see wcf\page\AbstractPage::$activeMenuItem
+ */
+ public $activeMenuItem = 'wcf.acp.menu.link.package.server';
+
+ /**
+ * @see wcf\page\AbstractPage::$neededPermissions
+ */
+ public $neededPermissions = array('admin.system.package.canEditServer');
+
+ /**
+ * server url
+ * @var string
+ */
+ public $serverURL = '';
+
+ /**
+ * server login username
+ * @var string
+ */
+ public $loginUsername = '';
+
+ /**
+ * server login password
+ * @var string
+ */
+ public $loginPassword = '';
+
+ /**
+ * @see wcf\form\IForm::readFormParameters()
+ */
+ public function readFormParameters() {
+ parent::readFormParameters();
+
+ if (isset($_POST['serverURL'])) $this->serverURL = StringUtil::trim($_POST['serverURL']);
+ if (isset($_POST['loginUsername'])) $this->loginUsername = $_POST['loginUsername'];
+ if (isset($_POST['loginPassword'])) $this->loginPassword = $_POST['loginPassword'];
+ }
+
+ /**
+ * @see wcf\form\IForm::validate()
+ */
+ public function validate() {
+ parent::validate();
+
+ if (empty($this->serverURL)) {
+ throw new UserInputException('serverURL');
+ }
+
+ if (!PackageUpdateServer::isValidServerURL($this->serverURL)) {
+ throw new UserInputException('serverURL', 'notValid');
+ }
+ }
+
+ /**
+ * @see wcf\form\IForm::save()
+ */
+ public function save() {
+ parent::save();
+
+ // save server
+ $this->objectAction = new PackageUpdateServerAction(array(), 'create', array('data' => array(
+ 'serverURL' => $this->serverURL,
+ 'loginUsername' => $this->loginUsername,
+ 'loginPassword' => $this->loginPassword
+ )));
+ $this->objectAction->executeAction();
+ $this->saved();
+
+ // reset values
+ $this->serverURL = $this->loginUsername = $this->loginPassword = '';
+
+ // show success message
+ WCF::getTPL()->assign('success', true);
+ }
+
+ /**
+ * @see wcf\page\IPage::assignVariables()
+ */
+ public function assignVariables() {
+ parent::assignVariables();
+
+ WCF::getTPL()->assign(array(
+ 'serverURL' => $this->serverURL,
+ 'loginUsername' => $this->loginUsername,
+ 'loginPassword' => $this->loginPassword,
+ 'action' => 'add'
+ ));
+ }
+
+ /**
+ * @see wcf\page\IPage::assignVariables()
+ */
+ public function show() {
+ // check master password
+ WCFACP::checkMasterPassword();
+
+ parent::show();
+ }
+}
--- /dev/null
+<?php
+namespace wcf\acp\form;
+use wcf\data\package\update\server\PackageUpdateServer;
+use wcf\data\package\update\server\PackageUpdateServerAction;
+use wcf\form\AbstractForm;
+use wcf\system\exception\IllegalLinkException;
+use wcf\system\WCF;
+
+/**
+ * Shows the server edit form.
+ *
+ * @author Marcel Werk
+ * @copyright 2001-2013 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package com.woltlab.wcf
+ * @subpackage acp.form
+ * @category Community Framework
+ */
+class PackageUpdateServerEditForm extends PackageUpdateServerAddForm {
+ /**
+ * @see wcf\page\AbstractPage::$activeMenuItem
+ */
+ public $activeMenuItem = 'wcf.acp.menu.link.package.server';
+
+ /**
+ * update server id
+ * @var integer
+ */
+ public $packageUpdateServerID = 0;
+
+ /**
+ * active package update server
+ * @var wcf\data\package\update\server\PackageUpdateServer
+ */
+ public $updateServer = null;
+
+ /**
+ * @see wcf\page\IPage::readParameters()
+ */
+ public function readParameters() {
+ parent::readParameters();
+
+ if (isset($_REQUEST['id'])) $this->packageUpdateServerID = intval($_REQUEST['id']);
+ $this->updateServer = new PackageUpdateServer($this->packageUpdateServerID);
+ if (!$this->updateServer->packageUpdateServerID) {
+ throw new IllegalLinkException();
+ }
+ }
+
+ /**
+ * @see wcf\form\IForm::save()
+ */
+ public function save() {
+ AbstractForm::save();
+
+ // save server
+ $this->objectAction = new PackageUpdateServerAction(array($this->packageUpdateServerID), 'update', array('data' => array(
+ 'serverURL' => $this->serverURL,
+ 'loginUsername' => $this->loginUsername,
+ 'loginPassword' => $this->loginPassword
+ )));
+ $this->objectAction->executeAction();
+ $this->saved();
+
+ // show success message
+ WCF::getTPL()->assign('success', true);
+ }
+
+ /**
+ * @see wcf\page\IPage::readData()
+ */
+ public function readData() {
+ parent::readData();
+
+ if (empty($_POST)) {
+ $this->serverURL = $this->updateServer->serverURL;
+ $this->loginUsername = $this->updateServer->loginUsername;
+ $this->loginPassword = $this->updateServer->loginPassword;
+ }
+ }
+
+ /**
+ * @see wcf\page\IPage::assignVariables()
+ */
+ public function assignVariables() {
+ parent::assignVariables();
+
+ WCF::getTPL()->assign(array(
+ 'packageUpdateServerID' => $this->packageUpdateServerID,
+ 'packageUpdateServer' => $this->updateServer,
+ 'action' => 'edit'
+ ));
+ }
+}
+++ /dev/null
-<?php
-namespace wcf\acp\form;
-use wcf\data\package\update\server\PackageUpdateServer;
-use wcf\data\package\update\server\PackageUpdateServerAction;
-use wcf\form\AbstractForm;
-use wcf\system\exception\UserInputException;
-use wcf\system\WCF;
-use wcf\system\WCFACP;
-use wcf\util\StringUtil;
-
-/**
- * Shows the server add form.
- *
- * @author Marcel Werk
- * @copyright 2001-2012 WoltLab GmbH
- * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package com.woltlab.wcf
- * @subpackage acp.form
- * @category Community Framework
- */
-class UpdateServerAddForm extends AbstractForm {
- /**
- * @see wcf\page\AbstractPage::$activeMenuItem
- */
- public $activeMenuItem = 'wcf.acp.menu.link.package.server.add';
-
- /**
- * @see wcf\page\AbstractPage::$neededPermissions
- */
- public $neededPermissions = array('admin.system.package.canEditServer');
-
- /**
- * server url
- * @var string
- */
- public $serverURL = '';
-
- /**
- * server login username
- * @var string
- */
- public $loginUsername = '';
-
- /**
- * server login password
- * @var string
- */
- public $loginPassword = '';
-
- /**
- * @see wcf\form\IForm::readFormParameters()
- */
- public function readFormParameters() {
- parent::readFormParameters();
-
- if (isset($_POST['serverURL'])) $this->serverURL = StringUtil::trim($_POST['serverURL']);
- if (isset($_POST['loginUsername'])) $this->loginUsername = $_POST['loginUsername'];
- if (isset($_POST['loginPassword'])) $this->loginPassword = $_POST['loginPassword'];
- }
-
- /**
- * @see wcf\form\IForm::validate()
- */
- public function validate() {
- parent::validate();
-
- if (empty($this->serverURL)) {
- throw new UserInputException('serverURL');
- }
-
- if (!PackageUpdateServer::isValidServerURL($this->serverURL)) {
- throw new UserInputException('serverURL', 'notValid');
- }
- }
-
- /**
- * @see wcf\form\IForm::save()
- */
- public function save() {
- parent::save();
-
- // save server
- $this->objectAction = new PackageUpdateServerAction(array(), 'create', array('data' => array(
- 'serverURL' => $this->serverURL,
- 'loginUsername' => $this->loginUsername,
- 'loginPassword' => $this->loginPassword
- )));
- $this->objectAction->executeAction();
- $this->saved();
-
- // reset values
- $this->serverURL = $this->loginUsername = $this->loginPassword = '';
-
- // show success message
- WCF::getTPL()->assign('success', true);
- }
-
- /**
- * @see wcf\page\IPage::assignVariables()
- */
- public function assignVariables() {
- parent::assignVariables();
-
- WCF::getTPL()->assign(array(
- 'serverURL' => $this->serverURL,
- 'loginUsername' => $this->loginUsername,
- 'loginPassword' => $this->loginPassword,
- 'action' => 'add'
- ));
- }
-
- /**
- * @see wcf\page\IPage::assignVariables()
- */
- public function show() {
- // check master password
- WCFACP::checkMasterPassword();
-
- parent::show();
- }
-}
+++ /dev/null
-<?php
-namespace wcf\acp\form;
-use wcf\data\package\update\server\PackageUpdateServer;
-use wcf\data\package\update\server\PackageUpdateServerAction;
-use wcf\form\AbstractForm;
-use wcf\system\exception\IllegalLinkException;
-use wcf\system\WCF;
-
-/**
- * Shows the server edit form.
- *
- * @author Marcel Werk
- * @copyright 2001-2012 WoltLab GmbH
- * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package com.woltlab.wcf
- * @subpackage acp.form
- * @category Community Framework
- */
-class UpdateServerEditForm extends UpdateServerAddForm {
- /**
- * @see wcf\page\AbstractPage::$activeMenuItem
- */
- public $activeMenuItem = 'wcf.acp.menu.link.package.server';
-
- /**
- * update server id
- * @var integer
- */
- public $packageUpdateServerID = 0;
-
- /**
- * active package update server
- * @var wcf\data\package\update\server\PackageUpdateServer
- */
- public $updateServer = null;
-
- /**
- * @see wcf\page\IPage::readParameters()
- */
- public function readParameters() {
- parent::readParameters();
-
- if (isset($_REQUEST['id'])) $this->packageUpdateServerID = intval($_REQUEST['id']);
- $this->updateServer = new PackageUpdateServer($this->packageUpdateServerID);
- if (!$this->updateServer->packageUpdateServerID) {
- throw new IllegalLinkException();
- }
- }
-
- /**
- * @see wcf\form\IForm::save()
- */
- public function save() {
- AbstractForm::save();
-
- // save server
- $this->objectAction = new PackageUpdateServerAction(array($this->packageUpdateServerID), 'update', array('data' => array(
- 'serverURL' => $this->serverURL,
- 'loginUsername' => $this->loginUsername,
- 'loginPassword' => $this->loginPassword
- )));
- $this->objectAction->executeAction();
- $this->saved();
-
- // show success message
- WCF::getTPL()->assign('success', true);
- }
-
- /**
- * @see wcf\page\IPage::readData()
- */
- public function readData() {
- parent::readData();
-
- if (empty($_POST)) {
- $this->serverURL = $this->updateServer->serverURL;
- $this->loginUsername = $this->updateServer->loginUsername;
- $this->loginPassword = $this->updateServer->loginPassword;
- }
- }
-
- /**
- * @see wcf\page\IPage::assignVariables()
- */
- public function assignVariables() {
- parent::assignVariables();
-
- WCF::getTPL()->assign(array(
- 'packageUpdateServerID' => $this->packageUpdateServerID,
- 'packageUpdateServer' => $this->updateServer,
- 'action' => 'edit'
- ));
- }
-}
+++ /dev/null
-<?php
-namespace wcf\acp\page;
-use wcf\data\package\Package;
-use wcf\data\search\Search;
-use wcf\page\SortablePage;
-use wcf\system\database\util\PreparedStatementConditionBuilder;
-use wcf\system\exception\IllegalLinkException;
-use wcf\system\WCF;
-
-/**
- * Shows the list of package update search results.
- *
- * @author Marcel Werk
- * @copyright 2001-2012 WoltLab GmbH
- * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package com.woltlab.wcf
- * @subpackage acp.page
- * @category Community Framework
- */
-class PackageUpdateSearchResultPage extends SortablePage {
- /**
- * @see wcf\page\AbstractPage::$activeMenuItem
- */
- public $activeMenuItem = 'wcf.acp.menu.link.package.database';
-
- /**
- * @see wcf\page\AbstractPage::$neededPermissions
- */
- public $neededPermissions = array('admin.system.package.canUpdatePackage', 'admin.system.package.canInstallPackage');
-
- /**
- * @see wcf\page\SortablePage::$defaultSortField
- */
- public $defaultSortField = 'packageName';
-
- /**
- * @see wcf\page\SortablePage::$validSortFields
- */
- public $validSortFields = array('package', 'packageName', 'author');
-
- /**
- * id of the package update search
- * @var integer
- */
- public $searchID = 0;
-
- /**
- * search object
- * @var wcf\data\search\Search
- */
- public $search = null;
-
- /**
- * list with data of package updates
- * @var array
- */
- public $packages = array();
-
- /**
- * @see wcf\page\IPage::readParameters()
- */
- public function readParameters() {
- parent::readParameters();
-
- if (isset($_REQUEST['searchID'])) $this->searchID = intval($_REQUEST['searchID']);
-
- // get search data
- $conditions = new PreparedStatementConditionBuilder();
- $conditions->add("searchID = ?", array($this->searchID));
- $conditions->add("userID = ?", array(WCF::getUser()->userID));
- $conditions->add("searchType = ?", array('packages'));
-
- $sql = "SELECT *
- FROM wcf".WCF_N."_search
- ".$conditions;
- $statement = WCF::getDB()->prepareStatement($sql);
- $statement->execute($conditions->getParameters());
-
- $this->search = new Search(null, $statement->fetchArray());
- if (empty($this->search->searchID)) {
- throw new IllegalLinkException();
- }
- }
-
- /**
- * @see wcf\page\IPage::readData()
- */
- public function readData() {
- parent::readData();
-
- // read packages
- $this->readPackages();
- }
-
- /**
- * @see wcf\page\MultipleLinkPage::countItems()
- */
- public function countItems() {
- $conditions = new PreparedStatementConditionBuilder();
- $conditions->add("packageUpdateID IN (?)", array(explode(',', $this->search->searchData)));
-
- $sql = "SELECT COUNT(*) AS count
- FROM wcf".WCF_N."_package_update
- ".$conditions;
- $statement = WCF::getDB()->prepareStatement($sql);
- $statement->execute($conditions->getParameters());
- $row = $statement->fetchArray();
-
- return $row['count'];
- }
-
- /**
- * Gets a list of packages.
- */
- protected function readPackages() {
- if ($this->items) {
- $conditions = new PreparedStatementConditionBuilder();
- $conditions->add("packageUpdateID IN (?)", array(explode(',', $this->search->searchData)));
-
- $sql = "SELECT *
- FROM wcf".WCF_N."_package_update
- ".$conditions."
- ORDER BY ".$this->sortField." ".$this->sortOrder;
- $statement = WCF::getDB()->prepareStatement($sql, $this->itemsPerPage, ($this->pageNo - 1) * $this->itemsPerPage);
- $statement->execute($conditions->getParameters());
- while ($row = $statement->fetchArray()) {
- // default values
- $row['updatableInstances'] = array();
- $row['packageVersions'] = array();
- $row['packageVersion'] = '1.0.0';
- $row['instances'] = 0;
-
- // get package versions
- $sql = "SELECT packageVersion
- FROM wcf".WCF_N."_package_update_version
- WHERE packageUpdateID IN (
- SELECT packageUpdateID
- FROM wcf".WCF_N."_package_update
- WHERE package = ?
- )";
- $statement2 = WCF::getDB()->prepareStatement($sql);
- $statement2->execute(array($row['package']));
- while ($row2 = $statement2->fetchArray()) {
- $row['packageVersions'][] = $row2['packageVersion'];
- }
-
- if (!empty($row['packageVersions'])) {
- // remove duplicates
- $row['packageVersions'] = array_unique($row['packageVersions']);
- // sort versions
- usort($row['packageVersions'], array('wcf\data\package\Package', 'compareVersion'));
- // take lastest version
- $row['packageVersion'] = end($row['packageVersions']);
- }
-
- $this->packages[] = $row;
- }
- }
- }
-
- /**
- * @see wcf\page\IPage::assignVariables()
- */
- public function assignVariables() {
- parent::assignVariables();
-
- WCF::getTPL()->assign(array(
- 'searchID' => $this->searchID,
- 'packages' => $this->packages,
- 'selectedPackages' => array()
- ));
- }
-}
--- /dev/null
+<?php
+namespace wcf\acp\page;
+use wcf\page\SortablePage;
+use wcf\system\WCF;
+
+/**
+ * Shows information about available update package servers.
+ *
+ * @author Marcel Werk
+ * @copyright 2001-2013 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package com.woltlab.wcf
+ * @subpackage acp.page
+ * @category Community Framework
+ */
+class PackageUpdateServerListPage extends SortablePage {
+ /**
+ * @see wcf\page\AbstractPage::$activeMenuItem
+ */
+ public $activeMenuItem = 'wcf.acp.menu.link.package.server.list';
+
+ /**
+ * @see wcf\page\AbstractPage::$neededPermissions
+ */
+ public $neededPermissions = array('admin.system.package.canEditServer');
+
+ /**
+ * @see wcf\page\SortablePage::$defaultSortField
+ */
+ public $defaultSortField = 'serverURL';
+
+ /**
+ * @see wcf\page\SortablePage::$validSortFields
+ */
+ public $validSortFields = array('packageUpdateServerID', 'serverURL', 'status', 'errorMessage', 'lastUpdateTime', 'packages');
+
+ /**
+ * @see wcf\page\MultipleLinkPage::$objectListClassName
+ */
+ public $objectListClassName = 'wcf\data\package\update\server\PackageUpdateServerList';
+
+ /**
+ * id of a package update server that has just been deleted
+ * @var integer
+ */
+ public $deletedPackageUpdateServerID = 0;
+
+ /**
+ * @see wcf\page\IPage::readParameters()
+ */
+ public function readParameters() {
+ parent::readParameters();
+
+ if (isset($_REQUEST['deletedPackageUpdateServerID'])) $this->deletedPackageUpdateServerID = intval($_REQUEST['deletedPackageUpdateServerID']);
+ }
+
+ /**
+ * @see wcf\page\MultipleLinkPage::readObjects()
+ */
+ public function readObjects() {
+ $this->sqlOrderBy = ($this->sortField != 'packages' ? 'package_update_server.' : '') . $this->sortField.' '.$this->sortOrder;
+
+ parent::readObjects();
+ }
+
+ /**
+ * @see wcf\page\IPage::assignVariables()
+ */
+ public function assignVariables() {
+ parent::assignVariables();
+
+ WCF::getTPL()->assign(array(
+ 'deletedPackageUpdateServerID' => $this->deletedPackageUpdateServerID
+ ));
+ }
+}
+++ /dev/null
-<?php
-namespace wcf\acp\page;
-use wcf\page\SortablePage;
-use wcf\system\WCF;
-
-/**
- * Shows information about available update package servers.
- *
- * @author Marcel Werk
- * @copyright 2001-2012 WoltLab GmbH
- * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package com.woltlab.wcf
- * @subpackage acp.page
- * @category Community Framework
- */
-class UpdateServerListPage extends SortablePage {
- /**
- * @see wcf\page\AbstractPage::$activeMenuItem
- */
- public $activeMenuItem = 'wcf.acp.menu.link.package.server.list';
-
- /**
- * @see wcf\page\AbstractPage::$neededPermissions
- */
- public $neededPermissions = array('admin.system.package.canEditServer');
-
- /**
- * @see wcf\page\SortablePage::$defaultSortField
- */
- public $defaultSortField = 'serverURL';
-
- /**
- * @see wcf\page\SortablePage::$validSortFields
- */
- public $validSortFields = array('packageUpdateServerID', 'serverURL', 'status', 'errorMessage', 'lastUpdateTime', 'packages');
-
- /**
- * @see wcf\page\MultipleLinkPage::$objectListClassName
- */
- public $objectListClassName = 'wcf\data\package\update\server\PackageUpdateServerList';
-
- /**
- * id of a package update server that has just been deleted
- * @var integer
- */
- public $deletedPackageUpdateServerID = 0;
-
- /**
- * @see wcf\page\IPage::readParameters()
- */
- public function readParameters() {
- parent::readParameters();
-
- if (isset($_REQUEST['deletedPackageUpdateServerID'])) $this->deletedPackageUpdateServerID = intval($_REQUEST['deletedPackageUpdateServerID']);
- }
-
- /**
- * @see wcf\page\MultipleLinkPage::readObjects()
- */
- public function readObjects() {
- $this->sqlOrderBy = ($this->sortField != 'packages' ? 'package_update_server.' : '') . $this->sortField.' '.$this->sortOrder;
-
- parent::readObjects();
- }
-
- /**
- * @see wcf\page\IPage::assignVariables()
- */
- public function assignVariables() {
- parent::assignVariables();
-
- WCF::getTPL()->assign(array(
- 'deletedPackageUpdateServerID' => $this->deletedPackageUpdateServerID
- ));
- }
-}
* Represents a package.
*
* @author Alexander Ebert
- * @copyright 2001-2012 WoltLab GmbH
+ * @copyright 2001-2013 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
* @package com.woltlab.wcf
* @subpackage data.package
* Executes package-related actions.
*
* @author Alexander Ebert
- * @copyright 2001-2012 WoltLab GmbH
+ * @copyright 2001-2013 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
* @package com.woltlab.wcf
* @subpackage data.package
<?php
namespace wcf\data\package\update;
+use wcf\data\package\update\version\PackageUpdateVersion;
+use wcf\data\search\Search;
+use wcf\data\search\SearchEditor;
use wcf\data\AbstractDatabaseObjectAction;
+use wcf\system\database\util\PreparedStatementConditionBuilder;
+use wcf\system\exception\PermissionDeniedException;
+use wcf\system\exception\UserInputException;
+use wcf\system\WCF;
/**
* Executes package update-related actions.
*
* @author Alexander Ebert
- * @copyright 2001-2012 WoltLab GmbH
+ * @copyright 2001-2013 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
* @package com.woltlab.wcf
* @subpackage data.package.update
* @see wcf\data\AbstractDatabaseObjectAction::$className
*/
protected $className = 'wcf\data\package\update\PackageUpdateEditor';
+
+ /**
+ * search object
+ * @var wcf\data\search\Search
+ */
+ protected $search = null;
+
+ /**
+ * Validates parameters to search for installable packages.
+ */
+ public function validateSearch() {
+ WCF::getSession()->checkPermissions(array('admin.system.package.canInstallPackage'));
+
+ $this->readString('package', true);
+ $this->readString('packageDescription', true);
+ $this->readString('packageName', true);
+ $this->readBoolean('searchDescription', true);
+
+ if (empty($this->parameters['package']) && empty($this->parameters['packageDescription']) && empty($this->parameters['packageName'])) {
+ throw new PermissionDeniedException();
+ }
+ }
+
+ /**
+ * Returns a result list of a search for installable packages.
+ *
+ * @return array
+ */
+ public function search() {
+ $conditions = new PreparedStatementConditionBuilder();
+ if (!empty($this->parameters['package'])) {
+ $conditions->add("package_update.package LIKE ?", array('%'.$this->parameters['package'].'%'));
+ }
+ if (!empty($this->parameters['packageDescription'])) {
+ $conditions->add("package_update.packageDescription LIKE ?", array('%'.$this->parameters['packageDescription'].'%'));
+ }
+ if (!empty($this->parameters['packageName'])) {
+ $conditions->add("package_update.packageName LIKE ?", array('%'.$this->parameters['packageName'].'%'));
+ }
+
+ // find matching packages
+ $sql = "SELECT package_update.packageUpdateID
+ FROM wcf".WCF_N."_package_update package_update
+ ".$conditions."
+ ORDER BY package_update.packageName ASC";
+ $statement = WCF::getDB()->prepareStatement($sql, 1000);
+ $statement->execute($conditions->getParameters());
+ $packageUpdateIDs = array();
+ while ($row = $statement->fetchArray()) {
+ $packageUpdateIDs[] = $row['packageUpdateID'];
+ }
+
+ // no matches found
+ if (empty($packageUpdateIDs)) {
+ WCF::getTPL()->assign(array(
+ 'packageUpdates' => array()
+ ));
+
+ return array(
+ 'count' => 0,
+ 'pageCount' => 0,
+ 'searchID' => 0,
+ 'template' => WCF::getTPL()->fetch('packageSearchResultList')
+ );
+ }
+
+ // filter by version
+ $conditions = new PreparedStatementConditionBuilder();
+ $conditions->add("puv.packageUpdateID IN (?)", array($packageUpdateIDs));
+ $sql = "SELECT pu.package, puv.packageUpdateVersionID, puv.packageUpdateID, puv.packageVersion, puv.isAccessible
+ FROM wcf".WCF_N."_package_update_version puv
+ LEFT JOIN wcf".WCF_N."_package_update pu
+ ON (pu.packageUpdateID = puv.packageUpdateID)
+ ".$conditions;
+ $statement = WCF::getDB()->prepareStatement($sql);
+ $statement->execute($conditions->getParameters());
+ $packageVersions = array();
+ while ($row = $statement->fetchArray()) {
+ $package = $row['package'];
+ if (!isset($packageVersions[$package])) {
+ $packageVersions[$package] = array();
+ }
+
+ $packageUpdateID = $row['packageUpdateID'];
+ if (!isset($packageVersions[$package][$packageUpdateID])) {
+ $packageVersions[$package][$packageUpdateID] = array(
+ 'accessible' => array(),
+ 'existing' => array()
+ );
+ }
+
+ if ($row['isAccessible']) {
+ $packageVersions[$package][$packageUpdateID]['accessible'][$row['packageUpdateVersionID']] = $row['packageVersion'];
+ }
+ $packageVersions[$package][$packageUpdateID]['existing'][$row['packageUpdateVersionID']] = $row['packageVersion'];
+ }
+
+ // determine highest versions
+ $packageUpdates = array();
+ foreach ($packageVersions as $package => $versionData) {
+ $accessible = $existing = $versions = array();
+
+ foreach ($versionData as $packageUpdateID => $versionTypes) {
+ // ignore unaccessible packages
+ if (empty($versionTypes['accessible'])) {
+ continue;
+ }
+
+ uasort($versionTypes['accessible'], array('wcf\data\package\Package', 'compareVersion'));
+ uasort($versionTypes['existing'], array('wcf\data\package\Package', 'compareVersion'));
+
+ $accessibleVersion = array_slice($versionTypes['accessible'], -1, 1, true);
+ $existingVersion = array_slice($versionTypes['existing'], -1, 1, true);
+
+ $ak = key($accessibleVersion);
+ $av = current($accessibleVersion);
+ $ek = key($existingVersion);
+ $ev = current($existingVersion);
+
+ $accessible[$av] = $ak;
+ $existing[$ev] = $ek;
+ $versions[$ak] = $packageUpdateID;
+ $versions[$ek] = $packageUpdateID;
+ }
+
+ uksort($accessible, array('wcf\data\package\Package', 'compareVersion'));
+ uksort($existing, array('wcf\data\package\Package', 'compareVersion'));
+
+ $accessible = array_pop($accessible);
+ $existing = array_pop($existing);
+ $packageUpdates[$versions[$accessible]] = array(
+ 'accessible' => $accessible,
+ 'existing' => $existing
+ );
+ }
+
+ $search = SearchEditor::create(array(
+ 'userID' => WCF::getUser()->userID,
+ 'searchData' => serialize($packageUpdates),
+ 'searchTime' => TIME_NOW,
+ 'searchType' => 'acpPackageSearch'
+ ));
+
+ // forward call to build the actual result list
+ $updateAction = new PackageUpdateAction(array(), 'getResultList', array(
+ 'pageNo' => 1,
+ 'search' => $search
+ ));
+
+ $returnValues = $updateAction->executeAction();
+ return $returnValues['returnValues'];
+ }
+
+ /**
+ * Validates parameters to return a result list for a previous search.
+ */
+ public function validateGetResultList() {
+ WCF::getSession()->checkPermissions(array('admin.system.package.canInstallPackage'));
+
+ $this->readInteger('pageNo');
+ $this->readInteger('searchID');
+
+ $this->search = new Search($this->parameters['searchID']);
+ if (!$this->search->searchID || $this->search->userID != WCF::getUser()->userID) {
+ throw new UserInputException('searchID');
+ }
+ }
+
+ /**
+ * Returns a result list for a previous search.
+ *
+ * @return array
+ */
+ public function getResultList() {
+ if ($this->search === null && isset($this->parameters['search']) && $this->parameters['search'] instanceof Search) {
+ $this->search = $this->parameters['search'];
+ }
+ $updateData = unserialize($this->search->searchData);
+
+ // get package updates
+ $conditions = new PreparedStatementConditionBuilder();
+ $conditions->add("packageUpdateID IN (?)", array(array_keys($updateData)));
+
+ $sql = "SELECT packageUpdateID, packageName, packageDescription, author, authorURL
+ FROM wcf".WCF_N."_package_update
+ ".$conditions;
+ $statement = WCF::getDB()->prepareStatement($sql, 20, ($this->parameters['pageNo'] - 1) * 20);
+ $statement->execute($conditions->getParameters());
+ $packageUpdates = $packageVersionIDs = array();
+ while ($packageUpdate = $statement->fetchObject('wcf\data\package\update\PackageUpdate')) {
+ $packageUpdates[$packageUpdate->packageUpdateID] = new ViewablePackageUpdate($packageUpdate);
+
+ // collect package version ids
+ $versionIDs = $updateData[$packageUpdate->packageUpdateID];
+ $packageVersionIDs[] = $versionIDs['accessible'];
+ $packageVersionIDs[] = $versionIDs['existing'];
+ }
+
+ // read update versions
+ $conditions = new PreparedStatementConditionBuilder();
+ $conditions->add("packageUpdateVersionID IN (?)", array($packageVersionIDs));
+
+ $sql = "SELECT packageUpdateVersionID, packageVersion, packageDate, license, licenseURL
+ FROM wcf".WCF_N."_package_update_version
+ ".$conditions;
+ $statement = WCF::getDB()->prepareStatement($sql);
+ $statement->execute($conditions->getParameters());
+ $updateVersions = array();
+ while ($updateVersion = $statement->fetchObject('wcf\data\package\update\version\PackageUpdateVersion')) {
+ $updateVersions[$updateVersion->packageUpdateVersionID] = $updateVersion;
+ }
+
+ // assign versions
+ foreach ($packageUpdates as $packageUpdateID => $packageUpdate) {
+ $versionIDs = $updateData[$packageUpdate->packageUpdateID];
+ $packageUpdate->setAccessibleVersion($updateVersions[$versionIDs['accessible']]);
+ $packageUpdate->setLatestVersion($updateVersions[$versionIDs['existing']]);
+ }
+
+ WCF::getTPL()->assign(array(
+ 'packageUpdates' => $packageUpdates
+ ));
+
+ $count = count($updateData);
+ return array(
+ 'count' => $count,
+ 'pageCount' => ceil($count / 20),
+ 'searchID' => $this->search->searchID,
+ 'template' => WCF::getTPL()->fetch('packageSearchResultList')
+ );
+ }
}
<?php
namespace wcf\data\package\update;
use wcf\data\DatabaseObjectList;
+use wcf\system\database\util\PreparedStatementConditionBuilder;
/**
* Represents a list of package updates.
*
* @author Alexander Ebert
- * @copyright 2001-2012 WoltLab GmbH
+ * @copyright 2001-2013 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
* @package com.woltlab.wcf
* @subpackage data.package.update
* @see wcf\data\DatabaseObjectList::$className
*/
public $className = 'wcf\data\package\update\PackageUpdate';
+
+ /**
+ * @see wcf\data\DatabaseObjectList::__construct()
+ */
+ public function __construct($useSqlOr = false) {
+ parent::__construct();
+
+ if ($useSqlOr) {
+ $this->conditionBuilder = new PreparedStatementConditionBuilder(true, 'OR');
+ }
+ }
}
--- /dev/null
+<?php
+namespace wcf\data\package\update;
+use wcf\data\package\update\version\PackageUpdateVersion;
+use wcf\data\DatabaseObjectDecorator;
+
+/**
+ * Provides a viewable package update object.
+ *
+ * @author Alexander Ebert
+ * @copyright 2001-2013 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package com.woltlab.wcf
+ * @subpackage data.package.update
+ * @category Community Framework
+ */
+class ViewablePackageUpdate extends DatabaseObjectDecorator {
+ /**
+ * @see wcf\data\DatabaseObjectDecorator::$baseClass
+ */
+ protected static $baseClass = 'wcf\data\package\update\PackageUpdate';
+
+ /**
+ * latest accessible package update version object
+ * @var wcf\data\package\update\version\PackageUpdateVersion
+ */
+ protected $accessibleVersion = null;
+
+ /**
+ * latest package update version object
+ * @var wcf\data\package\update\version\PackageUpdateVersion
+ */
+ protected $latestVersion = null;
+
+ /**
+ * Sets latest accessible package update version object.
+ *
+ * @param wcf\data\package\update\version\PackageUpdateVersion $latestVersion
+ */
+ public function setAccessibleVersion(PackageUpdateVersion $latestVersion) {
+ $this->accessibleVersion = $latestVersion;
+ }
+
+ /**
+ * Sets latest package update version object.
+ *
+ * @param wcf\data\package\update\version\PackageUpdateVersion $latestVersion
+ */
+ public function setLatestVersion(PackageUpdateVersion $latestVersion) {
+ $this->latestVersion = $latestVersion;
+ }
+
+ /**
+ * Returns latest accessible package update version object.
+ *
+ * @return wcf\data\package\update\version\PackageUpdateVersion
+ */
+ public function getAccessibleVersion() {
+ return $this->accessibleVersion;
+ }
+
+ /**
+ * Returns latest package update version object.
+ *
+ * @return wcf\data\package\update\version\PackageUpdateVersion
+ */
+ public function getLatestVersion() {
+ return $this->latestVersion;
+ }
+}
<item name="wcf.acp.menu.link.option"><![CDATA[Optionen]]></item>
<item name="wcf.acp.menu.link.option.importAndExport"><![CDATA[Sichern & Wiederherstellen]]></item>
<item name="wcf.acp.menu.link.package"><![CDATA[Pakete]]></item>
- <item name="wcf.acp.menu.link.package.database"><![CDATA[Pakete suchen]]></item>
<item name="wcf.acp.menu.link.package.install"><![CDATA[Paket installieren]]></item>
- <item name="wcf.acp.menu.link.package.server.add"><![CDATA[Server hinzufügen]]></item>
<item name="wcf.acp.menu.link.package.server.list"><![CDATA[Server auflisten]]></item>
<item name="wcf.acp.menu.link.package.list"><![CDATA[Pakete auflisten]]></item>
<item name="wcf.acp.menu.link.package.autoupdate"><![CDATA[Automatisches Update]]></item>
<item name="wcf.acp.package.application.title"><![CDATA[Anwendungen]]></item>
<item name="wcf.acp.package.author"><![CDATA[Entwickler]]></item>
<item name="wcf.acp.package.button.info"><![CDATA[Informationen]]></item>
+ <item name="wcf.acp.package.button.installPackage"><![CDATA[Paket installieren]]></item>
<item name="wcf.acp.package.button.uninstall"><![CDATA[Deinstallieren]]></item>
<item name="wcf.acp.package.button.update"><![CDATA[Aktualisieren]]></item>
<item name="wcf.acp.package.dependencies.dependent"><![CDATA[Abhängige Pakete]]></item>
<item name="wcf.acp.package.installation.step.prepare"><![CDATA[Installation wird vorbereitet …]]></item>
<item name="wcf.acp.package.installation.title"><![CDATA[Installation]]></item>
<item name="wcf.acp.package.installation.requiredVersion"><![CDATA[Benötigte Version]]></item>
+ <item name="wcf.acp.package.license"><![CDATA[Lizenz]]></item>
<item name="wcf.acp.package.list"><![CDATA[Paketliste]]></item>
<item name="wcf.acp.package.list.detailed"><![CDATA[Detaillierte Paketliste]]></item>
<item name="wcf.acp.package.name"><![CDATA[Paket]]></item>
<item name="wcf.acp.package.packageDir.notAvailable"><![CDATA[Das angegebene Verzeichnis enthält bereits eine Anwendung.]]></item>
<item name="wcf.acp.package.plugin.installed"><![CDATA[Installierte Pakete]]></item>
<item name="wcf.acp.package.plugin.title"><![CDATA[Erweiterungen]]></item>
+ <item name="wcf.acp.package.search"><![CDATA[Paket suchen]]></item>
+ <item name="wcf.acp.package.search.conditions"><![CDATA[Suchbegriffe]]></item>
+ <item name="wcf.acp.package.search.package"><![CDATA[Paketbezeichner]]></item>
+ <item name="wcf.acp.package.search.package.description"><![CDATA[Suche nach einem bestimmten Paketbezeichner, z.B. „com.woltlab.wcf“]]></item>
+ <item name="wcf.acp.package.search.packageDescription"><![CDATA[Paketbeschreibung]]></item>
+ <item name="wcf.acp.package.search.packageName"><![CDATA[Paketname]]></item>
+ <item name="wcf.acp.package.search.resultList"><![CDATA[Suchergebnisse]]></item>
<item name="wcf.acp.package.source"><![CDATA[Datenquelle]]></item>
<item name="wcf.acp.package.source.download"><![CDATA[Paket herunterladen]]></item>
<item name="wcf.acp.package.source.download.description"><![CDATA[Geben Sie den direkten Pfad zur Paketdatei an. Dabei kann es sich um die Internetadresse der Paketdatei oder alternativ den Pfad zur Paketdatei im Dateisystem handeln.]]></item>
<item name="wcf.acp.menu.link.option"><![CDATA[Options]]></item>
<item name="wcf.acp.menu.link.option.importAndExport"><![CDATA[Import & export]]></item>
<item name="wcf.acp.menu.link.package"><![CDATA[Packages]]></item>
- <item name="wcf.acp.menu.link.package.database"><![CDATA[Search packages]]></item>
<item name="wcf.acp.menu.link.package.install"><![CDATA[Install package]]></item>
- <item name="wcf.acp.menu.link.package.server.add"><![CDATA[Add new server]]></item>
<item name="wcf.acp.menu.link.package.server.list"><![CDATA[List update server]]></item>
<item name="wcf.acp.menu.link.package.list"><![CDATA[List packages]]></item>
<item name="wcf.acp.menu.link.package.autoupdate"><![CDATA[Automatic update]]></item>