</dd>
</dl>
+ <dl>
+ <dt><label for="landingPageID">{lang}wcf.acp.application.landingPage{/lang}</label></dt>
+ <dd>
+ <select name="landingPageID" id="landingPageID">
+ <option value="0">{lang}wcf.global.noSelection{/lang}</option>
+
+ {foreach from=$pageNodeList item=pageNode}
+ {if !$pageNode->requireObjectID}
+ <option value="{@$pageNode->pageID}"{if $pageNode->pageID == $landingPageID} selected{/if} data-identifier="{@$pageNode->identifier}">{if $pageNode->getDepth() > 1}{@" "|str_repeat:($pageNode->getDepth() - 1)}{/if}{$pageNode->name}</option>
+ {/if}
+ {/foreach}
+ </select>
+ <small>{lang}wcf.acp.application.landingPage.description{/lang}</small>
+ </dd>
+ </dl>
+
{event name='domainFields'}
</section>
<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 columnLandingPageID">{lang}wcf.acp.application.landingPage{/lang}</th>
{event name='columnHeads'}
</tr>
<td class="columnTitle columnPackageName"><a href="{link controller='ApplicationEdit' id=$application->packageID}{/link}">{$application->getPackage()}</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 columnLandingPageID">
+ {if $application->landingPageID && $pageList[$application->landingPageID]|isset}
+ {$pageList[$application->landingPageID]}
+ {else}
+ {lang}wcf.global.noSelection{/lang}
+ {/if}
+ </td>
{event name='columns'}
</tr>
use wcf\data\application\ApplicationAction;
use wcf\data\application\ViewableApplication;
use wcf\data\package\PackageCache;
+use wcf\data\page\Page;
+use wcf\data\page\PageNodeTree;
use wcf\system\application\ApplicationHandler;
use wcf\form\AbstractForm;
+use wcf\system\cache\builder\ApplicationCacheBuilder;
+use wcf\system\cache\builder\RoutingCacheBuilder;
use wcf\system\exception\IllegalLinkException;
use wcf\system\exception\UserInputException;
use wcf\system\Regex;
* viewable application object
* @var ViewableApplication
*/
- public $application = null;
+ public $application;
/**
* cookie domain
*/
public $domainPath = '';
+ /**
+ * landing page id
+ * @var integer
+ */
+ public $landingPageID = 0;
+
/**
* @inheritDoc
*/
*/
public $templateName = 'applicationEdit';
+ /**
+ * nested list of page nodes
+ * @var \RecursiveIteratorIterator
+ */
+ public $pageNodeList;
+
/**
* @inheritDoc
*/
if (!$this->application->packageID) {
throw new IllegalLinkException();
}
+
+ $this->pageNodeList = (new PageNodeTree())->getNodeList();
}
/**
if (isset($_POST['cookieDomain'])) $this->cookieDomain = StringUtil::trim($_POST['cookieDomain']);
if (isset($_POST['domainName'])) $this->domainName = StringUtil::trim($_POST['domainName']);
if (isset($_POST['domainPath'])) $this->domainPath = StringUtil::trim($_POST['domainPath']);
+ if (isset($_POST['landingPageID'])) $this->landingPageID = intval($_POST['landingPageID']);
}
/**
$this->cookieDomain = $this->application->cookieDomain;
$this->domainName = $this->application->domainName;
$this->domainPath = $this->application->domainPath;
+ $this->landingPageID = $this->application->landingPageID;
}
}
WCF::getTPL()->assign('conflictApplication', PackageCache::getInstance()->getPackage($row['packageID']));
throw new UserInputException('domainPath', 'conflict');
}
+
+ if ($this->landingPageID) {
+ $page = new Page($this->landingPageID);
+ if (!$page->pageID) {
+ throw new UserInputException('landingPageID');
+ }
+ else if ($page->requireObjectID) {
+ throw new UserInputException('landingPageID', 'invalid');
+ }
+ }
}
/**
$this->objectAction = new ApplicationAction([$this->application->getDecoratedObject()], 'update', ['data' => array_merge($this->additionalFields, [
'cookieDomain' => mb_strtolower($this->cookieDomain),
'domainName' => mb_strtolower($this->domainName),
- 'domainPath' => $this->domainPath
+ 'domainPath' => $this->domainPath,
+ 'landingPageID' => ($this->landingPageID ?: null)
])]);
$this->objectAction->executeAction();
$this->saved();
+ if ($this->application->packageID === 1) {
+ if ($this->landingPageID) {
+ (new Page($this->landingPageID))->setAsLandingPage();
+ }
+ else {
+ $sql = "UPDATE wcf".WCF_N."_page
+ SET isLandingPage = ?
+ WHERE isLandingPage = ?";
+ $statement = WCF::getDB()->prepareStatement($sql);
+ $statement->execute([
+ 0,
+ 1
+ ]);
+ }
+ }
+
// re-calculate cookie settings
ApplicationHandler::rebuild();
+ // reset caches to reflect new landing page
+ ApplicationCacheBuilder::getInstance()->reset();
+ RoutingCacheBuilder::getInstance()->reset();
+
// show success message
WCF::getTPL()->assign('success', true);
}
'cookieDomain' => $this->cookieDomain,
'domainName' => $this->domainName,
'domainPath' => $this->domainPath,
- 'packageID' => $this->packageID
+ 'packageID' => $this->packageID,
+ 'pageNodeList' => $this->pageNodeList,
+ 'landingPageID' => $this->landingPageID
]);
}
}
<?php
namespace wcf\acp\page;
use wcf\data\application\ViewableApplicationList;
+use wcf\data\page\PageList;
use wcf\page\AbstractPage;
use wcf\system\WCF;
public function assignVariables() {
parent::assignVariables();
+ $pageList = new PageList();
+ $pageList->readObjects();
+
WCF::getTPL()->assign([
- 'applicationList' => $this->applicationList
+ 'applicationList' => $this->applicationList,
+ 'pageList' => $pageList->getObjects()
]);
}
}
* @property-read string $domainPath path used to access the application
* @property-read string $cookieDomain domain used to set cookies (corresponds to `domain` cookie property; may not contain path components)
* @property-read integer $isTainted is `1` if the application is being uninstalled and thus should not be loaded during uninstallation, otherwise `0`
+ * @property-read integer $landingPageID id of the page that is used as initial page when app is accessed without a controller name
*/
class Application extends DatabaseObject {
/**
use wcf\data\TDatabaseObjectPermissions;
use wcf\system\acl\simple\SimpleAclResolver;
use wcf\system\application\ApplicationHandler;
+use wcf\system\cache\builder\ApplicationCacheBuilder;
+use wcf\system\cache\builder\RoutingCacheBuilder;
use wcf\system\database\util\PreparedStatementConditionBuilder;
use wcf\system\exception\SystemException;
use wcf\system\request\LinkHandler;
$this->pageID
]);
WCF::getDB()->commitTransaction();
+
+ $sql = "UPDATE wcf".WCF_N."_application
+ SET landingPageID = ?
+ WHERE packageID = ?";
+ $statement = WCF::getDB()->prepareStatement($sql);
+ $statement->execute([
+ $this->pageID,
+ 1
+ ]);
+ WCF::getDB()->commitTransaction();
+
+ // reset caches to reflect new landing page
+ ApplicationCacheBuilder::getInstance()->reset();
+ RoutingCacheBuilder::getInstance()->reset();
}
/**
namespace wcf\system\cache\builder;
use wcf\data\application\Application;
use wcf\data\page\Page;
+use wcf\data\page\PageCache;
use wcf\page\CmsPage;
use wcf\system\application\ApplicationHandler;
use wcf\system\request\ControllerMap;
}
}
else {
- $controller = WCF::getApplicationObject($application)->getPrimaryController();
+ if ($application->landingPageID) {
+ $page = PageCache::getInstance()->getPage($application->landingPageID);
+ if ($page !== null) {
+ if ($page->controller) {
+ $controller = $page->controller;
+ }
+ else {
+ $controller = '__WCF_CMS__' . $page->pageID;
+ $controller = [$controller, $controller, CmsPage::class];
+ }
+ }
+ }
+
+ if ($controller === null) {
+ $controller = WCF::getApplicationObject($application)->getPrimaryController();
+ }
}
if (is_string($controller)) {
else if (!empty($data['redirect'])) {
// force a redirect
HeaderUtil::redirect($data['redirect'], true, false);
+ exit;
}
else if (!empty($data['application']) && $data['application'] !== $application) {
HeaderUtil::redirect(
<item name="wcf.acp.application.domainPath.description"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Gib{else}Geben Sie{/if} den Pfad an, über den diese App erreichbar ist. Wenn die App zum Beispiel unter „http://www.example.com/community/forum/“ erreichbar ist, müsste hier die korrekte Angabe „/community/forum/“ lauten.]]></item>
<item name="wcf.acp.application.edit"><![CDATA[App bearbeiten]]></item>
<item name="wcf.acp.application.edit.title"><![CDATA[App bearbeiten: „<a href="{link controller='Package' id=$application->packageID}{/link}">{$application->getPackage()->getName()}</a>“]]></item>
+ <item name="wcf.acp.application.landingPage"><![CDATA[Einstiegsseite]]></item>
+ <item name="wcf.acp.application.landingPage.description"><![CDATA[Optional: {if LANGUAGE_USE_INFORMAL_VARIANT}Gib{else}Geben Sie{/if} die Seite an, die angezeigt wird, wenn diese App direkt aufgerufen wird.]]></item>
<item name="wcf.acp.application.list"><![CDATA[Installierte Apps]]></item>
</category>
<item name="wcf.acp.application.domainPath.description"><![CDATA[If you are accessing this application through “http://www.example.com/community/forum/”, please enter “/community/forum/”.]]></item>
<item name="wcf.acp.application.edit"><![CDATA[Edit Application]]></item>
<item name="wcf.acp.application.edit.title"><![CDATA[Edit Application: “<a href="{link controller='Package' id=$application->packageID}{/link}">{$application->getPackage()->getName()}</a>”]]></item>
+ <item name="wcf.acp.application.landingPage"><![CDATA[Entry Page]]></item>
+ <item name="wcf.acp.application.landingPage.description"><![CDATA[Optional: This page will be shown when a user is navigating to this app.]]></item>
<item name="wcf.acp.application.list"><![CDATA[Installed Applications]]></item>
</category>
domainName VARCHAR(255) NOT NULL,
domainPath VARCHAR(255) NOT NULL DEFAULT '/',
cookieDomain VARCHAR(255) NOT NULL,
- isTainted TINYINT(1) NOT NULL DEFAULT 0
+ isTainted TINYINT(1) NOT NULL DEFAULT 0,
+ landingPageID INT(10) NULL
);
DROP TABLE IF EXISTS wcf1_article;
ALTER TABLE wcf1_ad ADD FOREIGN KEY (objectTypeID) REFERENCES wcf1_object_type (objectTypeID) ON DELETE CASCADE;
ALTER TABLE wcf1_application ADD FOREIGN KEY (packageID) REFERENCES wcf1_package (packageID) ON DELETE CASCADE;
+ALTER TABLE wcf1_application ADD FOREIGN KEY (landingPageID) REFERENCES wcf1_page (pageID) ON DELETE SET NULL;
ALTER TABLE wcf1_article ADD FOREIGN KEY (userID) REFERENCES wcf1_user (userID) ON DELETE SET NULL;
ALTER TABLE wcf1_article ADD FOREIGN KEY (categoryID) REFERENCES wcf1_category (categoryID) ON DELETE SET NULL;