Set new landing page reset style cache, too
[GitHub/WoltLab/WCF.git] / wcfsetup / install / files / lib / acp / form / ApplicationManagementForm.class.php
1 <?php
2
3 namespace wcf\acp\form;
4
5 use wcf\data\application\ViewableApplicationList;
6 use wcf\data\page\Page;
7 use wcf\data\page\PageList;
8 use wcf\data\page\PageNodeTree;
9 use wcf\form\AbstractForm;
10 use wcf\system\application\ApplicationHandler;
11 use wcf\system\cache\builder\ApplicationCacheBuilder;
12 use wcf\system\cache\builder\PageCacheBuilder;
13 use wcf\system\cache\builder\RoutingCacheBuilder;
14 use wcf\system\exception\UserInputException;
15 use wcf\system\Regex;
16 use wcf\system\style\StyleHandler;
17 use wcf\system\WCF;
18 use wcf\util\ArrayUtil;
19 use wcf\util\FileUtil;
20 use wcf\util\StringUtil;
21
22 /**
23 * Shows the application management form.
24 *
25 * @author Alexander Ebert
26 * @copyright 2001-2021 WoltLab GmbH
27 * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
28 */
29 final class ApplicationManagementForm extends AbstractForm
30 {
31 /**
32 * @inheritDoc
33 */
34 public $activeMenuItem = 'wcf.acp.menu.link.application.management';
35
36 /**
37 * list of applications
38 * @var ViewableApplicationList
39 */
40 public $applicationList;
41
42 /**
43 * @var string
44 */
45 public $cookieDomain = '';
46
47 /**
48 * @var string
49 */
50 public $domainName = '';
51
52 /**
53 * @var int[]
54 */
55 public $landingPageID = [];
56
57 /**
58 * @inheritDoc
59 */
60 public $neededPermissions = ['admin.configuration.canManageApplication'];
61
62 /**
63 * nested list of page nodes
64 * @var \RecursiveIteratorIterator
65 */
66 public $pageNodeList;
67
68 /**
69 * @inheritDoc
70 */
71 public function readParameters()
72 {
73 parent::readParameters();
74
75 $this->pageNodeList = (new PageNodeTree())->getNodeList();
76 }
77
78 /**
79 * @inheritDoc
80 */
81 public function readFormParameters()
82 {
83 parent::readFormParameters();
84
85 if (!ENABLE_ENTERPRISE_MODE || WCF::getUser()->hasOwnerAccess()) {
86 if (isset($_POST['cookieDomain'])) {
87 $this->cookieDomain = StringUtil::trim($_POST['cookieDomain']);
88 }
89 if (isset($_POST['domainName'])) {
90 $this->domainName = StringUtil::trim($_POST['domainName']);
91 }
92 }
93
94 if (isset($_POST['landingPageID']) && \is_array($_POST['landingPageID'])) {
95 $this->landingPageID = ArrayUtil::toIntegerArray($_POST['landingPageID']);
96 }
97 }
98
99 public function validate()
100 {
101 parent::validate();
102
103 if (!ENABLE_ENTERPRISE_MODE || WCF::getUser()->hasOwnerAccess()) {
104 if (empty($this->domainName)) {
105 throw new UserInputException('domainName');
106 }
107
108 $regex = new Regex('^https?\://');
109 $this->domainName = FileUtil::removeTrailingSlash($regex->replace($this->domainName, ''));
110 $this->cookieDomain = FileUtil::removeTrailingSlash($regex->replace($this->cookieDomain, ''));
111
112 // domain may not contain path components
113 $regex = new Regex('[/#\?&]');
114 if ($regex->match($this->domainName)) {
115 throw new UserInputException('domainName', 'containsPath');
116 } elseif ($regex->match($this->cookieDomain)) {
117 throw new UserInputException('cookieDomain', 'containsPath');
118 }
119
120 // strip port from cookie domain
121 $regex = new Regex(':[0-9]+$');
122 $this->cookieDomain = $regex->replace($this->cookieDomain, '');
123
124 // check if cookie domain shares the same domain (may exclude subdomains)
125 if (!\str_ends_with($regex->replace($this->domainName, ''), $this->cookieDomain)) {
126 throw new UserInputException('cookieDomain', 'invalid');
127 }
128 }
129
130 foreach ($this->landingPageID as $landingPageID) {
131 if (!$landingPageID) {
132 continue;
133 }
134
135 $page = new Page($landingPageID);
136 if (!$page->pageID) {
137 throw new UserInputException('landingPageID');
138 } elseif ($page->requireObjectID || $page->excludeFromLandingPage || $page->isDisabled) {
139 throw new UserInputException('landingPageID', 'invalid');
140 }
141 }
142 }
143
144 /**
145 * @inheritDoc
146 */
147 public function readData()
148 {
149 parent::readData();
150
151 $this->applicationList = new ViewableApplicationList();
152 $this->applicationList->readObjects();
153
154 $core = ApplicationHandler::getInstance()->getApplicationByID(1);
155 $this->domainName = $core->domainName;
156 $this->cookieDomain = $core->cookieDomain;
157 }
158
159 public function save()
160 {
161 parent::save();
162
163 if (!ENABLE_ENTERPRISE_MODE || WCF::getUser()->hasOwnerAccess()) {
164 $sql = "UPDATE wcf" . WCF_N . "_application
165 SET domainName = ?,
166 cookieDomain = ?";
167 $statement = WCF::getDB()->prepareStatement($sql);
168 $statement->execute([
169 $this->domainName,
170 $this->cookieDomain,
171 ]);
172 }
173
174 $sql = "UPDATE wcf" . WCF_N . "_application
175 SET landingPageID = ?
176 WHERE packageID = ?";
177 $statement = WCF::getDB()->prepareStatement($sql);
178 foreach ($this->landingPageID as $packageID => $landingPageID) {
179 $statement->execute([
180 $landingPageID ?: null,
181 $packageID,
182 ]);
183 }
184
185 $this->saved();
186
187 ApplicationHandler::rebuild();
188
189 // Reset caches to reflect the new landing pages.
190 ApplicationCacheBuilder::getInstance()->reset();
191 PageCacheBuilder::getInstance()->reset();
192 RoutingCacheBuilder::getInstance()->reset();
193 StyleHandler::resetStylesheets();
194
195 // Reload the applications to update the selected landing page id.
196 $this->applicationList = new ViewableApplicationList();
197 $this->applicationList->readObjects();
198
199 // show success message
200 WCF::getTPL()->assign('success', true);
201 }
202
203 /**
204 * @inheritDoc
205 */
206 public function assignVariables()
207 {
208 parent::assignVariables();
209
210 $pageList = new PageList();
211 $pageList->readObjects();
212
213 WCF::getTPL()->assign([
214 'applicationList' => $this->applicationList,
215 'cookieDomain' => $this->cookieDomain,
216 'domainName' => $this->domainName,
217 'pageNodeList' => $this->pageNodeList,
218 'pageList' => $pageList->getObjects(),
219 ]);
220 }
221 }