]> git.agnieray.net Git - galette.git/blob - galette/lib/Galette/Controllers/PluginsController.php
Switch to PSR12, phpcbf fix
[galette.git] / galette / lib / Galette / Controllers / PluginsController.php
1 <?php
2
3 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
4
5 /**
6 * Galette plugins controller
7 *
8 * PHP version 5
9 *
10 * Copyright © 2020 The Galette Team
11 *
12 * This file is part of Galette (http://galette.tuxfamily.org).
13 *
14 * Galette is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation, either version 3 of the License, or
17 * (at your option) any later version.
18 *
19 * Galette is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with Galette. If not, see <http://www.gnu.org/licenses/>.
26 *
27 * @category Controllers
28 * @package Galette
29 *
30 * @author Johan Cwiklinski <johan@x-tnd.be>
31 * @copyright 2020 The Galette Team
32 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
33 * @version SVN: $Id$
34 * @link http://galette.tuxfamily.org
35 * @since Available since 0.9.4dev - 2020-05-02
36 */
37
38 namespace Galette\Controllers;
39
40 use Slim\Http\Request;
41 use Slim\Http\Response;
42 use Galette\Core\Install;
43 use Galette\Core\PluginInstall;
44 use Laminas\Db\Adapter\Adapter;
45 use Analog\Analog;
46
47 /**
48 * Galette plugins controller
49 *
50 * @category Controllers
51 * @name PluginsController
52 * @package Galette
53 * @author Johan Cwiklinski <johan@x-tnd.be>
54 * @copyright 2020 The Galette Team
55 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
56 * @link http://galette.tuxfamily.org
57 * @since Available since 0.9.4dev - 2020-05-02
58 */
59
60 class PluginsController extends AbstractController
61 {
62 /**
63 * Plugins page
64 *
65 * @param Request $request PSR Request
66 * @param Response $response PSR Response
67 *
68 * @return Response
69 */
70 public function showPlugins(Request $request, Response $response): Response
71 {
72 $plugins = $this->plugins;
73
74 $plugins_list = $plugins->getModules();
75 $disabled_plugins = $plugins->getDisabledModules();
76
77 // display page
78 $this->view->render(
79 $response,
80 'plugins.tpl',
81 array(
82 'page_title' => _T("Plugins"),
83 'plugins_list' => $plugins_list,
84 'plugins_disabled_list' => $disabled_plugins
85 )
86 );
87 return $response;
88 }
89
90 /**
91 * Plugins activation/desactivaion
92 *
93 * @param Request $request PSR Request
94 * @param Response $response PSR Response
95 * @param array $args Request arguments
96 *
97 * @return Response
98 */
99 public function togglePlugin(Request $request, Response $response, array $args = []): Response
100 {
101 if (GALETTE_MODE !== 'DEMO') {
102 $plugins = $this->plugins;
103 $action = $args['action'];
104 $reload_plugins = false;
105 if ($action == 'activate') {
106 try {
107 $plugins->activateModule($args['module_id']);
108 $this->flash->addMessage(
109 'success_detected',
110 str_replace(
111 '%name',
112 $args['module_id'],
113 _T("Plugin %name has been enabled")
114 )
115 );
116 $reload_plugins = true;
117 } catch (\Exception $e) {
118 $this->flash->addMessage(
119 'error_detected',
120 $e->getMessage()
121 );
122 }
123 } elseif ($args['action'] == 'deactivate') {
124 try {
125 $plugins->deactivateModule($args['module_id']);
126 $this->flash->addMessage(
127 'success_detected',
128 str_replace(
129 '%name',
130 $args['module_id'],
131 _T("Plugin %name has been disabled")
132 )
133 );
134 $reload_plugins = true;
135 } catch (\Exception $e) {
136 $this->flash->addMessage(
137 'error_detected',
138 $e->getMessage()
139 );
140 }
141 }
142
143 //If some plugins have been (de)activated, we have to reload
144 if ($reload_plugins === true) {
145 $plugins->loadModules($this->preferences, GALETTE_PLUGINS_PATH, $this->i18n->getLongID());
146 }
147 }
148
149 return $response
150 ->withStatus(301)
151 ->withHeader('Location', $this->router->pathFor('plugins'));
152 }
153
154 /**
155 * Plugins database activation
156 *
157 * @param Request $request PSR Request
158 * @param Response $response PSR Response
159 * @param array $args Request arguments
160 *
161 * @return Response
162 */
163 public function initPluginDb(Request $request, Response $response, array $args = []): Response
164 {
165 if (GALETTE_MODE === 'DEMO') {
166 Analog::log(
167 'Trying to access plugin database initialization in DEMO mode.',
168 Analog::WARNING
169 );
170 return $response->withStatus(403);
171 }
172
173 $params = [];
174 $warning_detected = [];
175 $error_detected = [];
176
177 $plugid = $args['id'];
178 $plugin = $this->plugins->getModules($plugid);
179
180 if ($plugin === null) {
181 Analog::log(
182 'Unable to load plugin `' . $plugid . '`!',
183 Analog::URGENT
184 );
185 $notFound = $this->notFoundHandler;
186 return $notFound($request, $response);
187 }
188
189 $install = null;
190 $mdplugin = md5($plugin['root']);
191 if (
192 isset($this->session->$mdplugin)
193 && !isset($_GET['raz'])
194 ) {
195 $install = $this->session->$mdplugin;
196 } else {
197 $install = new PluginInstall();
198 }
199
200 $post = $request->getParsedBody();
201
202 if (isset($post['stepback_btn'])) {
203 $install->atPreviousStep();
204 } elseif (isset($post['install_prefs_ok'])) {
205 $install->atEndStep();
206 } elseif (isset($_POST['previous_version'])) {
207 $install->setInstalledVersion($_POST['previous_version']);
208 $install->atDbUpgradeStep();
209 } elseif (isset($post['install_dbperms_ok'])) {
210 if ($install->isInstall()) {
211 $install->atDbInstallStep();
212 } elseif ($install->isUpgrade()) {
213 $install->atVersionSelection();
214 }
215 } elseif (isset($post['install_type'])) {
216 $install->setMode($post['install_type']);
217 $install->atDbStep();
218 }
219
220 $step = 1;
221 $istep = 1;
222
223 if (isset($post['install_type'])) {
224 $params['install_type'] = $post['install_type'];
225 $istep = 2;
226 }
227
228 if (isset($post['install_dbperms_ok'])) {
229 if ($post['install_type'] === PluginInstall::INSTALL) {
230 $istep = 4;
231 } else {
232 $istep = 3;
233 }
234 }
235
236 if (isset($post['previous_version'])) {
237 $istep = 4;
238 }
239
240 if (isset($post['install_dbwrite_ok'])) {
241 $istep = 5;
242 }
243
244 if (isset($post['install_type'])) {
245 if ($post['install_type'] == PluginInstall::INSTALL) {
246 $step = 'i' . $istep;
247 } elseif ($istep > 1 && $post['install_type'] == PluginInstall::UPDATE) {
248 $step = 'u' . $istep;
249 }
250 }
251
252 switch ($step) {
253 case '1':
254 //let's look for updates scripts
255 $update_scripts = $install::getUpdateScripts($plugin['root'], TYPE_DB);
256 if (count($update_scripts) > 0) {
257 $params['update_scripts'] = $update_scripts;
258 }
259 break;
260 case 'i2':
261 case 'u2':
262 if (!defined('GALETTE_THEME_DIR')) {
263 define('GALETTE_THEME_DIR', './themes/default/');
264 }
265
266 $install_plugin = true;
267 //not used here, but from include
268 $zdb = $this->zdb;
269 ob_start();
270 include_once __DIR__ . '/../../install/steps/db_checks.php';
271 $params['results'] = ob_get_contents();
272 ob_end_clean();
273 break;
274 case 'u3':
275 $update_scripts = Install::getUpdateScripts($plugin['root'], TYPE_DB);
276 $params['update_scripts'] = $update_scripts;
277 break;
278 case 'i4':
279 case 'u4':
280 $messages = [];
281
282 // begin : copyright (2002) the phpbb group (support@phpbb.com)
283 // load in the sql parser
284 include GALETTE_ROOT . 'includes/sql_parse.php';
285 if ($step == 'u4') {
286 $update_scripts = Install::getUpdateScripts(
287 $plugin['root'],
288 TYPE_DB,
289 $_POST['previous_version']
290 );
291 } else {
292 $update_scripts['current'] = TYPE_DB . '.sql';
293 }
294
295 $sql_query = '';
296 foreach ($update_scripts as $key => $val) {
297 $sql_query .= @fread(
298 @fopen($plugin['root'] . '/scripts/' . $val, 'r'),
299 @filesize($plugin['root'] . '/scripts/' . $val)
300 );
301 $sql_query .= "\n";
302 }
303
304 $sql_query = preg_replace('/galette_/', PREFIX_DB, $sql_query);
305 $sql_query = remove_remarks($sql_query);
306
307 $sql_query = split_sql_file($sql_query, ';');
308
309 for ($i = 0; $i < sizeof($sql_query); $i++) {
310 $query = trim($sql_query[$i]);
311 if ($query != '' && $query[0] != '-') {
312 //some output infos
313 @list($w1, $w2, $w3, $extra) = array_pad(explode(' ', $query, 4), 4, '');
314 if ($extra != '') {
315 $extra = '...';
316 }
317 try {
318 $this->zdb->db->query(
319 $query,
320 Adapter::QUERY_MODE_EXECUTE
321 );
322 $messages['success'][] = $w1 . ' ' . $w2 . ' ' . $w3 .
323 ' ' . $extra;
324 } catch (Exception $e) {
325 Analog::log(
326 'Error executing query | ' . $e->getMessage() .
327 ' | Query was: ' . $query,
328 Analog::WARNING
329 );
330 if (
331 (strcasecmp(trim($w1), 'drop') != 0)
332 && (strcasecmp(trim($w1), 'rename') != 0)
333 ) {
334 $error_detected[] = $w1 . ' ' . $w2 . ' ' . $w3 . ' ' . $extra;
335 $error_detected[] = $e->getMessage() . '<br/>(' . $query . ')';
336 } else {
337 //if error are on drop, DROP, rename or RENAME we can continue
338 $warning_detected[] = $w1 . ' ' . $w2 . ' ' . $w3 . ' ' . $extra;
339 $warning_detected[] = $e->getMessage() . '<br/>(' . $query . ')';
340 }
341 }
342 }
343 }
344 break;
345 }
346
347 $this->session->$mdplugin = $install;
348
349 $params += [
350 'page_title' => $install->getStepTitle(),
351 'step' => $step,
352 'istep' => $istep,
353 'plugid' => $plugid,
354 'plugin' => $plugin,
355 'mode' => ($request->isXhr() ? 'ajax' : ''),
356 'error_detected' => $error_detected
357 ];
358
359 // display page
360 $this->view->render(
361 $response,
362 'plugin_initdb.tpl',
363 $params
364 );
365 return $response;
366 }
367 }