PageRenderTime 56ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/web/system/ExtensionsModule/Controller/AdminController.php

https://github.com/antoniom/core
PHP | 1383 lines | 968 code | 178 blank | 237 comment | 179 complexity | cc2777e2e7550eb6e3eb84e7c49e345d MD5 | raw file
Possible License(s): GPL-3.0, LGPL-3.0, MIT

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. /**
  3. * Copyright Zikula Foundation 2009 - Zikula Application Framework
  4. *
  5. * This work is contributed to the Zikula Foundation under one or more
  6. * Contributor Agreements and licensed to You under the following license:
  7. *
  8. * @license GNU/LGPLv3 (or at your option, any later version).
  9. * @package Zikula
  10. *
  11. * Please see the NOTICE file distributed with this source code for further
  12. * information regarding copyright and licensing.
  13. */
  14. namespace ExtensionsModule\Controller;
  15. use SecurityUtil, Zikula_View, ModUtil, LogUtil, ZLanguage, System, PluginUtil;
  16. use ExtensionsModule\Util as ExtensionsUtil;
  17. /**
  18. * Extensions_Controller_Admin class.
  19. */
  20. class AdminController extends \Zikula\Framework\Controller\AbstractController
  21. {
  22. /**
  23. * Post initialise.
  24. *
  25. * @return void
  26. */
  27. protected function postInitialize()
  28. {
  29. // In this controller we do not want caching.
  30. $this->view->setCaching(Zikula_View::CACHE_DISABLED);
  31. }
  32. /**
  33. * Extensions Module main admin function
  34. *
  35. * @return string HTML output string
  36. */
  37. public function indexAction()
  38. {
  39. // Security check will be done in view()
  40. return $this->redirect(ModUtil::url('Extensions', 'admin', 'view'));
  41. }
  42. /**
  43. * Extensions_admin_modify - modify a module.
  44. *
  45. * @return string HTML output string.
  46. */
  47. public function modifyAction()
  48. {
  49. $id = (int) $this->request->query->get('id', null);
  50. if (!is_numeric($id)) {
  51. return LogUtil::registerArgsError(ModUtil::url('Extensions', 'admin', 'view'));
  52. }
  53. $obj = ModUtil::getInfo($id);
  54. if (!isset($id) || $obj == false) {
  55. return LogUtil::registerError($this->__('Error! No such module ID exists.'),
  56. 404,
  57. ModUtil::url('Extensions', 'admin', 'modify', array('id' => $id)));
  58. }
  59. if (!SecurityUtil::checkPermission('Extensions::', "$obj[name]::$id", ACCESS_ADMIN)) {
  60. throw new \Zikula\Framework\Exception\ForbiddenException();
  61. }
  62. $restore = (bool)$this->request->query->get('restore', false);
  63. if ($restore) {
  64. // load the version array
  65. $baseDir = ($obj['type'] == ModUtil::TYPE_SYSTEM) ? 'system' : 'modules';
  66. // load gettext domain for 3rd party modules
  67. if ($baseDir == 'modules' && is_dir("modules/$obj[directory]/locale")) {
  68. // This is required here since including pnversion automatically executes the pnversion code
  69. // this results in $this->__() caching the result before the domain is bounded. Will not occur in zOO
  70. // since loading is self contained in each zOO application.
  71. ZLanguage::bindModuleDomain($obj['directory']);
  72. }
  73. $modversion = ExtensionsUtil::getVersionMeta($obj['directory'], $baseDir);
  74. // load defaults
  75. $name = (isset($modversion['name']) ? $modversion['name'] : '');
  76. $displayname = (isset($modversion['displayname']) ? $modversion['displayname'] : $name);
  77. $url = (isset($modversion['url']) ? $modversion['url'] : $displayname);
  78. $description = (isset($modversion['description']) ? $modversion['description'] : '');
  79. $obj = array(
  80. 'id' => $id,
  81. 'displayname' => $displayname,
  82. 'url' => $url,
  83. 'description' => $description
  84. );
  85. }
  86. $this->view->assign($obj);
  87. // Return the output that has been generated by this function
  88. return $this->response($this->view->fetch('Admin/modify.tpl'));
  89. }
  90. /**
  91. * Extensions_admin_update - update a module
  92. * @return string HTML output string
  93. * @param int 'id' module id
  94. * @param string 'newdisplayname' new display name of the module
  95. * @param string 'newdescription' new description of the module
  96. */
  97. public function updateAction()
  98. {
  99. $this->checkCsrfToken();
  100. // Get parameters
  101. $id = (int) $this->request->request->get('id', null);
  102. $newdisplayname = $this->request->request->get('newdisplayname', null);
  103. $newdescription = $this->request->request->get('newdescription', null);
  104. $newurl = $this->request->request->get('newurl', null);
  105. // Pass to API
  106. if (ModUtil::apiFunc('ExtensionsModule', 'admin', 'update', array(
  107. 'id' => $id,
  108. 'displayname' => $newdisplayname,
  109. 'description' => $newdescription,
  110. 'url' => $newurl))) {
  111. // Success
  112. LogUtil::registerStatus($this->__('Done! Saved module information.'));
  113. } else {
  114. return $this->redirect(ModUtil::url('Extensions', 'admin', 'modify', array('id' => $id)));
  115. }
  116. return $this->redirect(ModUtil::url('Extensions', 'admin', 'view'));
  117. }
  118. /**
  119. * Extensions_admin_view - list modules and current settings
  120. * @return string HTML output string
  121. */
  122. public function viewAction()
  123. {
  124. // Security check
  125. if (!SecurityUtil::checkPermission('Extensions::', '::', ACCESS_ADMIN)) {
  126. throw new \Zikula\Framework\Exception\ForbiddenException();
  127. }
  128. $session = $this->request->getSession();
  129. // Get parameters from whatever input we need.
  130. $modinfo = $this->getModInfo();
  131. $startnum = (int) $this->request->query->get('startnum', null);
  132. $letter = $this->request->query->get('letter', null);
  133. $state = $this->request->query->get('state', (!strstr(System::serverGetVar('HTTP_REFERER'), 'module='.$modinfo['url'])) ? null : $session->get('state', null));
  134. $sort = $this->request->query->get('sort', (!strstr(System::serverGetVar('HTTP_REFERER'), 'module='.$modinfo['url'])) ? null : $session->get('sort', null));
  135. $sortdir = $this->request->query->get('sortdir', (!strstr(System::serverGetVar('HTTP_REFERER'), 'module='.$modinfo['url'])) ? null : $session->get('sortdir', null));
  136. // parameter for used sort order
  137. if ($sort != 'name' && $sort != 'displayname') $sort = 'name';
  138. if ($sortdir != 'ASC' && $sortdir != 'DESC') $sortdir = 'ASC';
  139. // save the current values
  140. $session->set('state', $state);
  141. $session->set('sort', $sort);
  142. $session->set('sortdir', $sortdir);
  143. // do some clean up
  144. $session->remove('interactive_init');
  145. $session->remove('interactive_remove');
  146. $session->remove('interactive_upgrade');
  147. if ($this->container['multisites.enabled'] != 1 || ($this->container['multisites.mainsiteurl'] == $this->request->query->get('sitedns', null) && $this->container['multisites.based_on_domains'] == 0) || ($this->container['multisites.mainsiteurl'] == $_SERVER['HTTP_HOST'] && $this->container['multisites.based_on_domains'] == 1)) {
  148. // always regenerate modules list
  149. $filemodules = ModUtil::apiFunc('ExtensionsModule', 'admin', 'getfilemodules');
  150. $inconsistencies = ModUtil::apiFunc('ExtensionsModule', 'admin', 'checkconsistency', array('filemodules' => $filemodules));
  151. if (!(empty($inconsistencies['errors_modulenames']) && empty($inconsistencies['errors_displaynames']))) {
  152. $this->view->assign('errors_modulenames', $inconsistencies['errors_modulenames'])
  153. ->assign('errors_displaynames', $inconsistencies['errors_displaynames']);
  154. return $this->response($this->view->fetch('Admin/regenerate_errors.tpl'));
  155. }
  156. // No inconsistencies, so we can regenerate modules
  157. $defaults = (int) $this->request->query->get('defaults', false);
  158. if (!ModUtil::apiFunc('ExtensionsModule', 'admin', 'regenerate', array('filemodules' => $filemodules, 'defaults' => $defaults))) {
  159. LogUtil::registerError($this->__('Errors were detected regenerating the modules list from file system.'));
  160. }
  161. }
  162. // assign the state filter
  163. $this->view->assign('state', $state);
  164. // Get list of modules
  165. $mods = ModUtil::apiFunc('ExtensionsModule', 'admin', 'listmodules',
  166. array('startnum' => $startnum,
  167. 'letter' => $letter,
  168. 'state' => $state,
  169. 'numitems' => $this->getVar('itemsperpage'),
  170. 'sortdir' => $sortdir,
  171. 'sort' => $sort));
  172. // generate an auth key to use in urls
  173. $csrftoken = SecurityUtil::generateCsrfToken($this->container, true);
  174. $moduleinfo = array();
  175. if (!empty($mods)) {
  176. foreach ($mods as $mod) {
  177. $mod = $mod->toArray();
  178. // Add applicable actions
  179. $actions = array();
  180. if (SecurityUtil::checkPermission('Extensions::', "$mod[name]::$mod[id]", ACCESS_ADMIN)) {
  181. switch ($mod['state']) {
  182. case ModUtil::STATE_ACTIVE:
  183. if (!ModUtil::apiFunc('ExtensionsModule', 'admin', 'iscoremodule', array('modulename' => $mod['name']))) {
  184. $actions[] = array(
  185. 'url' => ModUtil::url('Extensions', 'admin', 'deactivate', array(
  186. 'id' => $mod['id'],
  187. 'startnum' => $startnum,
  188. 'csrftoken' => $csrftoken,
  189. 'letter' => $letter,
  190. 'state' => $state)),
  191. 'image' => 'folder_red.png',
  192. 'title' => $this->__f('Deactivate \'%s\' module', $mod['name']));
  193. }
  194. if (PluginUtil::hasModulePlugins($mod['name'])) {
  195. $actions[] = array(
  196. 'url' => ModUtil::url('Extensions', 'admin', 'viewPlugins', array(
  197. 'bymodule' => $mod['name'])),
  198. 'image' => 'blockdevice.png',
  199. 'title' => $this->__f('Plugins for \'%s\'', $mod['name']));
  200. }
  201. break;
  202. case ModUtil::STATE_INACTIVE:
  203. $actions[] = array(
  204. 'url' => ModUtil::url('Extensions', 'admin', 'activate', array(
  205. 'id' => $mod['id'],
  206. 'startnum' => $startnum,
  207. 'csrftoken' => $csrftoken,
  208. 'letter' => $letter,
  209. 'state' => $state)),
  210. 'image' => 'folder_green.png',
  211. 'title' => $this->__f('Activate \'%s\'', $mod['name']));
  212. $actions[] = array(
  213. 'url' => ModUtil::url('Extensions', 'admin', 'remove', array(
  214. 'id' => $mod['id'],
  215. 'startnum' => $startnum,
  216. 'letter' => $letter,
  217. 'state' => $state)),
  218. 'image' => '14_layer_deletelayer.png',
  219. 'title' => $this->__f('Uninstall \'%s\' module', $mod['name']));
  220. break;
  221. case ModUtil::STATE_MISSING:
  222. $actions[] = array(
  223. 'url' => ModUtil::url('Extensions', 'admin', 'remove', array(
  224. 'id' => $mod['id'],
  225. 'startnum' => $startnum,
  226. 'letter' => $letter,
  227. 'state' => $state)),
  228. 'image' => '14_layer_deletelayer.png',
  229. 'title' => $this->__f('Remove \'%s\' module', $mod['name']));
  230. break;
  231. case ModUtil::STATE_UPGRADED:
  232. $actions[] = array(
  233. 'url' => ModUtil::url('Extensions', 'admin', 'upgrade', array(
  234. 'id' => $mod['id'],
  235. 'startnum' => $startnum,
  236. 'csrftoken' => $csrftoken,
  237. 'letter' => $letter,
  238. 'state' => $state)),
  239. 'image' => 'folder_favorites.png',
  240. 'title' => $this->__f('Upgrade \'%s\'', $mod['name']));
  241. break;
  242. case ModUtil::STATE_INVALID:
  243. // nothing to do, remove manually
  244. // future wish list, allow removal if FS is writable
  245. /*
  246. $actions[] = array(
  247. 'url' => ModUtil::url('Extensions', 'admin', 'remove', array(
  248. 'id' => $mod['id'],
  249. 'startnum' => $startnum,
  250. 'authid' => $authid,
  251. 'letter' => $letter,
  252. 'state' => $state)),
  253. 'image' => '14_layer_deletelayer.png',
  254. 'title' => $this->__('Remove module')); */
  255. break;
  256. case ModUtil::STATE_NOTALLOWED:
  257. $actions[] = array(
  258. 'url' => ModUtil::url('Extensions', 'admin', 'remove', array(
  259. 'id' => $mod['id'],
  260. 'startnum' => $startnum,
  261. 'csrftoken' => $csrftoken,
  262. 'letter' => $letter,
  263. 'state' => $state)),
  264. 'image' => '14_layer_deletelayer.png',
  265. 'title' => $this->__f('Remove \'%s\' module', $mod['name']));
  266. break;
  267. case ModUtil::STATE_UNINITIALISED:
  268. default:
  269. if ($mod['state'] < 10) {
  270. $actions[] = array(
  271. 'url' => ModUtil::url('Extensions', 'admin', 'initialise', array(
  272. 'id' => $mod['id'],
  273. 'startnum' => $startnum,
  274. 'csrftoken' => $csrftoken,
  275. 'letter' => $letter,
  276. 'state' => $state)),
  277. 'image' => 'folder_new.png',
  278. 'title' => $this->__f('Install \'%s\'', $mod['name']));
  279. // if ($this->container['multisites.enabled'] != 1 || ($this->container['multisites.mainsiteurl'] == $this->request->query->get('sitedns', null) && $this->container['multisites.based_on_domains'] == 0) || ($this->container['multisites.mainsiteurl'] == $_SERVER['HTTP_HOST'] && $this->container['multisites.based_on_domains'] == 1)) {
  280. // $actions[] = array(
  281. // 'url' => ModUtil::url('Extensions', 'admin', 'remove', array(
  282. // 'id' => $mod['id'],
  283. // 'startnum' => $startnum,
  284. // 'authid' => $authid,
  285. // 'letter' => $letter,
  286. // 'state' => $state)),
  287. // 'image' => '14_layer_deletelayer.png',
  288. // 'title' => $this->__('Remove module'));
  289. // }
  290. } else {
  291. $actions[] = array(
  292. 'url' => ModUtil::url('Extensions', 'admin', 'compinfo', array(
  293. 'id' => $mod['id'],
  294. 'startnum' => $startnum,
  295. 'letter' => $letter,
  296. 'state' => $state)),
  297. 'image' => 'documentinfo.png',
  298. 'title' => $this->__f('Incompatible version: \'%s\'', $mod['name']));
  299. }
  300. break;
  301. }
  302. // RNG: can't edit an invalid module
  303. if ($mod['state'] != ModUtil::STATE_INVALID) {
  304. $actions[] = array(
  305. 'url' => ModUtil::url('Extensions', 'admin', 'modify', array(
  306. 'id' => $mod['id'])),
  307. 'image' => 'xedit.png',
  308. 'title' => $this->__f('Edit \'%s\'', $mod['name']));
  309. }
  310. }
  311. // Translate state
  312. switch ($mod['state']) {
  313. case ModUtil::STATE_INACTIVE:
  314. $status = $this->__('Inactive');
  315. $statusimage = 'yellowled.png';
  316. break;
  317. case ModUtil::STATE_ACTIVE:
  318. $status = $this->__('Active');
  319. $statusimage = 'greenled.png';
  320. break;
  321. case ModUtil::STATE_MISSING:
  322. $status = $this->__('Files missing');
  323. $statusimage = 'redled.png';
  324. break;
  325. case ModUtil::STATE_UPGRADED:
  326. $status = $this->__('New version');
  327. $statusimage = 'redled.png';
  328. break;
  329. case ModUtil::STATE_INVALID:
  330. $status = $this->__('Invalid structure');
  331. $statusimage = 'redled.png';
  332. break;
  333. case ModUtil::STATE_NOTALLOWED:
  334. $status = $this->__('Not allowed');
  335. $statusimage = 'folder_red.png';
  336. break;
  337. case ModUtil::STATE_UNINITIALISED:
  338. default:
  339. if ($mod['state'] > 10) {
  340. $status = $this->__('Incompatible');
  341. $statusimage = 'folder_red.png';
  342. } else {
  343. $status = $this->__('Not installed');
  344. $statusimage = 'redled.png';
  345. }
  346. break;
  347. }
  348. // get new version number for ModUtil::STATE_UPGRADED
  349. if ($mod['state'] == ModUtil::STATE_UPGRADED) {
  350. $mod['newversion'] = $filemodules[$mod['directory']]['version'];
  351. }
  352. $moduleinfo[] = array(
  353. 'modinfo' => $mod,
  354. 'status' => $status,
  355. 'statusimage' => $statusimage,
  356. 'options' => $actions);
  357. }
  358. }
  359. $this->view->assign('multi', $this->container['multisites.enabled'])
  360. ->assign('sort', $sort)
  361. ->assign('sortdir', $sortdir)
  362. ->assign('modules', $moduleinfo);
  363. // Assign the values for the smarty plugin to produce a pager.
  364. $this->view->assign('pager', array('numitems' => ModUtil::apiFunc('ExtensionsModule', 'admin', 'countitems', array('letter' => $letter, 'state' => $state)),
  365. 'itemsperpage' => $this->getVar('itemsperpage')));
  366. // Return the output that has been generated by this function
  367. return $this->response($this->view->fetch('Admin/view.tpl'));
  368. }
  369. /**
  370. * Extensions_admin_view - list modules and current settings
  371. *
  372. * This function is an alias to Admin/view as pnphpbb calls this
  373. * function name directly on the install
  374. *
  375. * @see Admin/view
  376. * @return string HTML output string
  377. */
  378. public function listviewAction()
  379. {
  380. return $this->redirect(ModUtil::url('Extensions', 'admin', 'view'));
  381. }
  382. /**
  383. * Initialise a module.
  384. *
  385. * @param int 'id' module id
  386. * @return bool true
  387. */
  388. public function initialiseAction()
  389. {
  390. $csrftoken = $this->request->get('csrftoken');
  391. $this->checkCsrfToken($csrftoken);
  392. // Get parameters from whatever input we need
  393. $id = (int) $this->request->get('id', 0);
  394. $objectid = (int) $this->request->get('objectid', 0);
  395. $confirmation = (bool) $this->request->get('confirmation', false);
  396. $startnum = (int) $this->request->get('startnum');
  397. $letter = $this->request->get('letter');
  398. $state = (int)$this->request->get('state');
  399. if ($objectid) {
  400. $id = $objectid;
  401. }
  402. // assign any dependencies - filtering out non-active module dependents
  403. // when getting here without a valid id we are in interactive init mode and then
  404. // the dependencies checks have been done before already
  405. $fataldependency = false;
  406. if ($id != 0) {
  407. $dependencies = ModUtil::apiFunc('ExtensionsModule', 'admin', 'getdependencies', array('modid' => $id));
  408. $modulenotfound = false;
  409. if (!$confirmation && $dependencies) {
  410. foreach ($dependencies as $key => $dependency) {
  411. $dependencies[$key] = $dependency->toArray();
  412. $dependencies[$key]['insystem'] = true;
  413. $modinfo = ModUtil::getInfoFromName($dependency['modname']);
  414. $base = ($modinfo['type'] == ModUtil::TYPE_MODULE) ? 'modules' : 'system';
  415. if (is_dir("$base/$dependency[modname]")) {
  416. $minok = 0;
  417. $maxok = 0;
  418. $modversion = ExtensionsUtil::getVersionMeta($dependency['modname'], $base);
  419. if (!empty($dependency['minversion'])) {
  420. $minok = version_compare($modversion['version'], $dependency['minversion']);
  421. }
  422. if (!empty($dependency['maxversion'])) {
  423. $maxok = version_compare($dependency['maxversion'], $modversion['version']);
  424. }
  425. if ($minok == -1 || $maxok == -1) {
  426. if ($dependency['status'] == ModUtil::DEPENDENCY_REQUIRED) {
  427. $fataldependency = true;
  428. } else {
  429. unset($dependencies[$key]);
  430. }
  431. } else {
  432. $dependencies[$key] = array_merge($dependencies[$key], $modinfo);
  433. // if this module is already installed, don't display it in the list of dependencies.
  434. if (isset($dependencies[$key]['state']) && ($dependencies[$key]['state'] > ModUtil::STATE_UNINITIALISED && $dependencies[$key]['state'] < ModUtil::STATE_NOTALLOWED)) {
  435. unset($dependencies[$key]);
  436. }
  437. }
  438. } elseif (!empty($modinfo)) {
  439. $dependencies[$key] = array_merge($dependencies[$key], $modinfo);
  440. } else {
  441. $dependencies[$key]['insystem'] = false;
  442. $modulenotfound = true;
  443. if ($dependency['status'] == ModUtil::DEPENDENCY_REQUIRED) {
  444. $fataldependency = true;
  445. }
  446. }
  447. }
  448. $this->view->assign('fataldependency', $fataldependency);
  449. // we have some dependencies so let's warn the user about these
  450. if (!empty($dependencies)) {
  451. return $this->response($this->view->assign('id', $id)
  452. ->assign('dependencies', $dependencies)
  453. ->assign('modulenotfound', $modulenotfound)
  454. ->fetch('Admin/initialise.tpl'));
  455. }
  456. } else {
  457. $dependencies = (array)$this->request->request->get('dependencies', array());
  458. }
  459. }
  460. $session = $this->request->getSession();
  461. $interactive_init = $session->get('interactive_init');
  462. $interactive_init = (empty($interactive_init)) ? false : true;
  463. if ($interactive_init == false) {
  464. $session->set('modules_id', $id);
  465. $session->set('modules_startnum', $startnum);
  466. $session->set('modules_letter', $letter);
  467. $session->set('modules_state', $state);
  468. $activate = false;
  469. } else {
  470. $id = $session->get('modules_id');
  471. $startnum = $session->get('modules_startnum');
  472. $letter = $session->get('modules_letter');
  473. $state = $session->get('modules_state');
  474. $activate = (bool) $this->request->get('activate');
  475. }
  476. if (empty($id) || !is_numeric($id)) {
  477. return LogUtil::registerError($this->__('Error! No module ID provided.'), 404, ModUtil::url('Extensions', 'admin', 'view'));
  478. }
  479. // initialise and activate any dependencies
  480. if (isset($dependencies) && is_array($dependencies)) {
  481. foreach ($dependencies as $dependency) {
  482. if (!ModUtil::apiFunc('ExtensionsModule', 'admin', 'initialise',
  483. array('id' => $dependency))) {
  484. return $this->redirect(ModUtil::url('Extensions', 'admin', 'view', array(
  485. 'startnum' => $startnum,
  486. 'letter' => $letter,
  487. 'state' => $state)));
  488. }
  489. if (!ModUtil::apiFunc('ExtensionsModule', 'admin', 'setstate',
  490. array('id' => $dependency,
  491. 'state' => ModUtil::STATE_ACTIVE))) {
  492. return $this->redirect(ModUtil::url('Extensions', 'admin', 'view', array(
  493. 'startnum' => $startnum,
  494. 'letter' => $letter,
  495. 'state' => $state)));
  496. }
  497. }
  498. }
  499. // Now we've initialised the dependencies initialise the main module
  500. $res = ModUtil::apiFunc('ExtensionsModule', 'admin', 'initialise',
  501. array('id' => $id,
  502. 'interactive_init' => $interactive_init));
  503. if (is_bool($res) && $res == true) {
  504. // Success
  505. $session->remove('modules_id');
  506. $session->remove('modules_startnum');
  507. $session->remove('modules_letter');
  508. $session->remove('modules_state');
  509. $session->remove('interactive_init');
  510. LogUtil::registerStatus($this->__('Done! Installed module.'));
  511. if ($activate == true) {
  512. if (ModUtil::apiFunc('ExtensionsModule', 'admin', 'setstate',
  513. array('id' => $id,
  514. 'state' => ModUtil::STATE_ACTIVE))) {
  515. // Success
  516. LogUtil::registerStatus($this->__('Done! Activated module.'));
  517. }
  518. }
  519. return $this->redirect(ModUtil::url('Extensions', 'admin', 'view',
  520. array('startnum' => $startnum,
  521. 'letter' => $letter,
  522. 'state' => $state)));
  523. } elseif (is_bool($res)) {
  524. return $this->redirect(ModUtil::url('Extensions', 'admin', 'view',
  525. array('startnum' => $startnum,
  526. 'letter' => $letter,
  527. 'state' => $state)));
  528. } else {
  529. return $res;
  530. }
  531. }
  532. /**
  533. * Activate a module
  534. * @param int 'id' module id
  535. * @return bool true
  536. */
  537. public function activateAction()
  538. {
  539. $csrftoken = $this->request->get('csrftoken');
  540. $this->checkCsrfToken($csrftoken);
  541. $id = (int) $this->request->query->get('id', null);
  542. $startnum = (int) $this->request->query->get('startnum', null);
  543. $letter = $this->request->query->get('letter', null);
  544. $state = $this->request->query->get('state', null);
  545. if (empty($id) || !is_numeric($id)) {
  546. return LogUtil::registerError($this->__('Error! No module ID provided.'), 404, ModUtil::url('Extensions', 'admin', 'view'));
  547. }
  548. $moduleinfo = ModUtil::getInfo($id);
  549. if ($moduleinfo['state'] == 6) {
  550. LogUtil::registerError($this->__('Error! Module not allowed.'));
  551. return $this->redirect(ModUtil::url('Extensions', 'admin', 'view', array(
  552. 'startnum' => $startnum,
  553. 'letter' => $letter,
  554. 'state' => $state)));
  555. }
  556. // Update state
  557. $setstate = ModUtil::apiFunc('ExtensionsModule', 'admin', 'setstate', array('id' => $id, 'state' => ModUtil::STATE_ACTIVE));
  558. if ($setstate) {
  559. // Success
  560. LogUtil::registerStatus($this->__('Done! Activated module.'));
  561. }
  562. return $this->redirect(ModUtil::url('Extensions', 'admin', 'view',
  563. array('startnum' => $startnum,
  564. 'letter' => $letter,
  565. 'state' => $state)));
  566. }
  567. /**
  568. * Upgrade a module
  569. * @param int 'id' module id
  570. * @return bool true
  571. */
  572. public function upgradeAction()
  573. {
  574. $csrftoken = $this->request->get('csrftoken');
  575. $this->checkCsrfToken($csrftoken);
  576. $session = $this->request->getSession();
  577. $interactive_upgrade = $session->get('interactive_upgrade');
  578. $interactive_upgrade = (empty($interactive_upgrade)) ? false : true;
  579. if ($interactive_upgrade == false) {
  580. $id = (int) $this->request->query->get('id', null);
  581. $startnum = (int) $this->request->query->get('startnum', null);
  582. $letter = $this->request->query->get('letter', null);
  583. $state = $this->request->query->get('state', null);
  584. $session->set('modules_id', $id);
  585. $session->set('modules_startnum', $startnum);
  586. $session->set('modules_letter', $letter);
  587. $session->set('modules_state', $state);
  588. $activate = false;
  589. } else {
  590. $id = $session->get('modules_id');
  591. $startnum = $session->get('modules_startnum');
  592. $letter = $session->get('modules_letter');
  593. $state = $session->get('modules_state');
  594. $activate = (bool) $this->request->request->get('activate', null);
  595. }
  596. if (empty($id) || !is_numeric($id)) {
  597. return LogUtil::registerError($this->__('Error! No module ID provided.'), 404, ModUtil::url('Extensions', 'admin', 'view'));
  598. }
  599. // Upgrade module
  600. $res = ModUtil::apiFunc('ExtensionsModule', 'admin', 'upgrade',
  601. array('id' => $id,
  602. 'interactive_upgrade' => $interactive_upgrade));
  603. if (is_bool($res) && $res == true) {
  604. // Success
  605. $session->remove('modules_id');
  606. $session->remove('modules_startnum');
  607. $session->remove('modules_letter');
  608. $session->remove('modules_state');
  609. $session->set('interactive_upgrade', false);
  610. LogUtil::registerStatus($this->__('New version'));
  611. if ($activate == true) {
  612. if (ModUtil::apiFunc('ExtensionsModule', 'admin', 'setstate',
  613. array('id' => $id,
  614. 'state' => ModUtil::STATE_ACTIVE))) {
  615. // Success
  616. LogUtil::registerStatus($this->__('Activated'));
  617. }
  618. }
  619. // Clear the Zikula_View cached/compiled files and Themes cached/compiled/cssjs combination files
  620. $theme = \Zikula_View_Theme::getInstance('Theme');
  621. $theme->clear_compiled();
  622. $theme->clear_all_cache();
  623. $theme->clear_cssjscombinecache();
  624. $this->view->clear_compiled();
  625. $this->view->clear_all_cache();
  626. return $this->redirect(ModUtil::url('Extensions', 'admin', 'view', array(
  627. 'startnum' => $startnum,
  628. 'letter' => $letter,
  629. 'state' => $state)));
  630. } elseif (is_bool($res)) {
  631. return $this->redirect(ModUtil::url('Extensions', 'admin', 'view', array(
  632. 'startnum' => $startnum,
  633. 'letter' => $letter,
  634. 'state' => $state)));
  635. } else {
  636. return $res;
  637. }
  638. }
  639. /**
  640. * Deactivate a module
  641. * @param int 'id' module id
  642. * @return bool true
  643. */
  644. public function deactivateAction()
  645. {
  646. $csrftoken = $this->request->get('csrftoken');
  647. $this->checkCsrfToken($csrftoken);
  648. $id = (int) $this->request->query->get('id', null);
  649. $startnum = (int) $this->request->query->get('startnum', null);
  650. $letter = $this->request->query->get('letter', null);
  651. $state = $this->request->query->get('state', null);
  652. if (empty($id) || !is_numeric($id)) {
  653. return LogUtil::registerError($this->__('Error! No module ID provided.'), 404, ModUtil::url('Extensions', 'admin', 'view'));
  654. }
  655. // check if the modules is the systems start module
  656. $modinfo = ModUtil::getInfo($id);
  657. if ($modinfo == false) {
  658. return LogUtil::registerError($this->__('Error! No such module ID exists.'), 404, ModUtil::url('Extensions', 'admin', 'view'));
  659. }
  660. $startmod = System::getVar('startpage');
  661. if ($startmod == $modinfo['name']) {
  662. return LogUtil::registerError($this->__('Error! This module is currently set as the site\'s home page. You must choose another module for the home page before you can deactivate this one.'), null, ModUtil::url('Extensions', 'admin', 'view'));
  663. }
  664. if (ModUtil::apiFunc('ExtensionsModule', 'admin', 'iscoremodule',array('modulename' => $modinfo['name']))) {
  665. return LogUtil::registerError($this->__('Error! You cannot deactivate this module. It is a mandatory core module, and is needed by the system.'), null, ModUtil::url('Extensions', 'admin', 'view'));
  666. }
  667. // Update state
  668. $setstate = ModUtil::apiFunc('ExtensionsModule', 'admin', 'setstate', array('id' => $id, 'state' => ModUtil::STATE_INACTIVE));
  669. if ($setstate) {
  670. // Success
  671. LogUtil::registerStatus($this->__('Done! Deactivated module.'));
  672. }
  673. return $this->redirect(ModUtil::url('Extensions', 'admin', 'view', array(
  674. 'startnum' => $startnum,
  675. 'letter' => $letter,
  676. 'state' => $state)));
  677. }
  678. /**
  679. * Remove a module
  680. * @param int 'id' module id
  681. * @return bool true if successful
  682. */
  683. public function removeAction()
  684. {
  685. // Get parameters from whatever input we need
  686. $id = (int) $this->request->get('id', 0);
  687. $objectid = (int) $this->request->get('objectid', 0);
  688. $confirmation = (bool) $this->request->get('confirmation', false);
  689. $dependents = (array) $this->request->get('dependents');
  690. $startnum = (int) $this->request->get('startnum');
  691. $letter = $this->request->get('letter');
  692. $state = $this->request->get('state');
  693. if ($objectid) {
  694. $id = $objectid;
  695. }
  696. $session = $this->request->getSession();
  697. $interactive_remove = $session->get('interactive_remove');
  698. $interactive_remove = (empty($interactive_remove)) ? false : true;
  699. if ($interactive_remove == false) {
  700. $session->set('modules_id', $id);
  701. $session->set('modules_startnum', $startnum);
  702. $session->set('modules_letter', $letter);
  703. $session->set('modules_state', $state);
  704. } else {
  705. $id = $session->get('modules_id');
  706. $startnum = $session->get('modules_startnum');
  707. $letter = $session->get('modules_letter');
  708. $state = $session->get('modules_state');
  709. $confirmation = 1;
  710. }
  711. if (empty($id) || !is_numeric($id) || !ModUtil::getInfo($id)) {
  712. return LogUtil::registerError($this->__('Error! No module ID provided.'), 404, ModUtil::url('Extensions', 'admin', 'view'));
  713. }
  714. // Check for confirmation.
  715. if (empty($confirmation)) {
  716. // No confirmation yet
  717. // Add a hidden field for the item ID to the output
  718. $this->view->assign('id', $id);
  719. // assign any dependencies - filtering out non-active module dependents
  720. $dependents = ModUtil::apiFunc('ExtensionsModule', 'admin', 'getdependents', array('modid' => $id));
  721. foreach ($dependents as $key => $dependent) {
  722. $modinfo = ModUtil::getInfo($dependent['modid']);
  723. if (!ModUtil::available($modinfo['name'])) {
  724. unset($dependents[$key]);
  725. } else {
  726. $dependents[$key] = array_merge($dependents[$key], $modinfo);
  727. }
  728. }
  729. // check the blocks module for existing blocks
  730. $blocks = ModUtil::apiFunc('BlocksModule', 'user', 'getall', array('modid' => $id));
  731. $this->view->assign('hasBlocks', count($blocks));
  732. $this->view->assign('dependents', $dependents)
  733. ->assign('startnum', $startnum)
  734. ->assign('letter', $letter)
  735. ->assign('state', $state);
  736. // Return the output that has been generated by this function
  737. return $this->response($this->view->fetch('Admin/remove.tpl'));
  738. }
  739. // If we get here it means that the user has confirmed the action
  740. $csrftoken = $this->request->get('csrftoken');
  741. $this->checkCsrfToken($csrftoken);
  742. // remove dependent modules
  743. foreach ($dependents as $dependent) {
  744. $remove = ModUtil::apiFunc('ExtensionsModule', 'admin', 'remove', array('id' => $dependent));
  745. if (!$remove) {
  746. return $this->redirect(ModUtil::url('Extensions', 'admin', 'view', array(
  747. 'startnum' => $startnum,
  748. 'letter' => $letter,
  749. 'state' => $state)));
  750. }
  751. }
  752. // remove the module blocks
  753. $blocks = ModUtil::apiFunc('BlocksModule', 'user', 'getall', array('modid' => $id));
  754. foreach ($blocks as $block) {
  755. $delete = ModUtil::apiFunc('BlocksModule', 'admin', 'delete', array('bid' => $block['bid']));
  756. if (!$delete) {
  757. LogUtil::registerError($this->__f('Error! Deleting the block %s .', $block['title']));
  758. return $this->redirect(ModUtil::url('Extensions', 'admin', 'view', array(
  759. 'startnum' => $startnum,
  760. 'letter' => $letter,
  761. 'state' => $state)));
  762. }
  763. }
  764. // Now we've removed dependents and associated blocks remove the main module
  765. $res = ModUtil::apiFunc('ExtensionsModule', 'admin', 'remove', array('id' => $id, 'interactive_remove' => $interactive_remove));
  766. if (is_bool($res) && $res == true) {
  767. // Success
  768. $session->remove('modules_id');
  769. $session->remove('modules_startnum');
  770. $session->remove('modules_letter');
  771. $session->remove('modules_state');
  772. $session->remove('interactive_remove');
  773. LogUtil::registerStatus($this->__('Done! Uninstalled module.'));
  774. return $this->redirect(ModUtil::url('Extensions', 'admin', 'view', array(
  775. 'startnum' => $startnum,
  776. 'letter' => $letter,
  777. 'state' => $state)));
  778. } elseif (is_bool($res)) {
  779. return $this->redirect(ModUtil::url('Extensions', 'admin', 'view', array(
  780. 'startnum' => $startnum,
  781. 'letter' => $letter,
  782. 'state' => $state)));
  783. } else {
  784. return $res;
  785. }
  786. }
  787. /**
  788. * This is a standard function to modify the configuration parameters of the
  789. * module
  790. * @return string HTML string
  791. */
  792. public function modifyconfigAction()
  793. {
  794. // Security check
  795. if (!SecurityUtil::checkPermission('Extensions::', '::', ACCESS_ADMIN)) {
  796. throw new \Zikula\Framework\Exception\ForbiddenException();
  797. }
  798. // assign all the module vars and return output
  799. return $this->response($this->view->assign($this->getVars())
  800. ->fetch('Admin/modifyconfig.tpl'));
  801. }
  802. /**
  803. * This is a standard function to update the configuration parameters of the
  804. * module given the information passed back by the modification form
  805. * @return bool true
  806. */
  807. public function updateconfigAction()
  808. {
  809. $this->checkCsrfToken();
  810. // Security check
  811. if (!SecurityUtil::checkPermission('Extensions::', '::', ACCESS_ADMIN)) {
  812. throw new \Zikula\Framework\Exception\ForbiddenException();
  813. }
  814. // Update module variables.
  815. $itemsperpage = (int) $this->request->request->get('itemsperpage', 25);
  816. if (!is_integer($itemsperpage) || $itemsperpage < 1) {
  817. LogUtil::registerError($this->__("Warning! The 'Items per page' setting must be a positive integer. The value you entered was corrected."));
  818. $itemsperpage = (int) $itemsperpage;
  819. if ($itemsperpage < 1) {
  820. $itemsperpage = 25;
  821. }
  822. }
  823. $this->setVar('itemsperpage', $itemsperpage);
  824. // the module configuration has been updated successfuly
  825. LogUtil::registerStatus($this->__('Done! Saved module configuration.'));
  826. // This function generated no output, and so now it is complete we redirect
  827. // the user to an appropriate page for them to carry on their work
  828. return $this->redirect(ModUtil::url('Extensions', 'admin', 'view'));
  829. }
  830. /**
  831. * Display information of a module compatibility with the version of the core
  832. * @param int 'id' identity of the module
  833. * @return string HTML output string
  834. */
  835. public function compinfoAction()
  836. {
  837. // get our input
  838. $id = (int) $this->request->get('id', null);
  839. $startnum = (int) $this->request->get('startnum');
  840. $letter = $this->request->get('letter');
  841. $state = (int) $this->request->get('state');
  842. // check the input
  843. if (!is_numeric($id)) {
  844. return LogUtil::registerArgsError(ModUtil::url('Extensions', 'admin', 'view'));
  845. }
  846. // get the modules information from the data base
  847. $modinfo = ModUtil::getInfo($id);
  848. if ($modinfo == false) {
  849. return LogUtil::registerError($this->__('Error! No such module ID exists.'), 404, ModUtil::url('Extensions', 'admin', 'view'));
  850. }
  851. if (!SecurityUtil::checkPermission('Extensions::', "$modinfo[name]::$id", ACCESS_ADMIN)) {
  852. throw new \Zikula\Framework\Exception\ForbiddenException();
  853. }
  854. // get the module information from the files system
  855. $moduleInfo = ModUtil::apiFunc('ExtensionsModule', 'admin', 'getfilemodules',
  856. array('name' => $modinfo['name']));
  857. // assign the module information and other variables to the template
  858. $this->view->assign('moduleInfo', $moduleInfo)
  859. ->assign('id', $id)
  860. ->assign('startnum', $startnum)
  861. ->assign('letter', $letter)
  862. ->assign('state', $state);
  863. // Return the output that has been generated by this function
  864. return $this->response($this->view->fetch('Admin/compinfo.tpl'));
  865. }
  866. /**
  867. * Lists all plugins.
  868. * @return string HTML output string
  869. */
  870. public function viewPluginsAction()
  871. {
  872. // Security check
  873. if (!SecurityUtil::checkPermission('Extensions::', '::', ACCESS_ADMIN)) {
  874. throw new \Zikula\Framework\Exception\ForbiddenException();
  875. }
  876. $state = $this->request->get('state', -1);
  877. $sort = $this->request->get('sort', null);
  878. $module = $this->request->get('bymodule', null);
  879. $systemplugins = $this->request->get('systemplugins', false)? true : null;
  880. $this->view->assign('state', $state);
  881. // generate an auth key to use in urls
  882. $csrfToken = SecurityUtil::generateCsrfToken($this->container, true);
  883. $plugins = array();
  884. $pluginClasses = ($systemplugins) ? PluginUtil::loadAllSystemPlugins() : PluginUtil::loadAllModulePlugins();
  885. foreach ($pluginClasses as $className) {
  886. $instance = PluginUtil::loadPlugin($className);
  887. $pluginstate = PluginUtil::getState($instance->getServiceId(), PluginUtil::getDefaultState());
  888. // Tweak UI if the plugin is AlwaysOn
  889. if ($instance instanceof \Zikula_Plugin_AlwaysOnInterface) {
  890. $pluginstate['state'] = PluginUtil::ENABLED;
  891. $pluginstate['version'] = $instance->getMetaVersion();
  892. }
  893. // state filer
  894. if ($state >= 0 && $pluginstate['state'] != $state) {
  895. continue;
  896. }
  897. // module filter
  898. if (!empty($module) && $instance->getModuleName() != $module) {
  899. continue;
  900. }
  901. $actions = array();
  902. // Translate state
  903. switch ($pluginstate['state']) {
  904. case PluginUtil::NOTINSTALLED:
  905. $status = $this->__('Not installed');
  906. $statusimage = 'redled.png';
  907. $actions[] = array('url' => ModUtil::url('Extensions', 'admin', 'initialisePlugin',
  908. array('plugin' => $className,
  909. 'state' => $state,
  910. 'bymodule' => $module,
  911. 'sort' => $sort,
  912. 'systemplugins' => $systemplugins,
  913. 'csrftoken' => $csrfToken)
  914. ),
  915. 'image' => 'folder_new.png',
  916. 'title' => $this->__('Install'));
  917. break;
  918. case PluginUtil::ENABLED:
  919. $status = $this->__('Active');
  920. $statusimage = 'greenled.png';
  921. $pluginLink = array();
  922. if (!$systemplugins) {
  923. $pluginLink['_module'] = $instance->getModuleName();
  924. }
  925. $pluginLink['_plugin'] = $instance->getPluginName();
  926. $pluginLink['_action'] = 'configure';
  927. if ($instance instanceof \Zikula_Plugin_ConfigurableInterface) {
  928. $actions[] = array('url' => ModUtil::url('Extensions', 'adminplugin', 'dispatch', $pluginLink),
  929. 'image' => 'configure.png',
  930. 'title' => $this->__('Configure plugin'));
  931. }
  932. // Dont allow to disable/uninstall plugins that are AlwaysOn
  933. if (!$instance instanceof \Zikula_Plugin_AlwaysOnInterface) {
  934. $actions[] = array('url' => ModUtil::url('Extensions', 'admin', 'deactivatePlugin',
  935. array('plugin' => $className,
  936. 'state' => $state,
  937. 'bymodule' => $module,
  938. 'sort' => $sort,
  939. 'systemplugins' => $systemplugins,
  940. 'csrftoken' => $csrfToken)
  941. ),
  942. 'image' => 'folder_re…

Large files files are truncated, but you can click here to view the full file