Package search now runs via AJAX
authorAlexander Ebert <ebert@woltlab.com>
Sat, 19 Jan 2013 16:47:35 +0000 (17:47 +0100)
committerAlexander Ebert <ebert@woltlab.com>
Sat, 19 Jan 2013 16:47:35 +0000 (17:47 +0100)
Renamed UpdateServer* -> PackageUpdateServer*

26 files changed:
com.woltlab.wcf/acpMenu.xml
wcfsetup/install/files/acp/js/WCF.ACP.js
wcfsetup/install/files/acp/templates/packageSearchResultList.tpl [new file with mode: 0644]
wcfsetup/install/files/acp/templates/packageStartInstall.tpl
wcfsetup/install/files/acp/templates/packageUpdateSearch.tpl [deleted file]
wcfsetup/install/files/acp/templates/packageUpdateSearchResult.tpl [deleted file]
wcfsetup/install/files/acp/templates/packageUpdateServerAdd.tpl [new file with mode: 0644]
wcfsetup/install/files/acp/templates/packageUpdateServerList.tpl [new file with mode: 0644]
wcfsetup/install/files/acp/templates/updateServerAdd.tpl [deleted file]
wcfsetup/install/files/acp/templates/updateServerList.tpl [deleted file]
wcfsetup/install/files/js/WCF.js
wcfsetup/install/files/lib/acp/form/PackageUpdateSearchForm.class.php [deleted file]
wcfsetup/install/files/lib/acp/form/PackageUpdateServerAddForm.class.php [new file with mode: 0755]
wcfsetup/install/files/lib/acp/form/PackageUpdateServerEditForm.class.php [new file with mode: 0755]
wcfsetup/install/files/lib/acp/form/UpdateServerAddForm.class.php [deleted file]
wcfsetup/install/files/lib/acp/form/UpdateServerEditForm.class.php [deleted file]
wcfsetup/install/files/lib/acp/page/PackageUpdateSearchResultPage.class.php [deleted file]
wcfsetup/install/files/lib/acp/page/PackageUpdateServerListPage.class.php [new file with mode: 0755]
wcfsetup/install/files/lib/acp/page/UpdateServerListPage.class.php [deleted file]
wcfsetup/install/files/lib/data/package/Package.class.php
wcfsetup/install/files/lib/data/package/PackageAction.class.php
wcfsetup/install/files/lib/data/package/update/PackageUpdateAction.class.php
wcfsetup/install/files/lib/data/package/update/PackageUpdateList.class.php
wcfsetup/install/files/lib/data/package/update/ViewablePackageUpdate.class.php [new file with mode: 0644]
wcfsetup/install/lang/de.xml
wcfsetup/install/lang/en.xml

index 1a8f1ba5c4d63247657a4cf63f27e1b5c7df801e..918faa9cf0bb35537a5629f76bf30711437811f2 100644 (file)
                        <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 -->
index 260f843482697095b5e4015c2ae6859ad9c9f33b..496646946b3954a10e5e023b05d35abb52e4b2ef 100644 (file)
@@ -599,6 +599,283 @@ WCF.ACP.Package.Uninstallation = WCF.ACP.Package.Installation.extend({
        }
 });
 
+/**
+ * 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.
  */
diff --git a/wcfsetup/install/files/acp/templates/packageSearchResultList.tpl b/wcfsetup/install/files/acp/templates/packageSearchResultList.tpl
new file mode 100644 (file)
index 0000000..b2e60df
--- /dev/null
@@ -0,0 +1,45 @@
+{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
index e59a633ae1f564efd70b4e4d3a7332766979f7c1..4559b798e326fd77615e13bbe5d22ed2891e7fb8 100644 (file)
@@ -5,6 +5,16 @@
 {/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'}
diff --git a/wcfsetup/install/files/acp/templates/packageUpdateSearch.tpl b/wcfsetup/install/files/acp/templates/packageUpdateSearch.tpl
deleted file mode 100644 (file)
index 5c37b2c..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-{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'}
diff --git a/wcfsetup/install/files/acp/templates/packageUpdateSearchResult.tpl b/wcfsetup/install/files/acp/templates/packageUpdateSearchResult.tpl
deleted file mode 100644 (file)
index 84d1d21..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-{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'}
diff --git a/wcfsetup/install/files/acp/templates/packageUpdateServerAdd.tpl b/wcfsetup/install/files/acp/templates/packageUpdateServerAdd.tpl
new file mode 100644 (file)
index 0000000..bbe5a72
--- /dev/null
@@ -0,0 +1,79 @@
+{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'}
diff --git a/wcfsetup/install/files/acp/templates/packageUpdateServerList.tpl b/wcfsetup/install/files/acp/templates/packageUpdateServerList.tpl
new file mode 100644 (file)
index 0000000..b192693
--- /dev/null
@@ -0,0 +1,96 @@
+{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'}
diff --git a/wcfsetup/install/files/acp/templates/updateServerAdd.tpl b/wcfsetup/install/files/acp/templates/updateServerAdd.tpl
deleted file mode 100644 (file)
index ab4d428..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-{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'}
diff --git a/wcfsetup/install/files/acp/templates/updateServerList.tpl b/wcfsetup/install/files/acp/templates/updateServerList.tpl
deleted file mode 100644 (file)
index b62ffd7..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-{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'}
index 34f1ee58c01f9e9f19c923602281eef320055042..edd0637024072aae8f0ff66308d3a2de8beff585 100755 (executable)
@@ -5316,8 +5316,8 @@ WCF.System.PageNavigation = {
                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));
diff --git a/wcfsetup/install/files/lib/acp/form/PackageUpdateSearchForm.class.php b/wcfsetup/install/files/lib/acp/form/PackageUpdateSearchForm.class.php
deleted file mode 100644 (file)
index 35cc9d1..0000000
+++ /dev/null
@@ -1,279 +0,0 @@
-<?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();
-       }
-}
diff --git a/wcfsetup/install/files/lib/acp/form/PackageUpdateServerAddForm.class.php b/wcfsetup/install/files/lib/acp/form/PackageUpdateServerAddForm.class.php
new file mode 100755 (executable)
index 0000000..2eb0f46
--- /dev/null
@@ -0,0 +1,121 @@
+<?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();
+       }
+}
diff --git a/wcfsetup/install/files/lib/acp/form/PackageUpdateServerEditForm.class.php b/wcfsetup/install/files/lib/acp/form/PackageUpdateServerEditForm.class.php
new file mode 100755 (executable)
index 0000000..508d6c1
--- /dev/null
@@ -0,0 +1,94 @@
+<?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'
+               ));
+       }
+}
diff --git a/wcfsetup/install/files/lib/acp/form/UpdateServerAddForm.class.php b/wcfsetup/install/files/lib/acp/form/UpdateServerAddForm.class.php
deleted file mode 100755 (executable)
index 5fc82c5..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-<?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();
-       }
-}
diff --git a/wcfsetup/install/files/lib/acp/form/UpdateServerEditForm.class.php b/wcfsetup/install/files/lib/acp/form/UpdateServerEditForm.class.php
deleted file mode 100755 (executable)
index c506b7c..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-<?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'
-               ));
-       }
-}
diff --git a/wcfsetup/install/files/lib/acp/page/PackageUpdateSearchResultPage.class.php b/wcfsetup/install/files/lib/acp/page/PackageUpdateSearchResultPage.class.php
deleted file mode 100755 (executable)
index a028d41..0000000
+++ /dev/null
@@ -1,173 +0,0 @@
-<?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()
-               ));
-       }
-}
diff --git a/wcfsetup/install/files/lib/acp/page/PackageUpdateServerListPage.class.php b/wcfsetup/install/files/lib/acp/page/PackageUpdateServerListPage.class.php
new file mode 100755 (executable)
index 0000000..4cc6d4f
--- /dev/null
@@ -0,0 +1,76 @@
+<?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
+               ));
+       }
+}
diff --git a/wcfsetup/install/files/lib/acp/page/UpdateServerListPage.class.php b/wcfsetup/install/files/lib/acp/page/UpdateServerListPage.class.php
deleted file mode 100755 (executable)
index b1dbf8e..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-<?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
-               ));
-       }
-}
index 447bbe1d51d9dcda10b8b7c85fb158e886d491f7..17d7e30bb0bc175b0a40ba9c801c23995a593637 100644 (file)
@@ -12,7 +12,7 @@ use wcf\util\StringUtil;
  * 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
index 8edd8b486658527020f93770d63a40afc9ab8262..4603f02a224e5acbdd4ffb17fdd08b0771bd3ff8 100644 (file)
@@ -9,7 +9,7 @@ use wcf\system\WCF;
  * 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
index 85d47c8cd5308bdec0c9b1c16eb1713ffd16ed4a..de81ac3bc21cfb014149073362f242295f0b57b0 100644 (file)
@@ -1,12 +1,19 @@
 <?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
@@ -17,4 +24,235 @@ class PackageUpdateAction extends AbstractDatabaseObjectAction {
         * @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')
+               );
+       }
 }
index a59cdd5362cbddc37309db8069315afc5c07cdf5..0c71510fb5cedc0c560663e26e2d66470097e5bb 100644 (file)
@@ -1,12 +1,13 @@
 <?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
@@ -17,4 +18,15 @@ class PackageUpdateList extends DatabaseObjectList {
         * @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');
+               }
+       }
 }
diff --git a/wcfsetup/install/files/lib/data/package/update/ViewablePackageUpdate.class.php b/wcfsetup/install/files/lib/data/package/update/ViewablePackageUpdate.class.php
new file mode 100644 (file)
index 0000000..57d9617
--- /dev/null
@@ -0,0 +1,69 @@
+<?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;
+       }
+}
index 1f8dae9a6567703ce7dec91f2579efc301db8b0a..7f9f82a736eeeeab23f11d4bfdf68e8257582556 100644 (file)
                <item name="wcf.acp.menu.link.option"><![CDATA[Optionen]]></item>
                <item name="wcf.acp.menu.link.option.importAndExport"><![CDATA[Sichern &amp; 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>
index 400f9a6983876481f9ba4c97534d50e38de41e64..be610e212b98adccfaf9e7fd0eb7d966b207c5e9 100644 (file)
                <item name="wcf.acp.menu.link.option"><![CDATA[Options]]></item>
                <item name="wcf.acp.menu.link.option.importAndExport"><![CDATA[Import &amp; 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>