PageRenderTime 59ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 1ms

/administrator/components/com_zoo/controllers/manager.php

https://bitbucket.org/organicdevelopment/joomla-2.5
PHP | 913 lines | 528 code | 259 blank | 126 comment | 44 complexity | 395e83efdb05244dad87e9247494225a MD5 | raw file
Possible License(s): LGPL-3.0, GPL-2.0, MIT, BSD-3-Clause, LGPL-2.1
  1. <?php
  2. /**
  3. * @package com_zoo
  4. * @author YOOtheme http://www.yootheme.com
  5. * @copyright Copyright (C) YOOtheme GmbH
  6. * @license http://www.gnu.org/licenses/gpl.html GNU/GPL
  7. */
  8. /*
  9. Class: ManagerController
  10. The controller class for application manager
  11. */
  12. class ManagerController extends AppController {
  13. public $group;
  14. public $application;
  15. public function __construct($default = array()) {
  16. parent::__construct($default);
  17. // set base url
  18. $this->baseurl = $this->app->link(array('controller' => $this->controller), false);
  19. // get application group
  20. $this->group = $this->app->request->getString('group');
  21. // if group exists
  22. if ($this->group) {
  23. // add group to base url
  24. $this->baseurl .= '&group='.$this->group;
  25. // create application object
  26. $this->application = $this->app->object->create('Application');
  27. $this->application->setGroup($this->group);
  28. }
  29. // register tasks
  30. $this->registerTask('addtype', 'edittype');
  31. $this->registerTask('applytype', 'savetype');
  32. $this->registerTask('applyelements', 'saveelements');
  33. $this->registerTask('applyassignelements', 'saveassignelements');
  34. $this->registerTask('applysubmission', 'savesubmission');
  35. }
  36. public function display($cachable = false, $urlparams = false) {
  37. // set toolbar items
  38. $this->app->toolbar->title(JText::_('App Manager'), $this->app->get('icon'));
  39. $this->app->toolbar->custom('cleandb', $this->app->joomla->isVersion('1.5') ? 'new' : 'refresh', $this->app->joomla->isVersion('1.5') ? 'New' : 'Refresh', 'Clean Database', false);
  40. $type = $this->app->joomla->isVersion('1.5') ? 'config' : 'options';
  41. JToolBar::getInstance('toolbar')->appendButton('Popup', $type, 'Check For Modifications', JRoute::_(JUri::root() . 'administrator/index.php?option='.$this->app->component->self->name.'&controller='.$this->controller.'&task=checkmodifications&tmpl=component', true, -1), 570, 550);
  42. JToolBar::getInstance('toolbar')->appendButton('Popup', $type, 'Check Requirements', JRoute::_(JUri::root() . 'administrator/index.php?option='.$this->app->component->self->name.'&controller='.$this->controller.'&task=checkrequirements&tmpl=component', true, -1), 570, 550);
  43. $this->app->toolbar->custom('dobackup', 'archive', 'Archive', 'Backup Database', false);
  44. $this->app->zoo->toolbarHelp();
  45. // get applications
  46. $this->applications = $this->app->application->groups();
  47. // display view
  48. $this->getView()->display();
  49. }
  50. public function info() {
  51. // set toolbar items
  52. $this->app->system->application->set('JComponentTitle', $this->application->getToolbarTitle(JText::_('Information').': '.$this->application->getMetaData('name')));
  53. $this->app->toolbar->custom('doexport', 'archive', 'Archive', 'Export', false);
  54. $this->app->toolbar->custom('uninstallapplication', 'delete', 'Delete', 'Uninstall', false);
  55. $this->app->toolbar->deleteList('APP_DELETE_WARNING', 'removeapplication');
  56. $this->app->zoo->toolbarHelp();
  57. // get application instances for selected group
  58. $this->applications = $this->app->application->getApplications($this->application->getGroup());
  59. // display view
  60. $this->getView()->setLayout('info')->display();
  61. }
  62. public function installApplication() {
  63. // check for request forgeries
  64. $this->app->request->checkToken() or jexit('Invalid Token');
  65. // get the uploaded file information
  66. $userfile = $this->app->request->getVar('install_package', null, 'files', 'array');
  67. try {
  68. $result = $this->app->install->installApplicationFromUserfile($userfile);
  69. $update = $result == 2 ? 'updated' : 'installed';
  70. // set redirect message
  71. $msg = JText::sprintf('Application group (%s) successfully.', $update);
  72. } catch (InstallHelperException $e) {
  73. // raise notice on exception
  74. $this->app->error->raiseNotice(0, JText::sprintf('Error installing Application group (%s).', $e));
  75. $msg = null;
  76. }
  77. $this->setRedirect($this->baseurl, $msg);
  78. }
  79. public function uninstallApplication() {
  80. // check for request forgeries
  81. $this->app->request->checkToken() or jexit('Invalid Token');
  82. try {
  83. $this->app->install->uninstallApplication($this->application);
  84. // set redirect message
  85. $msg = JText::_('Application group uninstalled successful.');
  86. $link = $this->baseurl;
  87. } catch (InstallHelperException $e) {
  88. // raise notice on exception
  89. $this->app->error->raiseNotice(0, JText::sprintf('Error uninstalling application group (%s).', $e));
  90. $msg = null;
  91. $link = $this->baseurl.'&task=info';
  92. }
  93. $this->setRedirect($link, $msg);
  94. }
  95. public function removeApplication() {
  96. // check for request forgeries
  97. $this->app->request->checkToken() or jexit('Invalid Token');
  98. // init vars
  99. $cid = $this->app->request->get('cid', 'array', array());
  100. if (count($cid) < 1) {
  101. $this->app->error->raiseError(500, JText::_('Select a application to delete'));
  102. }
  103. try {
  104. $table = $this->app->table->application;
  105. // delete applications
  106. foreach ($cid as $id) {
  107. $table->delete($table->get($id));
  108. }
  109. // set redirect message
  110. $msg = JText::_('Application Deleted');
  111. } catch (AppException $e) {
  112. // raise notice on exception
  113. $this->app->error->raiseNotice(0, JText::sprintf('Error Deleting Application (%s).', $e));
  114. $msg = null;
  115. }
  116. $this->setRedirect($this->baseurl.'&task=info', $msg);
  117. }
  118. public function types() {
  119. // set toolbar items
  120. $this->app->system->application->set('JComponentTitle', $this->application->getToolbarTitle(JText::_('Types').': ' . $this->application->getMetaData('name')));
  121. $this->app->toolbar->custom('copytype', 'copy', '', 'Copy');
  122. $this->app->toolbar->deleteList('', 'removetype');
  123. $this->app->toolbar->editListX('edittype');
  124. $this->app->toolbar->addNewX('addtype');
  125. $this->app->zoo->toolbarHelp();
  126. // get types
  127. $this->types = $this->application->getTypes();
  128. // get templates
  129. $this->templates = $this->application->getTemplates();
  130. // get extensions / trigger layout init event
  131. $this->extensions = $this->app->event->dispatcher->notify($this->app->event->create($this->app, 'layout:init'))->getReturnValue();
  132. // display view
  133. $this->getView()->setLayout('types')->display();
  134. }
  135. public function editType() {
  136. // disable menu
  137. $this->app->request->setVar('hidemainmenu', 1);
  138. // get request vars
  139. $cid = $this->app->request->get('cid.0', 'string', '');
  140. $this->edit = $cid ? true : false;
  141. // get type
  142. if (empty($cid)) {
  143. $this->type = $this->app->object->create('Type', array(null, $this->application));
  144. } else {
  145. $this->type = $this->application->getType($cid);
  146. }
  147. // set toolbar items
  148. $this->app->system->application->set('JComponentTitle', $this->application->getToolbarTitle(JText::_('Type').': '.$this->type->name.' <small><small>[ '.($this->edit ? JText::_('Edit') : JText::_('New')).' ]</small></small>'));
  149. $this->app->toolbar->save('savetype');
  150. $this->app->toolbar->apply('applytype');
  151. $this->app->toolbar->cancel('types', $this->edit ? 'Close' : 'Cancel');
  152. $this->app->zoo->toolbarHelp();
  153. // display view
  154. ob_start();
  155. $this->getView()->setLayout('edittype')->display();
  156. $output = ob_get_contents();
  157. ob_end_clean();
  158. // trigger edit event
  159. $this->app->event->dispatcher->notify($this->app->event->create($this->type, 'type:editdisplay', array('html' => &$output)));
  160. echo $output;
  161. }
  162. public function copyType() {
  163. // check for request forgeries
  164. $this->app->request->checkToken() or jexit('Invalid Token');
  165. // init vars
  166. $msg = '';
  167. $cid = $this->app->request->get('cid', 'array', array());
  168. if (count($cid) < 1) {
  169. $this->app->error->raiseError(500, JText::_('Select a type to copy'));
  170. }
  171. // copy types
  172. foreach ($cid as $id) {
  173. try {
  174. // get type
  175. $type = $this->application->getType($id);
  176. // copy type
  177. $copy = $this->app->object->create('Type', array(null, $this->application));
  178. $copy->identifier = $type->identifier.'-copy'; // set copied alias
  179. $this->app->type->setUniqueIndentifier($copy); // set unique identifier
  180. $copy->name = sprintf('%s (%s)', $type->name, JText::_('Copy')); // set copied name
  181. // give elements a new unique id
  182. $elements = array();
  183. foreach ($type->elements as $identifier => $element) {
  184. if ($type->getElement($identifier)->getGroup() != 'Core') {
  185. $elements[$this->app->utility->generateUUID()] = $element;
  186. } else {
  187. $elements[$identifier] = $element;
  188. }
  189. }
  190. $copy->elements = $elements;
  191. // save copied type
  192. $copy->save();
  193. // trigger copied event
  194. $this->app->event->dispatcher->notify($this->app->event->create($copy, 'type:copied', array('old_id' => $id)));
  195. $msg = JText::_('Type Copied');
  196. } catch (AppException $e) {
  197. // raise notice on exception
  198. $this->app->error->raiseNotice(0, JText::sprintf('Error Copying Type (%s).', $e));
  199. $msg = null;
  200. break;
  201. }
  202. }
  203. $this->setRedirect($this->baseurl.'&task=types', $msg);
  204. }
  205. public function saveType() {
  206. // check for request forgeries
  207. $this->app->request->checkToken() or jexit('Invalid Token');
  208. // init vars
  209. $post = $this->app->request->get('post:', 'array', array());
  210. $cid = $this->app->request->get('cid.0', 'string', '');
  211. // get type
  212. $type = $this->application->getType($cid);
  213. // type is new ?
  214. if (!$type) {
  215. $type = $this->app->object->create('Type', array(null, $this->application));
  216. }
  217. // filter identifier
  218. $post['identifier'] = $this->app->string->sluggify($post['identifier'] == '' ? $post['name'] : $post['identifier']);
  219. try {
  220. // set post data and save type
  221. $type->bind($post);
  222. // ensure unique identifier
  223. $this->app->type->setUniqueIndentifier($type);
  224. // trigger before save event
  225. $this->app->event->dispatcher->notify($this->app->event->create($type, 'type:beforesave'));
  226. // save type
  227. $type->save();
  228. // trigger after save event
  229. $this->app->event->dispatcher->notify($this->app->event->create($type, 'type:aftersave'));
  230. // set redirect message
  231. $msg = JText::_('Type Saved');
  232. } catch (AppException $e) {
  233. // raise notice on exception
  234. $this->app->error->raiseNotice(0, JText::sprintf('Error Saving Type (%s).', $e));
  235. $this->_task = 'apply';
  236. $msg = null;
  237. }
  238. switch ($this->getTask()) {
  239. case 'applytype':
  240. $link = $this->baseurl.'&task=edittype&cid[]='.$type->id;
  241. break;
  242. case 'savetype':
  243. default:
  244. $link = $this->baseurl.'&task=types';
  245. break;
  246. }
  247. $this->setRedirect($link, $msg);
  248. }
  249. public function removeType() {
  250. // check for request forgeries
  251. $this->app->request->checkToken() or jexit('Invalid Token');
  252. // init vars
  253. $msg = '';
  254. $cid = $this->app->request->get('cid', 'array', array());
  255. if (count($cid) < 1) {
  256. $this->app->error->raiseError(500, JText::_('Select a type to delete'));
  257. }
  258. foreach ($cid as $id) {
  259. try {
  260. // delete type
  261. $type = $this->application->getType($id);
  262. $type->delete();
  263. // trigger after save event
  264. $this->app->event->dispatcher->notify($this->app->event->create($type, 'type:deleted'));
  265. // set redirect message
  266. $msg = JText::_('Type Deleted');
  267. } catch (AppException $e) {
  268. // raise notice on exception
  269. $this->app->error->raiseNotice(0, JText::sprintf('Error Deleting Type (%s).', $e));
  270. $msg = null;
  271. break;
  272. }
  273. }
  274. $this->setRedirect($this->baseurl.'&task=types', $msg);
  275. }
  276. public function editElements() {
  277. // disable menu
  278. $this->app->request->setVar('hidemainmenu', 1);
  279. // get request vars
  280. $cid = $this->app->request->get('cid.0', 'string', '');
  281. // get type
  282. $this->type = $this->application->getType($cid);
  283. // set toolbar items
  284. $this->app->system->application->set('JComponentTitle', $this->application->getToolbarTitle(JText::_('Type').': '.$this->type->name.' <small><small>[ '.JText::_('Edit elements').' ]</small></small>'));
  285. $this->app->toolbar->save('saveelements');
  286. $this->app->toolbar->apply('applyelements');
  287. $this->app->toolbar->cancel('types', 'Close');
  288. $this->app->zoo->toolbarHelp();
  289. // sort elements by group
  290. $this->elements = array();
  291. foreach ($this->app->element->getAll($this->application) as $element) {
  292. $this->elements[$element->getGroup()][$element->getElementType()] = $element;
  293. }
  294. ksort($this->elements);
  295. foreach ($this->elements as $group => $elements) {
  296. ksort($elements);
  297. $this->elements[$group] = $elements;
  298. }
  299. // display view
  300. $this->getView()->setLayout('editElements')->display();
  301. }
  302. public function addElement() {
  303. // get request vars
  304. $element = $this->app->request->getWord('element', 'text');
  305. // load element
  306. $this->element = $this->app->element->create($element, $this->application);
  307. $this->element->identifier = $this->app->utility->generateUUID();
  308. // display view
  309. $this->getView()->setLayout('addElement')->display();
  310. }
  311. public function saveElements() {
  312. // check for request forgeries
  313. $this->app->request->checkToken() or jexit('Invalid Token');
  314. // init vars
  315. $post = $this->app->request->get('post:', 'array', array());
  316. $cid = $this->app->request->get('cid.0', 'string', '');
  317. try {
  318. // save types elements
  319. $type = $this->application->getType($cid);
  320. $type->bindElements($post)->save();
  321. // reset related item search data
  322. $table = $this->app->table->item;
  323. $items = $table->getByType($type->id, $this->application->id);
  324. foreach ($items as $item) {
  325. $table->save($item);
  326. }
  327. $msg = JText::_('Elements Saved');
  328. } catch (AppException $e) {
  329. $this->app->error->raiseNotice(0, JText::sprintf('Error Saving Elements (%s)', $e));
  330. $this->_task = 'applyelements';
  331. $msg = null;
  332. }
  333. switch ($this->getTask()) {
  334. case 'applyelements':
  335. $link = $this->baseurl.'&task=editelements&cid[]='.$type->id;
  336. break;
  337. case 'saveelements':
  338. default:
  339. $link = $this->baseurl.'&task=types';
  340. break;
  341. }
  342. $this->setRedirect($link, $msg);
  343. }
  344. public function assignElements() {
  345. // disable menu
  346. $this->app->request->setVar('hidemainmenu', 1);
  347. // init vars
  348. $type = $this->app->request->getString('type');
  349. $this->relative_path = urldecode($this->app->request->getVar('path'));
  350. $this->path = $this->relative_path ? JPATH_ROOT . '/' . $this->relative_path : '';
  351. $this->layout = $this->app->request->getString('layout');
  352. $dispatcher = JDispatcher::getInstance();
  353. if (strpos($this->relative_path, 'plugins') === 0) {
  354. @list($_, $plugin_type, $plugin_name) = explode('/', $this->relative_path);
  355. JPluginHelper::importPlugin($plugin_type, $plugin_name);
  356. }
  357. $dispatcher->trigger('registerZOOEvents');
  358. // get type
  359. $this->type = $this->application->getType($type);
  360. if ($this->type) {
  361. // set toolbar items
  362. $this->app->system->application->set('JComponentTitle', $this->application->getToolbarTitle(JText::_('Type').': '.$this->type->name.' <small><small>[ '.JText::_('Assign elements').': '. $this->layout .' ]</small></small>'));
  363. $this->app->toolbar->save('saveassignelements');
  364. $this->app->toolbar->apply('applyassignelements');
  365. $this->app->toolbar->cancel('types');
  366. $this->app->zoo->toolbarHelp();
  367. // get renderer
  368. $renderer = $this->app->renderer->create('item')->addPath($this->path);
  369. // get positions and config
  370. $this->config = $renderer->getConfig('item')->get($this->group.'.'.$type.'.'.$this->layout);
  371. $prefix = 'item.';
  372. if ($renderer->pathExists('item'.DIRECTORY_SEPARATOR.$type)) {
  373. $prefix .= $type.'.';
  374. }
  375. $this->positions = $renderer->getPositions($prefix.$this->layout);
  376. // display view
  377. ob_start();
  378. $this->getView()->setLayout('assignelements')->display();
  379. $output = ob_get_contents();
  380. ob_end_clean();
  381. // trigger edit event
  382. $this->app->event->dispatcher->notify($this->app->event->create($this->type, 'type:assignelements', array('html' => &$output)));
  383. echo $output;
  384. } else {
  385. $this->app->error->raiseNotice(0, JText::sprintf('Unable to find type (%s).', $type));
  386. $this->setRedirect($this->baseurl . '&task=types&group=' . $this->application->getGroup());
  387. }
  388. }
  389. public function saveAssignElements() {
  390. // check for request forgeries
  391. $this->app->request->checkToken() or jexit('Invalid Token');
  392. // init vars
  393. $type = $this->app->request->getString('type');
  394. $layout = $this->app->request->getString('layout');
  395. $relative_path = $this->app->request->getVar('path');
  396. $path = $relative_path ? JPATH_ROOT . '/' . urldecode($relative_path) : '';
  397. $positions = $this->app->request->getVar('positions', array(), 'post', 'array');
  398. // unset unassigned position
  399. unset($positions['unassigned']);
  400. // get renderer
  401. $renderer = $this->app->renderer->create('item')->addPath($path);
  402. // clean config
  403. $config = $renderer->getConfig('item');
  404. foreach ($config as $key => $value) {
  405. $parts = explode('.', $key);
  406. if ($parts[0] == $this->group && !$this->application->getType($parts[1])) {
  407. $config->remove($key);
  408. }
  409. }
  410. // save config
  411. $config->set($this->group.'.'.$type.'.'.$layout, $positions);
  412. $renderer->saveConfig($config, $path.'/renderer/item/positions.config');
  413. switch ($this->getTask()) {
  414. case 'applyassignelements':
  415. $link = $this->baseurl.'&task=assignelements&type='.$type.'&layout='.$layout.'&path='.$relative_path;
  416. break;
  417. default:
  418. $link = $this->baseurl.'&task=types';
  419. break;
  420. }
  421. $this->setRedirect($link, JText::_('Elements Assigned'));
  422. }
  423. public function assignSubmission() {
  424. // disable menu
  425. $this->app->request->setVar('hidemainmenu', 1);
  426. // init vars
  427. $type = $this->app->request->getString('type');
  428. $this->template = $this->app->request->getString('template');
  429. $this->layout = $this->app->request->getString('layout');
  430. // get type
  431. $this->type = $this->application->getType($type);
  432. // set toolbar items
  433. $this->app->system->application->set('JComponentTitle', $this->application->getToolbarTitle(JText::_('Type').': '.$this->type->name.' <small><small>[ '.JText::_('Assign Submittable elements').': '. $this->layout .' ]</small></small>'));
  434. $this->app->toolbar->save('savesubmission');
  435. $this->app->toolbar->apply('applysubmission');
  436. $this->app->toolbar->cancel('types');
  437. $this->app->zoo->toolbarHelp();
  438. // for template
  439. $this->path = $this->application->getPath().'/templates/'.$this->template;
  440. // get renderer
  441. $renderer = $this->app->renderer->create('submission')->addPath($this->path);
  442. // get positions and config
  443. $this->config = $renderer->getConfig('item')->get($this->group.'.'.$type.'.'.$this->layout);
  444. $prefix = 'item.';
  445. if ($renderer->pathExists('item'.DIRECTORY_SEPARATOR.$type)) {
  446. $prefix .= $type.'.';
  447. }
  448. $this->positions = $renderer->getPositions($prefix.$this->layout);
  449. // display view
  450. $this->getView()->setLayout('assignsubmission')->display();
  451. }
  452. public function saveSubmission() {
  453. // check for request forgeries
  454. $this->app->request->checkToken() or jexit('Invalid Token');
  455. // init vars
  456. $type = $this->app->request->getString('type');
  457. $template = $this->app->request->getString('template');
  458. $layout = $this->app->request->getString('layout');
  459. $positions = $this->app->request->getVar('positions', array(), 'post', 'array');
  460. // unset unassigned position
  461. unset($positions['unassigned']);
  462. // for template, module
  463. $path = '';
  464. if ($template) {
  465. $path = $this->application->getPath().'/templates/'.$template;
  466. }
  467. // get renderer
  468. $renderer = $this->app->renderer->create('submission')->addPath($path);
  469. // clean config
  470. $config = $renderer->getConfig('item');
  471. foreach ($config as $key => $value) {
  472. $parts = explode('.', $key);
  473. if ($parts[0] == $this->group && !$this->application->getType($parts[1])) {
  474. $config->remove($key);
  475. }
  476. }
  477. // save config
  478. $config->set($this->group.'.'.$type.'.'.$layout, $positions);
  479. $renderer->saveConfig($config, $path.'/renderer/item/positions.config');
  480. switch ($this->getTask()) {
  481. case 'applysubmission':
  482. $link = $this->baseurl.'&task=assignsubmission&type='.$type.'&layout='.$layout;
  483. $link .= $template ? '&template='.$template : null;
  484. break;
  485. default:
  486. $link = $this->baseurl.'&task=types';
  487. break;
  488. }
  489. $this->setRedirect($link, JText::_('Submitable Elements Assigned'));
  490. }
  491. public function doExport() {
  492. // check for request forgeries
  493. $this->app->request->checkToken() or jexit('Invalid Token');
  494. $filepath = $this->app->path->path("tmp:").'/'.$this->application->getGroup().'.zip';
  495. $read_directory = $this->application->getPath() . '/';
  496. $zip = $this->app->archive->open($filepath, 'zip');
  497. $files = $this->app->path->files($this->application->getResource(), true);
  498. $files = array_map(create_function('$file', 'return "'.$read_directory.'".$file;'), $files);
  499. $zip->create($files, PCLZIP_OPT_REMOVE_PATH, $read_directory);
  500. if (is_readable($filepath) && JFile::exists($filepath)) {
  501. $this->app->filesystem->output($filepath);
  502. if (!JFile::delete($filepath)) {
  503. $this->app->error->raiseNotice(0, JText::sprintf('Unable to delete file(%s).', $filepath));
  504. $this->setRedirect($this->baseurl.'&task=info');
  505. }
  506. } else {
  507. $this->app->error->raiseNotice(0, JText::sprintf('Unable to create file (%s).', $filepath));
  508. $this->setRedirect($this->baseurl.'&task=info');
  509. }
  510. }
  511. public function checkRequirements() {
  512. $this->app->loader->register('AppRequirements', 'installation:requirements.php');
  513. $requirements = $this->app->object->create('AppRequirements');
  514. $requirements->checkRequirements();
  515. $requirements->displayResults();
  516. }
  517. public function checkModifications() {
  518. // add system.css for
  519. $this->app->document->addStylesheet("root:administrator/templates/system/css/system.css");
  520. try {
  521. $this->results = $this->app->modification->check();
  522. // display view
  523. $this->getView()->setLayout('modifications')->display();
  524. } catch (AppModificationException $e) {
  525. $this->app->error->raiseNotice(0, $e);
  526. }
  527. }
  528. public function cleanModifications() {
  529. // check for request forgeries
  530. $this->app->request->checkToken() or jexit('Invalid Token');
  531. try {
  532. $this->app->modification->clean();
  533. $msg = JText::_('Unknown files removed.');
  534. } catch (AppModificationException $e) {
  535. $msg = JText::_('Error cleaning ZOO.');
  536. $this->app->error->raiseNotice(0, $e);
  537. }
  538. $route = JRoute::_($this->baseurl.'&task=checkmodifications&tmpl=component', false);
  539. $this->setRedirect($route, $msg);
  540. }
  541. public function verify() {
  542. $result = false;
  543. try {
  544. $result = $this->app->modification->verify();
  545. } catch (AppModificationException $e) {}
  546. echo json_encode(compact('result'));
  547. }
  548. public function doBackup() {
  549. if ($result = $this->app->backup->all()) {
  550. $result = $this->app->backup->generateHeader() . $result;
  551. $size = strlen($result);
  552. while (@ob_end_clean());
  553. header("Pragma: public");
  554. header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
  555. header("Expires: 0");
  556. header("Content-Transfer-Encoding: binary");
  557. header('Content-Type: application/zip');
  558. header('Content-Disposition: attachment;'
  559. .' filename="zoo-db-backup-'.time().'-'.(md5(implode(',', $this->app->backup->getTables()))).'.sql";'
  560. .' modification-date="'.date('r').'";'
  561. .' size='.$size.';');
  562. header("Content-Length: ".$size);
  563. echo $result;
  564. return;
  565. }
  566. // raise error on exception
  567. $this->app->error->raiseNotice(0, JText::_('Error Creating Backup'));
  568. $this->setRedirect($this->baseurl);
  569. }
  570. public function restoreBackup() {
  571. // check for request forgeries
  572. $this->app->request->checkToken() or jexit('Invalid Token');
  573. // get the uploaded file information
  574. $userfile = $this->app->request->getVar('backupfile', null, 'files', 'array');
  575. try {
  576. $file = $this->app->validator->create('file', array('extension' => array('sql')))->clean($userfile);
  577. $this->app->backup->restore($file['tmp_name']);
  578. $msg = JText::_('Database backup successfully restored');
  579. } catch (AppValidatorException $e) {
  580. $msg = '';
  581. $this->app->error->raiseNotice(0, "Error uploading backup file. ($e) Please upload .sql files only.");
  582. } catch (BackupHelperException $e) {
  583. $msg = '';
  584. $this->app->error->raiseNotice(0, JText::sprintf("Error restoring ZOO backup. (%s)", $e));
  585. }
  586. $this->setRedirect($this->baseurl, $msg);
  587. }
  588. public function cleanDB() {
  589. // init vars
  590. $row = 0;
  591. $db = $this->app->database;
  592. if (($apps = $this->app->path->dirs('applications:')) && !empty($apps)) {
  593. $db->query(sprintf("DELETE FROM ".ZOO_TABLE_APPLICATION." WHERE application_group NOT IN ('%s')", implode("', '", $apps)));
  594. }
  595. $db->query("DELETE FROM ".ZOO_TABLE_ITEM." WHERE type = ''");
  596. $row += $db->getAffectedRows();
  597. $db->query("DELETE FROM ".ZOO_TABLE_ITEM." WHERE NOT EXISTS (SELECT id FROM ".ZOO_TABLE_APPLICATION." WHERE id = application_id)");
  598. $row += $db->getAffectedRows();
  599. $db->query("DELETE FROM ".ZOO_TABLE_CATEGORY." WHERE NOT EXISTS (SELECT id FROM ".ZOO_TABLE_APPLICATION." WHERE id = application_id)");
  600. $row += $db->getAffectedRows();
  601. $db->query("DELETE FROM ".ZOO_TABLE_SUBMISSION." WHERE NOT EXISTS (SELECT id FROM ".ZOO_TABLE_APPLICATION." WHERE id = application_id)");
  602. $row += $db->getAffectedRows();
  603. $db->query("DELETE FROM ".ZOO_TABLE_TAG." WHERE NOT EXISTS (SELECT id FROM ".ZOO_TABLE_ITEM." WHERE id = item_id)");
  604. $row += $db->getAffectedRows();
  605. $db->query("DELETE FROM ".ZOO_TABLE_COMMENT." WHERE NOT EXISTS (SELECT id FROM ".ZOO_TABLE_ITEM." WHERE id = item_id)");
  606. $row += $db->getAffectedRows();
  607. $db->query("DELETE FROM ".ZOO_TABLE_RATING." WHERE NOT EXISTS (SELECT id FROM ".ZOO_TABLE_ITEM." WHERE id = item_id)");
  608. $row += $db->getAffectedRows();
  609. $db->query("DELETE FROM ".ZOO_TABLE_SEARCH." WHERE NOT EXISTS (SELECT id FROM ".ZOO_TABLE_ITEM." WHERE id = item_id)");
  610. $row += $db->getAffectedRows();
  611. $db->query("DELETE FROM ".ZOO_TABLE_CATEGORY_ITEM." WHERE category_id != 0 AND (NOT EXISTS (SELECT id FROM ".ZOO_TABLE_ITEM." WHERE id = item_id) OR NOT EXISTS (SELECT id FROM ".ZOO_TABLE_CATEGORY." WHERE id = category_id))");
  612. $row += $db->getAffectedRows();
  613. do {
  614. $result = $db->queryResultArray("SELECT id FROM ".ZOO_TABLE_CATEGORY." as a WHERE a.parent != 0 AND NOT EXISTS (SELECT * FROM ".ZOO_TABLE_CATEGORY." as b WHERE b.id = a.parent)");
  615. $again = !empty($result);
  616. if ($again) {
  617. $db->query(sprintf("DELETE FROM ".ZOO_TABLE_CATEGORY." WHERE id IN (%s)", implode(", ", $result)));
  618. $row += $db->getAffectedRows();
  619. }
  620. } while ($again);
  621. do {
  622. $result = $db->queryResultArray("SELECT id FROM ".ZOO_TABLE_COMMENT." as a WHERE a.parent_id != 0 AND NOT EXISTS (SELECT * FROM ".ZOO_TABLE_COMMENT." as b WHERE b.id = a.parent_id)");
  623. $again = !empty($result);
  624. if ($again) {
  625. $db->query(sprintf("DELETE FROM ".ZOO_TABLE_COMMENT." WHERE id IN (%s)", implode(", ", $result)));
  626. $row += $db->getAffectedRows();
  627. }
  628. } while ($again);
  629. // get the item table
  630. $table = $this->app->table->item;
  631. try {
  632. $items = $table->all();
  633. foreach ($items as $item) {
  634. try {
  635. $table->save($item);
  636. } catch (Exception $e) {
  637. $this->app->error->raiseNotice(0, JText::sprintf("Error updating search data for item with id %s. (%s)", $item->id, $e));
  638. }
  639. }
  640. $msg = JText::sprintf('Cleaned database (Removed %s entries) and items search data has been updated.', $row);
  641. } catch (Exception $e) {
  642. $msg = '';
  643. $this->app->error->raiseNotice(0, JText::sprintf("Error cleaning database. (%s)", $e));
  644. }
  645. $this->setRedirect($this->baseurl, $msg);
  646. }
  647. public function hideUpdateNotification() {
  648. $this->app->update->hideUpdateNotification();
  649. }
  650. }
  651. /*
  652. Class: ManagerControllerException
  653. */
  654. class ManagerControllerException extends AppException {}