Added first draft for application management
authorAlexander Ebert <ebert@woltlab.com>
Sun, 4 Nov 2012 02:11:37 +0000 (03:11 +0100)
committerAlexander Ebert <ebert@woltlab.com>
Sun, 4 Nov 2012 02:11:37 +0000 (03:11 +0100)
wcfsetup/install/files/acp/templates/applicationGroupAdd.tpl [new file with mode: 0644]
wcfsetup/install/files/acp/templates/applicationManagement.tpl [new file with mode: 0644]
wcfsetup/install/files/lib/acp/form/ApplicationGroupAddForm.class.php [new file with mode: 0644]
wcfsetup/install/files/lib/acp/page/ApplicationManagementPage.class.php [new file with mode: 0644]
wcfsetup/install/files/lib/data/application/ApplicationAction.class.php
wcfsetup/install/files/lib/data/application/group/ApplicationGroupAction.class.php
wcfsetup/install/files/lib/data/application/group/ViewableApplicationGroup.class.php [new file with mode: 0644]
wcfsetup/install/lang/de.xml
wcfsetup/setup/db/install.sql

diff --git a/wcfsetup/install/files/acp/templates/applicationGroupAdd.tpl b/wcfsetup/install/files/acp/templates/applicationGroupAdd.tpl
new file mode 100644 (file)
index 0000000..873adf7
--- /dev/null
@@ -0,0 +1,107 @@
+{include file='header' pageTitle='wcf.acp.application.group.add'}
+
+<header class="boxHeadline">
+       <hgroup>
+               <h1>{lang}wcf.acp.application.group.add{/lang}</h1>
+       </hgroup>
+</header>
+
+{if $errorField}
+       <p class="error">{lang}wcf.global.form.error{/lang}</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='ApplicationManagement'}{/link}" class="button"><img src="{@RELATIVE_WCF_DIR}icon/list.svg" alt="" /> <span>{lang}wcf.acp.application.management{/lang}</span></a></li>
+               </ul>
+       </nav>
+</div>
+
+<div class="container containerPadding marginTop">
+       <form method="post" action="{link controller='ApplicationGroupAdd'}{/link}">
+               <fieldset>
+                       <legend>{lang}wcf.acp.application.group.data{/lang}</legend>
+                       <dl{if $errorField == 'groupName'} class="formError"{/if}>
+                               <dt><label for="groupName">{lang}wcf.acp.application.group.groupName{/lang}</label></dt>
+                               <dd>
+                                       <input type="text" name="groupName" id="groupName" value="{$groupName}" class="long" />
+                                       {if $errorField == 'groupName'}
+                                               <small class="innerError">
+                                                       {if $errorType == 'empty'}
+                                                               {lang}wcf.global.form.error.empty{/lang}
+                                                       {else}
+                                                               {lang}wcf.acp.application.group.groupName.error.{$errorType}{/lang}
+                                                       {/if}
+                                               </small>
+                                       {/if}
+                               </dd>
+                       </dl>
+               </fieldset>
+               
+               <fieldset{if $errorField == 'applications'} class="formError"{/if}>
+                       <legend>{lang}wcf.acp.application.group.availableApplications{/lang}</legend>
+                       
+                       <div class="tabularBox">
+                               <table class="table">
+                                       <thead>
+                                               <tr>
+                                                       <th class="columnID columnPackageID" colspan="2">{lang}wcf.global.objectID{/lang}</th>
+                                                       <th class="columnText columnPackageName">{lang}wcf.acp.package.name{/lang}</th>
+                                                       <th class="columnText columnDomainName">{lang}wcf.acp.application.domainName{/lang}</th>
+                                                       <th class="columnText columnDomainPath">{lang}wcf.acp.application.domainPath{/lang}</th>
+                                                       <th class="columnText columnCookieDomain">{lang}wcf.acp.application.cookieDomain{/lang}</th>
+                                                       <th class="columnText columnCookiePath">{lang}wcf.acp.application.cookiePath{/lang}</th>
+                                                       
+                                                       {event name='headColumns'}
+                                               </tr>
+                                       </thead>
+                                       
+                                       <tbody>
+                                               {foreach from=$availableApplications item=application}
+                                                       <tr data-package="{$application->package}">
+                                                               <td class="columnIcon"><a href="{link controller='ApplicationEdit' id=$application->packageID}{/link}"><img src="{@RELATIVE_WCF_DIR}icon/edit.svg" alt="" class="icon16 jsTooltip" title="{lang}wcf.global.button.edit{/lang}" /></a></td>
+                                                               <td class="columnID columnPackageID">{#$application->packageID}</td>
+                                                               <td class="columnText columnPackageName"><a href="{link controller='PackageView' id=$application->packageID}{/link}">{lang}{$application->packageName}{/lang}</a></td>
+                                                               <td class="columnText columnDomainName">{$application->domainName}</td>
+                                                               <td class="columnText columnDomainPath">{$application->domainPath}</td>
+                                                               <td class="columnText columnCookieDomain">{$application->cookieDomain}</td>
+                                                               <td class="columnText columnCookiePath">{$application->cookiePath}</td>
+                                                               
+                                                               {event name='columns'}
+                                                       </tr>
+                                               {/foreach}
+                                       </tbody>
+                               </table>
+                       </div>
+                       
+                       {if $errorField == 'applications'}
+                               <small class="innerError">
+                                       {if $errorType == 'empty'}
+                                               {lang}wcf.global.form.error.empty{/lang}
+                                       {else}
+                                               {lang}wcf.acp.application.group.applications.error.{$errorType}{/lang}
+                                       {/if}
+                               </small>
+                       {/if}
+               </fieldset>
+               
+               <div class="formSubmit">
+                       <input type="submit" value="{lang}wcf.global.button.submit{/lang}" />
+               </div>
+       </form>
+</div>
+
+<div class="contentNavigation">
+       <nav>
+               <ul>
+                       <li><a href="{link controller='ApplicationManagement'}{/link}" class="button"><img src="{@RELATIVE_WCF_DIR}icon/list.svg" alt="" /> <span>{lang}wcf.acp.application.management{/lang}</span></a></li>
+               </ul>
+       </nav>
+</div>
+
+{include file='footer'}
diff --git a/wcfsetup/install/files/acp/templates/applicationManagement.tpl b/wcfsetup/install/files/acp/templates/applicationManagement.tpl
new file mode 100644 (file)
index 0000000..01d78b3
--- /dev/null
@@ -0,0 +1,100 @@
+{include file='header' pageTitle='wcf.acp.application.management'}
+
+{foreach from=$applicationGroups item=applicationGroup}
+       <header class="boxHeadline">
+               <hgroup>
+                       <h1>{lang}wcf.acp.application.group.title{/lang} <span class="badge">{#$applicationGroup|count}</span></h1>
+               </hgroup>
+       </header>
+       
+       <div class="tabularBox marginTop">
+               <table class="table">
+                       <thead>
+                               <tr>
+                                       <th class="columnID columnPackageID" colspan="2">{lang}wcf.global.objectID{/lang}</th>
+                                       <th class="columnText columnPackageName">{lang}wcf.acp.package.name{/lang}</th>
+                                       <th class="columnText columnDomainName">{lang}wcf.acp.application.domainName{/lang}</th>
+                                       <th class="columnText columnDomainPath">{lang}wcf.acp.application.domainPath{/lang}</th>
+                                       <th class="columnText columnCookieDomain">{lang}wcf.acp.application.cookieDomain{/lang}</th>
+                                       <th class="columnText columnCookiePath">{lang}wcf.acp.application.cookiePath{/lang}</th>
+                                       
+                                       {event name='headColumns'}
+                               </tr>
+                       </thead>
+                       
+                       <tbody>
+                               {foreach from=$applicationGroup item=application}
+                                       <tr>
+                                               <td class="columnIcon"><a href="{link controller='ApplicationEdit' id=$application->packageID}{/link}"><img src="{@RELATIVE_WCF_DIR}icon/edit.svg" alt="" class="icon16 jsTooltip" title="{lang}wcf.global.button.edit{/lang}" /></a></td>
+                                               <td class="columnID columnPackageID">{#$application->packageID}</td>
+                                               <td class="columnText columnPackageName"><a href="{link controller='PackageView' id=$application->packageID}{/link}">{lang}{$application->packageName}{/lang}</a></td>
+                                               <td class="columnText columnDomainName">{$application->domainName}</td>
+                                               <td class="columnText columnDomainPath">{$application->domainPath}</td>
+                                               <td class="columnText columnCookieDomain">{$application->cookieDomain}</td>
+                                               <td class="columnText columnCookiePath">{$application->cookiePath}</td>
+                                       </tr>
+                               {/foreach}
+                       </tbody>
+               </table>
+       </div>
+       
+       <div class="contentNavigation">
+               <nav>
+                       <ul>
+                               <li><a href="{link controller='ApplicationGroupEdit' id=$applicationGroup->groupID}{/link}" class="button"><img src="{@RELATIVE_WCF_DIR}icon/edit.svg" class="icon24" /> <span>{lang}wcf.acp.application.group.edit{/lang}</span></a></li>
+                               <li><a href="{link controller='ApplicationGroupDelete' id=$applicationGroup->groupID}{/link}" class="button"><img src="{@RELATIVE_WCF_DIR}icon/delete.svg" class="icon24" /> <span>{lang}wcf.acp.application.group.delete{/lang}</span></a></li>
+                       </ul>
+               </nav>
+       </div>
+{/foreach}
+
+{hascontent}
+       <header class="boxHeadline">
+               <hgroup>
+                       <h1>{lang}wcf.acp.application.independentApplications{/lang} <span class="badge">{#$applications|count}</span></h1>
+               </hgroup>
+       </header>
+       
+       <div class="tabularBox marginTop">
+               <table class="table">
+                       <thead>
+                               <tr>
+                                       <th class="columnID columnPackageID" colspan="2">{lang}wcf.global.objectID{/lang}</th>
+                                       <th class="columnText columnPackageName">{lang}wcf.acp.package.name{/lang}</th>
+                                       <th class="columnText columnDomainName">{lang}wcf.acp.application.domainName{/lang}</th>
+                                       <th class="columnText columnDomainPath">{lang}wcf.acp.application.domainPath{/lang}</th>
+                                       <th class="columnText columnCookieDomain">{lang}wcf.acp.application.cookieDomain{/lang}</th>
+                                       <th class="columnText columnCookiePath">{lang}wcf.acp.application.cookiePath{/lang}</th>
+                                       
+                                       {event name='headColumns'}
+                               </tr>
+                       </thead>
+                       
+                       <tbody>
+                               {content}
+                                       {foreach from=$applications item=application}
+                                               <tr>
+                                                       <td class="columnIcon"><a href="{link controller='ApplicationEdit' id=$application->packageID}{/link}"><img src="{@RELATIVE_WCF_DIR}icon/edit.svg" alt="" class="icon16 jsTooltip" title="{lang}wcf.global.button.edit{/lang}" /></a></td>
+                                                       <td class="columnID columnPackageID">{#$application->packageID}</td>
+                                                       <td class="columnText columnPackageName"><a href="{link controller='PackageView' id=$application->packageID}{/link}">{lang}{$application->packageName}{/lang}</a></td>
+                                                       <td class="columnText columnDomainName">{$application->domainName}</td>
+                                                       <td class="columnText columnDomainPath">{$application->domainPath}</td>
+                                                       <td class="columnText columnCookieDomain">{$application->cookieDomain}</td>
+                                                       <td class="columnText columnCookiePath">{$application->cookiePath}</td>
+                                               </tr>
+                                       {/foreach}
+                               {/content}
+                       </tbody>
+               </table>
+       </div>
+       
+       <div class="contentNavigation">
+               <nav>
+                       <ul>
+                               <li><a href="{link controller='ApplicationGroupAdd'}{/link}" class="button"><img src="{@RELATIVE_WCF_DIR}icon/add.svg" class="icon24" /> <span>{lang}wcf.acp.application.group.add{/lang}</span></a></li>
+                       </ul>
+               </nav>
+       </div>
+{/hascontent}
+
+{include file='footer'}
diff --git a/wcfsetup/install/files/lib/acp/form/ApplicationGroupAddForm.class.php b/wcfsetup/install/files/lib/acp/form/ApplicationGroupAddForm.class.php
new file mode 100644 (file)
index 0000000..c24d409
--- /dev/null
@@ -0,0 +1,177 @@
+<?php
+namespace wcf\acp\form;
+use wcf\data\application\group\ApplicationGroupAction;
+
+use wcf\data\application\ApplicationList;
+use wcf\system\exception\UserInputException;
+use wcf\system\WCF;
+use wcf\util\ArrayUtil;
+use wcf\util\StringUtil;
+
+/**
+ * Shows the application group add form.
+ * 
+ * @author     Alexander Ebert
+ * @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 ApplicationGroupAddForm extends ACPForm {
+       /**
+        * @see wcf\acp\form\ACPForm::$activeMenuItem
+        */
+       public $activeMenuItem = 'wcf.acp.menu.link.application';
+       
+       /**
+        * list of application package ids
+        * @var array<integer>
+        */
+       public $applications = array();
+       
+       /**
+        * list of available applications
+        * @var array<wcf\data\application\Application>
+        */
+       public $availableApplications = array();
+       
+       /**
+        * group name
+        * @var string
+        */
+       public $groupName = '';
+       
+       /**
+        * @see wcf\page\AbstractPage::$neededPermissions
+        */
+       public $neededPermissions = array('admin.system.canManageApplication');
+       
+       /**
+        * @see wcf\page\IPage::readParameters()
+        */
+       public function readParameters() {
+               parent::readParameters();
+               
+               $this->readAvailableApplications();
+       }
+       
+       /**
+        * Reads the list of available applications.
+        */
+       protected function readAvailableApplications() {
+               $applicationList = new ApplicationList();
+               $applicationList->sqlSelects = "package.package, package.packageName";
+               $applicationList->sqlJoins = "LEFT JOIN wcf".WCF_N."_package package ON (package.packageID = application.packageID)";
+               $applicationList->getConditionBuilder()->add("application.groupID IS NULL");
+               $applicationList->getConditionBuilder()->add("application.packageID <> ? ", array(1));
+               $applicationList->sqlLimit = 0;
+               $applicationList->readObjects();
+               
+               $this->availableApplications = $applicationList->getObjects();
+       }
+       
+       /**
+        * @see wcf\form\IForm::readFormParameters()
+        */
+       public function readFormParameters() {
+               parent::readFormParameters();
+               
+               if (isset($_POST['applications']) && is_array($_POST['applications'])) $this->applications = ArrayUtil::toIntegerArray($_POST['applications']);
+               if (isset($_POST['groupName'])) $this->groupName = StringUtil::trim($_POST['groupName']);
+       }
+       
+       /**
+        * @see wcf\form\IForm::validate()
+        */
+       public function validate() {
+               parent::validate();
+               
+               // validate group name
+               if (empty($this->groupName)) {
+                       throw new UserInputException('groupName');
+               }
+               else {
+                       // check for duplicates
+                       $sql = "SELECT  COUNT(*) AS count
+                               FROM    wcf".WCF_N."_application_group
+                               WHERE   groupName = ?";
+                       $statement = WCF::getDB()->prepareStatement($sql);
+                       $statement->execute(array($this->groupName));
+                       $row = $statement->fetchArray();
+                       if ($row['count']) {
+                               throw new UserInputException('groupName', 'notUnique');
+                       }
+               }
+               
+               // validate application package ids
+               if (empty($this->applications)) {
+                       throw new UserInputException('applications');
+               }
+               else {
+                       $this->applications = array_unique($this->applications);
+                       
+                       // require at least two applications
+                       if (count($this->applications) == 1) {
+                               throw new UserInputException('applications', 'single');
+                       }
+                       
+                       $packages = array();
+                       foreach ($this->applications as $packageID) {
+                               // unknown package id
+                               if (!isset($this->availableApplications[$packageID])) {
+                                       throw new UserInputException('applications', 'notValid');
+                               }
+                               
+                               $application = $this->availableApplications[$packageID];
+                               
+                               // cannot group two or more applications of the same type
+                               if (in_array($application->package, $packages)) {
+                                       throw new UserInputException('applications', 'duplicate');
+                               }
+                               
+                               $packages[] = $application->package;
+                       }
+               }
+       }
+       
+       /**
+        * @see wcf\form\IForm::save()
+        */
+       public function save() {
+               parent::save();
+               
+               // save group
+               $this->objectAction = new ApplicationGroupAction(array(), 'create', array(
+                       'applications' => $this->applications,
+                       'data' => array(
+                               'groupName' => $this->groupName
+                       )
+               ));
+               $this->objectAction->executeAction();
+               $this->saved();
+               
+               // reset values
+               $this->applications = array();
+               $this->groupName = '';
+               
+               // show success.
+               WCF::getTPL()->assign(array(
+                       'success' => true
+               ));
+       }
+       
+       /**
+        * @see wcf\page\IPage::assignVariables()
+        */
+       public function assignVariables() {
+               parent::assignVariables();
+               
+               WCF::getTPL()->assign(array(
+                       'action' => 'add',
+                       'applications' => $this->applications,
+                       'availableApplications' => $this->availableApplications,
+                       'groupName' => $this->groupName
+               ));
+       }
+}
diff --git a/wcfsetup/install/files/lib/acp/page/ApplicationManagementPage.class.php b/wcfsetup/install/files/lib/acp/page/ApplicationManagementPage.class.php
new file mode 100644 (file)
index 0000000..a4a4070
--- /dev/null
@@ -0,0 +1,90 @@
+<?php
+namespace wcf\acp\page;
+use wcf\data\application\ApplicationList;
+use wcf\data\application\group\ApplicationGroupList;
+use wcf\data\application\group\ViewableApplicationGroup;
+use wcf\page\AbstractPage;
+use wcf\system\menu\acp\ACPMenu;
+use wcf\system\WCF;
+
+/**
+ * Shows the application management page.
+ * 
+ * @author     Alexander Ebert
+ * @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 ApplicationManagementPage extends AbstractPage {
+       /**
+        * list of ungrouped applications
+        * @var array<wcf\data\application\Application>
+        */
+       public $applications = null;
+       
+       /**
+        * list of viewable application groups
+        * @var array<wcf\data\application\group\ViewableApplicationGroup>
+        */
+       public $applicationGroups = null;
+       
+       /**
+        * number of ungrouped applications
+        * @var integer
+        */
+       public $ungroupedApplications = 0;
+       
+       /**
+        * @see wcf\page\IPage::readData()
+        */
+       public function readData() {
+               parent::readData();
+               
+               $applicationList = new ApplicationList();
+               $applicationList->sqlSelects = "package.packageName";
+               $applicationList->sqlJoins = "LEFT JOIN wcf".WCF_N."_package package ON (package.packageID = application.packageID)";
+               $applicationList->getConditionBuilder()->add("application.packageID <> ?", array(1)); // exclude WCF pseudo-application
+               $applicationList->sqlLimit = 0;
+               $applicationList->readObjects();
+               
+               $applicationGroupList = new ApplicationGroupList();
+               $applicationGroupList->sqlLimit = 0;
+               $applicationGroupList->readObjects();
+               foreach ($applicationGroupList as $applicationGroup) {
+                       $this->applicationGroups[$applicationGroup->groupID] = new ViewableApplicationGroup($applicationGroup);
+               }
+               
+               foreach ($applicationList as $application) {
+                       if (!$application->groupID) {
+                               $this->applications[$application->packageID] = $application;
+                       }
+                       else {
+                               $this->applicationGroups[$application->groupID]->addApplication($application);
+                       }
+               }
+       }
+       
+       /**
+        * @see wcf\page\IPage::assignVariables()
+        */
+       public function assignVariables() {
+               parent::assignVariables();
+               
+               WCF::getTPL()->assign(array(
+                       'applications' => $this->applications,
+                       'applicationGroups' => $this->applicationGroups
+               ));
+       }
+       
+       /**
+        * @see wcf\page\IPage::show()
+        */
+       public function show() {
+               // enable menu item
+               ACPMenu::getInstance()->setActiveMenuItem('wcf.acp.menu.link.application.management');
+       
+               parent::show();
+       }
+}
index 6292309e6c6e66d8a0ad90f84cbad8243cea04b2..2fa25a99a635571ddc99110829c445c62b63b923 100644 (file)
@@ -1,6 +1,8 @@
 <?php
 namespace wcf\data\application;
 use wcf\data\AbstractDatabaseObjectAction;
+use wcf\system\WCF;
+use wcf\util\FileUtil;
 
 /**
  * Executes application-related actions.
@@ -17,4 +19,92 @@ class ApplicationAction extends AbstractDatabaseObjectAction {
         * @see wcf\data\AbstractDatabaseObjectAction::$className
         */
        protected $className = 'wcf\data\application\ApplicationEditor';
+       
+       /**
+        * Assigns a list of applications to a group and computes cookie domain and path.
+        */
+       public function group() {
+               if (empty($this->objects)) {
+                       $this->readObjects();
+               }
+               
+               $sql = "UPDATE  wcf".WCF_N."_application
+                       SET     groupID = ?,
+                               cookieDomain = ?,
+                               cookiePath = ?
+                       WHERE   packageID = ?";
+               $statement = WCF::getDB()->prepareStatement($sql);
+               
+               // calculate cookie path
+               $domains = array();
+               foreach ($this->objects as $application) {
+                       if (!isset($domains[$application->domainName])) {
+                               $domains[$application->domainName] = array();
+                       }
+                       
+                       $domains[$application->domainName][$application->packageID] = explode('/', FileUtil::removeLeadingSlash(FileUtil::removeTrailingSlash($application->domainPath)));
+               }
+               
+               WCF::getDB()->beginTransaction();
+               foreach ($domains as $domainName => $data) {
+                       $path = null;
+                       foreach ($data as $domainPath) {
+                               if ($path === null) {
+                                       $path = $domainPath;
+                               }
+                               else {
+                                       foreach ($path as $i => $part) {
+                                               if (!isset($domainPath[$i]) || $domainPath[$i] != $part) {
+                                                       // remove all following elements including current one
+                                                       foreach ($path as $j => $innerPart) {
+                                                               if ($j >= $i) {
+                                                                       unset($path[$j]);
+                                                               }
+                                                       }
+                                                       
+                                                       // skip to next domain
+                                                       continue 2;
+                                               }
+                                       }
+                               }
+                       }
+                       
+                       $path = FileUtil::addLeadingSlash(FileUtil::addTrailingSlash(implode('/', $path)));
+                       
+                       foreach (array_keys($data) as $packageID) {
+                               $statement->execute(array(
+                                       $this->parameters['groupID'],
+                                       $domainName,
+                                       $path,
+                                       $packageID
+                               ));
+                       }
+               }
+               WCF::getDB()->commitTransaction();
+       }
+       
+       /**
+        * Removes a list of applications from their group and resets the cookie domain and path.
+        */
+       public function ungroup() {
+               if (empty($this->objects)) {
+                       $this->readObjects();
+               }
+               
+               $sql = "UPDATE  wcf".WCF_N."_application
+                       SET     groupID = ?,
+                               cookieDomain = domainName,
+                               cookiePath = domainPath
+                       WHERE   packageID = ?";
+               $statement = WCF::getDB()->prepareStatement($sql);
+               
+               WCF::getDB()->beginTransaction();
+               foreach ($this->objects as $application) {
+                       $statement->execute(array(
+                               null,
+                               $application->packageID
+                       ));
+               }
+               WCF::getDB()->commitTransaction();
+       }
 }
index 2451e3c23c7412dab820a4d50c5dfb9def6e0744..dba0c9ba3c07ec70c8892a1e3d34105a1d16d9d6 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 namespace wcf\data\application\group;
+use wcf\data\application\ApplicationAction;
 use wcf\data\AbstractDatabaseObjectAction;
 
 /**
@@ -17,4 +18,18 @@ class ApplicationGroupAction extends AbstractDatabaseObjectAction {
         * @see wcf\data\AbstractDatabaseObjectAction::$className
         */
        protected $className = 'wcf\data\application\group\ApplicationGroupEditor';
+       
+       /**
+        * @see wcf\data\AbstractDatabaseObjectAction::create()
+        */
+       public function create() {
+               $applicationGroup = parent::create();
+               
+               if (isset($this->parameters['applications'])) {
+                       $applicationAction = new ApplicationAction($this->parameters['applications'], 'group', array('groupID' => $applicationGroup->groupID));
+                       $applicationAction->executeAction();
+               }
+               
+               return $applicationGroup;
+       }
 }
diff --git a/wcfsetup/install/files/lib/data/application/group/ViewableApplicationGroup.class.php b/wcfsetup/install/files/lib/data/application/group/ViewableApplicationGroup.class.php
new file mode 100644 (file)
index 0000000..d7b7a79
--- /dev/null
@@ -0,0 +1,86 @@
+<?php
+namespace wcf\data\application\group;
+use wcf\data\application\Application;
+use wcf\data\DatabaseObjectDecorator;
+
+/**
+ * Provides a viewable application group.
+ * 
+ * @author     Alexander Ebert
+ * @copyright  2001-2012 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    com.woltlab.wcf
+ * @subpackage data.application.group
+ * @category   Community Framework
+ */
+class ViewableApplicationGroup extends DatabaseObjectDecorator implements \Countable, \Iterator {
+       /**
+        * @see wcf\data\DatabaseObjectDecorator::$baseClass
+        */
+       protected static $baseClass = 'wcf\data\application\group\ApplicationGroup';
+       
+       /**
+        * list of applications
+        * @var array<wcf\data\application\Application>
+        */
+       protected $applications = array();
+       
+       /**
+        * current iterator index
+        * @var integer
+        */
+       protected $index = 0;
+       
+       /**
+        * Assigns an application to this group.
+        * 
+        * @param       wcf\data\application\Application        $application
+        */
+       public function addApplication(Application $application) {
+               if ($this->groupID == $application->groupID) {
+                       $this->applications[] = $application;
+               }
+       }
+       
+       /**
+        * @see \Countable::count()
+        */
+       public function count() {
+               return count($this->applications);
+       }
+       
+       /**
+        * @see \Iterator::current()
+        */
+       public function current() {
+               return $this->applications[$this->index];
+       }
+       
+       /**
+        * @see \Iterator::key()
+        */
+       public function key() {
+               return $this->applications[$this->index];
+       }
+       
+       /**
+        * @see \Iterator::next()
+        */
+       public function next() {
+               ++$this->index;
+       }
+       
+       /**
+        * @see \Iterator::rewind()
+        */
+       public function rewind() {
+               $this->index = 0;
+       }
+       
+       /**
+        * @see \Iterator::valid()
+        */
+       public function valid() {
+               return isset($this->applications[$this->index]);
+       }
+}
index 90764aac8218bdbfa31c0a520f3e4a35c34fafdd..5bb1ba2720ecfe19c9802ccf73471cb54a0b98a8 100644 (file)
@@ -4,6 +4,26 @@
                <item name="wcf.acp"><![CDATA[Administration]]></item>
        </category>
        
+       <category name="wcf.acp.application">
+               <item name="wcf.acp.application.cookieDomain"><![CDATA[Cookie-Domain]]></item>
+               <item name="wcf.acp.application.cookiePath"><![CDATA[Cookie-Pfad]]></item>
+               <item name="wcf.acp.application.domainName"><![CDATA[Domain]]></item>
+               <item name="wcf.acp.application.domainPath"><![CDATA[Pfad]]></item>
+               <item name="wcf.acp.application.group.add"><![CDATA[Anwendungsgruppe hinzufügen]]></item>
+               <item name="wcf.acp.application.group.applications.error.duplicate"><![CDATA[Zwei oder mehr Anwendungen des selben Typs können nicht in einer Gruppe zusammengefasst werden.]]></item>
+               <item name="wcf.acp.application.group.applications.error.notValid"><![CDATA[Eine oder mehrere ausgewählte Anwendungen sind nicht mehr verfügbar.]]></item>
+               <item name="wcf.acp.application.group.applications.error.single"><![CDATA[Eine Gruppe muss aus mindestens zwei Anwendungen bestehen.]]></item>
+               <item name="wcf.acp.application.group.availableApplications"><![CDATA[Verfügbare Anwendungen]]></item>
+               <item name="wcf.acp.application.group.data"><![CDATA[Allgemein]]></item>
+               <item name="wcf.acp.application.group.delete"><![CDATA[Anwendungsgruppe löschen]]></item>
+               <item name="wcf.acp.application.group.edit"><![CDATA[Anwendungsgruppe bearbeiten]]></item>
+               <item name="wcf.acp.application.group.groupName"><![CDATA[Name]]></item>
+               <item name="wcf.acp.application.group.groupName.error.notUnique"><![CDATA[Der Gruppenname muss einzigartig sein.]]></item>
+               <item name="wcf.acp.application.group.title"><![CDATA[Anwendungsgruppe: &bdquo;{$applicationGroup->groupName}&ldquo;]]></item>
+               <item name="wcf.acp.application.independentApplications"><![CDATA[Unabhängige Anwendungen]]></item>
+               <item name="wcf.acp.application.management"><![CDATA[Anwendungen verwalten]]></item>
+       </category>
+       
        <category name="wcf.acp.cronjob">
                <item name="wcf.acp.cronjob.list"><![CDATA[Cronjobs]]></item>
                <item name="wcf.acp.cronjob.add"><![CDATA[Cronjob hinzufügen]]></item>
        </category>
        
        <category name="wcf.acp.menu">
-               <item name="wcf.acp.menu.link.application"><![CDATA[Applikationen]]></item>
+               <item name="wcf.acp.menu.link.application"><![CDATA[Anwendungen]]></item>
                <item name="wcf.acp.menu.link.application.cache"><![CDATA[Cache]]></item>
-               <item name="wcf.acp.menu.link.application.management"><![CDATA[Applikationen verwalten]]></item>
+               <item name="wcf.acp.menu.link.application.management"><![CDATA[Anwendungen verwalten]]></item>
                <item name="wcf.acp.menu.link.content"><![CDATA[Inhalt]]></item>
                <item name="wcf.acp.menu.link.cronjob"><![CDATA[Cronjobs]]></item>
                <item name="wcf.acp.menu.link.cronjob.add"><![CDATA[Aufgabe hinzufügen]]></item>
index 259a24a0ac39549fb898d8330b62228eae7ef672..ff153f5094e659ac2b62aab2767ba1b7142891bf 100644 (file)
@@ -80,6 +80,8 @@ CREATE TABLE wcf1_application (
        packageID INT(10) NOT NULL PRIMARY KEY,
        domainName VARCHAR(255) NOT NULL,
        domainPath VARCHAR(255) NOT NULL DEFAULT '/',
+       cookieDomain VARCHAR(255) NOT NULL,
+       cookieDomainPath VARCHAR(255) NOT NULL DEFAULT '/',
        groupID INT(10),
        isPrimary TINYINT(1) NOT NULL DEFAULT 0
 );