661dd51d38ee925ee2d4eb4b2d01193088d4bbc4
[GitHub/WoltLab/WCF.git] / wcfsetup / install / files / lib / data / option / OptionAction.class.php
1 <?php
2
3 namespace wcf\data\option;
4
5 use wcf\data\AbstractDatabaseObjectAction;
6 use wcf\system\application\ApplicationHandler;
7 use wcf\system\email\transport\SmtpEmailTransport;
8 use wcf\system\exception\UserInputException;
9 use wcf\system\WCF;
10 use wcf\util\FileUtil;
11
12 /**
13 * Executes option-related actions.
14 *
15 * @author Alexander Ebert
16 * @copyright 2001-2019 WoltLab GmbH
17 * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
18 * @package WoltLabSuite\Core\Data\Option
19 *
20 * @method Option create()
21 * @method OptionEditor[] getObjects()
22 * @method OptionEditor getSingleObject()
23 */
24 class OptionAction extends AbstractDatabaseObjectAction
25 {
26 /**
27 * @inheritDoc
28 */
29 protected $className = OptionEditor::class;
30
31 /**
32 * @inheritDoc
33 */
34 protected $permissionsCreate = ['admin.configuration.canEditOption'];
35
36 /**
37 * @inheritDoc
38 */
39 protected $permissionsDelete = ['admin.configuration.canEditOption'];
40
41 /**
42 * @inheritDoc
43 */
44 protected $permissionsUpdate = ['admin.configuration.canEditOption'];
45
46 /**
47 * @inheritDoc
48 */
49 protected $requireACP = [
50 'create',
51 'delete',
52 'emailSmtpTest',
53 'import',
54 'update',
55 'updateAll',
56 'generateRewriteRules',
57 ];
58
59 /**
60 * Validates permissions and parameters.
61 */
62 public function validateImport()
63 {
64 parent::validateCreate();
65 }
66
67 /**
68 * Validates permissions and parameters.
69 */
70 public function validateUpdateAll()
71 {
72 parent::validateCreate();
73 }
74
75 /**
76 * Imports options.
77 */
78 public function import()
79 {
80 // create data
81 \call_user_func([$this->className, 'import'], $this->parameters['data']);
82 }
83
84 /**
85 * Updates the value of all given options.
86 */
87 public function updateAll()
88 {
89 // create data
90 \call_user_func([$this->className, 'updateAll'], $this->parameters['data']);
91 }
92
93 /**
94 * Validates the basic SMTP connection parameters.
95 *
96 * @throws UserInputException
97 */
98 public function validateEmailSmtpTest()
99 {
100 WCF::getSession()->checkPermissions($this->permissionsUpdate);
101
102 $this->readString('host');
103 $this->readInteger('port');
104 $this->readString('startTls');
105
106 $this->readString('user', true);
107 $this->readString('password', true);
108 if (!empty($this->parameters['user']) && empty($this->parameters['password'])) {
109 throw new UserInputException('password');
110 } elseif (empty($this->parameters['user']) && !empty($this->parameters['password'])) {
111 throw new UserInputException('user');
112 }
113 }
114
115 /**
116 * Runs a simple test of the SMTP connection.
117 *
118 * @return string[]
119 */
120 public function emailSmtpTest()
121 {
122 $smtp = new SmtpEmailTransport(
123 $this->parameters['host'],
124 $this->parameters['port'],
125 $this->parameters['user'],
126 $this->parameters['password'],
127 $this->parameters['startTls']
128 );
129
130 return ['validationResult' => $smtp->testConnection()];
131 }
132
133 public function validateGenerateRewriteRules()
134 {
135 WCF::getSession()->checkPermissions(['admin.configuration.canEditOption']);
136 }
137
138 /**
139 * Returns a list of code-bbcode-containers containing the necessary
140 * rewrite rules
141 *
142 * @return string
143 */
144 public function generateRewriteRules()
145 {
146 return WCF::getTPL()->fetch('__optionRewriteRulesOutput', 'wcf', [
147 'rewriteRules' => $this->fetchRewriteRules(),
148 ]);
149 }
150
151 /**
152 * Returns an array with rewrite rules per necessary directory/file
153 * Applications in sub-directories of another application will be mapped to the top one
154 *
155 * @return string[][]
156 */
157 protected function fetchRewriteRules()
158 {
159 $dirs = [];
160 $rules = [
161 'apache' => [],
162 ];
163 foreach (ApplicationHandler::getInstance()->getApplications() as $app) {
164 $test = $app->getPackage()->getAbsolutePackageDir();
165 $insert = true;
166
167 foreach ($dirs as $dir => $apps) {
168 if (\strpos($dir, $test) !== false) {
169 unset($dirs[$dir]);
170 } elseif (\strpos($test, $dir) !== false) {
171 $insert = false;
172 break;
173 }
174 }
175
176 if ($insert) {
177 $dirs[$test] = [];
178 }
179 }
180
181 foreach (ApplicationHandler::getInstance()->getApplications() as $application) {
182 foreach ($dirs as $dir => $value) {
183 if (\strpos($application->getPackage()->getAbsolutePackageDir(), $dir) !== false) {
184 $dirs[$dir][$application->domainPath] = $application->getPackage()->getAbsolutePackageDir();
185 }
186 }
187 }
188
189 foreach ($dirs as $dir => $domainPaths) {
190 \krsort($domainPaths);
191
192 foreach ($domainPaths as $domainPath => $value) {
193 $htaccess = "{$dir}.htaccess";
194 $path = FileUtil::addTrailingSlash(\substr($value, \strlen($dir)));
195 if ($path == '/') {
196 $path = '';
197 }
198 $content = <<<SNIPPET
199 RewriteCond %{SCRIPT_FILENAME} !-d
200 RewriteCond %{SCRIPT_FILENAME} !-f
201 RewriteRule ^{$path}(.*)$ {$path}index.php?$1 [L,QSA]
202
203
204 SNIPPET;
205 if (empty($rules['apache'][$htaccess])) {
206 $rules['apache'][$htaccess] = "RewriteEngine On\n\n{$content}";
207 } else {
208 $rules['apache'][$htaccess] .= $content;
209 }
210 }
211 }
212
213 return $rules;
214 }
215 }