PageRenderTime 41ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/system/cms/modules/modules/models/module_m.php

https://github.com/kadoshmt/Pyro-Deals
PHP | 625 lines | 358 code | 82 blank | 185 comment | 39 complexity | b9be8557c41e538057e896dccf9fb215 MD5 | raw file
  1. <?php defined('BASEPATH') OR exit('No direct script access allowed');
  2. /**
  3. * Modules model
  4. *
  5. * @author PyroCMS Development Team
  6. * @package PyroCMS
  7. * @subpackage Modules
  8. * @category Modules
  9. * @since v1.0
  10. */
  11. class Module_m extends MY_Model
  12. {
  13. protected $_table = 'modules';
  14. private $_module_exists = array();
  15. /**
  16. * Constructor method
  17. * @access public
  18. * @return void
  19. */
  20. public function __construct()
  21. {
  22. parent::__construct();
  23. $this->load->helper('modules/module');
  24. }
  25. /**
  26. * Get
  27. *
  28. * Return an array containing module data
  29. *
  30. * @access public
  31. * @param string $module The name of the module to load
  32. * @return array
  33. */
  34. public function get($module = '')
  35. {
  36. // Have to return an associative array of NULL values for backwards compatibility.
  37. $null_array = array(
  38. 'name' => NULL,
  39. 'slug' => NULL,
  40. 'version' => NULL,
  41. 'description' => NULL,
  42. 'skip_xss' => NULL,
  43. 'is_frontend' => NULL,
  44. 'is_backend' => NULL,
  45. 'menu' => FALSE,
  46. 'enabled' => 1,
  47. 'is_core' => NULL,
  48. 'is_current' => NULL
  49. );
  50. if (is_array($module) || empty($module))
  51. {
  52. return $null_array;
  53. }
  54. $result = $this->db
  55. ->where('slug', $module)
  56. ->get($this->_table)
  57. ->row();
  58. if ($result)
  59. {
  60. // Return FALSE if the module is disabled
  61. if ($result->enabled == 0)
  62. {
  63. return FALSE;
  64. }
  65. if ( ! $descriptions = unserialize($result->description))
  66. {
  67. $this->session->set_flashdata('error', sprintf(lang('modules.details_error'), $result->slug));
  68. }
  69. $description = !isset($descriptions[CURRENT_LANGUAGE]) ? $descriptions['en'] : $descriptions[CURRENT_LANGUAGE];
  70. if ( ! $names = unserialize($result->name))
  71. {
  72. $this->session->set_flashdata('error', sprintf(lang('modules.details_error'), $result->slug));
  73. }
  74. $name = !isset($names[CURRENT_LANGUAGE]) ? $names['en'] : $names[CURRENT_LANGUAGE];
  75. return array(
  76. 'name' => $name,
  77. 'slug' => $result->slug,
  78. 'version' => $result->version,
  79. 'description' => $description,
  80. 'skip_xss' => $result->skip_xss,
  81. 'is_frontend' => $result->is_frontend,
  82. 'is_backend' => $result->is_backend,
  83. 'menu' => $result->menu,
  84. 'enabled' => $result->enabled,
  85. 'is_core' => $result->is_core,
  86. 'is_current' => version_compare($result->version, $this->version($result->slug), '>=')
  87. );
  88. }
  89. return $null_array;
  90. }
  91. /**
  92. * Add
  93. *
  94. * Adds a module to the database
  95. *
  96. * @access public
  97. * @param array $module Information about the module
  98. * @return object
  99. */
  100. public function add($module)
  101. {
  102. return $this->db->insert($this->_table, array(
  103. 'name' => serialize($module['name']),
  104. 'slug' => $module['slug'],
  105. 'version' => $module['version'],
  106. 'description' => serialize($module['description']),
  107. 'skip_xss' => ! empty($module['skip_xss']),
  108. 'is_frontend' => ! empty($module['frontend']),
  109. 'is_backend' => ! empty($module['backend']),
  110. 'menu' => ! empty($module['menu']) ? $module['menu'] : FALSE,
  111. 'enabled' => ! empty($module['enabled']),
  112. 'installed' => ! empty($module['installed']),
  113. 'is_core' => ! empty($module['is_core'])
  114. ));
  115. }
  116. /**
  117. * Update
  118. *
  119. * Updates a module in the database
  120. *
  121. * @access public
  122. * @param array $slug Module slug to update
  123. * @param array $module Information about the module
  124. * @return object
  125. */
  126. public function update($slug, $module)
  127. {
  128. return $this->db->where('slug', $slug)->update($this->_table, $module);
  129. }
  130. /**
  131. * Delete
  132. *
  133. * Delete a module from the database
  134. *
  135. * @param array $slug The module slug
  136. * @access public
  137. * @return object
  138. */
  139. public function delete($slug)
  140. {
  141. return $this->db->delete($this->_table, array('slug' => $slug));
  142. }
  143. /**
  144. * Get Modules
  145. *
  146. * Return an array of objects containing module related data
  147. *
  148. * @param array $params The array containing the modules to load
  149. * @param bool $return_disabled Whether to return disabled modules
  150. * @access public
  151. * @return array
  152. */
  153. public function get_all($params = array(), $return_disabled = FALSE)
  154. {
  155. $modules = array();
  156. // We have some parameters for the list of modules we want
  157. if ($params)
  158. {
  159. foreach ($params as $field => $value)
  160. {
  161. if (in_array($field, array('is_frontend', 'is_backend', 'menu', 'is_core')))
  162. {
  163. $this->db->where($field, $value);
  164. }
  165. }
  166. }
  167. // Skip the disabled modules
  168. if ($return_disabled === FALSE)
  169. {
  170. $this->db->where('enabled', 1);
  171. }
  172. foreach ($this->db->get($this->_table)->result() as $result)
  173. {
  174. if ( ! $descriptions = @unserialize($result->description))
  175. {
  176. $this->session->set_flashdata('error', sprintf(lang('modules.details_error'), $result->slug));
  177. }
  178. $description = ! isset($descriptions[CURRENT_LANGUAGE]) ? $descriptions['en'] : $descriptions[CURRENT_LANGUAGE];
  179. if ( ! $names = @unserialize($result->name))
  180. {
  181. $this->session->set_flashdata('error', sprintf(lang('modules.details_error'), $result->slug));
  182. }
  183. $name = ! isset($names[CURRENT_LANGUAGE]) ? $names['en'] : $names[CURRENT_LANGUAGE];
  184. $module = array(
  185. 'name' => $name,
  186. 'slug' => $result->slug,
  187. 'version' => $result->version,
  188. 'description' => $description,
  189. 'skip_xss' => $result->skip_xss,
  190. 'is_frontend' => $result->is_frontend,
  191. 'is_backend' => $result->is_backend,
  192. 'menu' => $result->menu,
  193. 'enabled' => $result->enabled,
  194. 'installed' => ! empty($result->installed),
  195. 'is_core' => $result->is_core,
  196. 'is_current' => version_compare($result->version, $this->version($result->slug), '>='),
  197. 'current_version' => $this->version($result->slug)
  198. );
  199. if ( ! empty($params['is_backend']))
  200. {
  201. // This user has no permissions for this module
  202. if ( $this->user->group !== 'admin' AND empty($this->permissions[$result->slug]))
  203. {
  204. continue;
  205. }
  206. }
  207. $modules[$module['name']] = $module;
  208. }
  209. ksort($modules);
  210. return array_values($modules);
  211. }
  212. /**
  213. * Exists
  214. *
  215. * Checks if a module exists
  216. *
  217. * @param string $module The module slug
  218. * @return bool
  219. */
  220. public function exists($module)
  221. {
  222. $this->_module_exists = array();
  223. if ( ! $module)
  224. {
  225. return FALSE;
  226. }
  227. // We already know about this module
  228. if (isset($this->_module_exists[$module]))
  229. {
  230. return $this->_module_exists[$module];
  231. }
  232. return $this->_module_exists[$module] = $this->db
  233. ->where('slug', $module)
  234. ->count_all_results($this->_table) > 0;
  235. }
  236. /**
  237. * Enable
  238. *
  239. * Enables a module
  240. *
  241. * @param string $module The module slug
  242. * @return bool
  243. */
  244. public function enable($module)
  245. {
  246. if ($this->exists($module))
  247. {
  248. $this->db->where('slug', $module)->update($this->_table, array('enabled' => 1));
  249. return TRUE;
  250. }
  251. return FALSE;
  252. }
  253. /**
  254. * Disable
  255. *
  256. * Disables a module
  257. *
  258. * @param string $module The module slug
  259. * @return bool
  260. */
  261. public function disable($module)
  262. {
  263. if ($this->exists($module))
  264. {
  265. $this->db->where('slug', $module)->update($this->_table, array('enabled' => 0));
  266. return TRUE;
  267. }
  268. return FALSE;
  269. }
  270. /**
  271. * Install
  272. *
  273. * Installs a module
  274. *
  275. * @param string $slug The module slug
  276. * @return bool
  277. */
  278. public function install($slug, $is_core = FALSE, $insert = FALSE)
  279. {
  280. if ( ! $details_class = $this->_spawn_class($slug, $is_core))
  281. {
  282. return FALSE;
  283. }
  284. // They've just finished uploading it so we need to make a record
  285. if ($insert)
  286. {
  287. // Get some info for the db
  288. $module = $details_class->info();
  289. // Now lets set some details ourselves
  290. $module['slug'] = $slug;
  291. $module['version'] = $details_class->version;
  292. $module['enabled'] = $is_core; // enable if core
  293. $module['installed'] = $is_core; // install if core
  294. $module['is_core'] = $is_core; // is core if core
  295. // It's a valid module let's make a record of it
  296. $this->add($module);
  297. }
  298. // TURN ME ON BABY!
  299. $this->db->where('slug', $slug)->update('modules', array('enabled' => 1, 'installed' => 1));
  300. // set the site_ref and upload_path for third-party devs
  301. $details_class->site_ref = SITE_REF;
  302. $details_class->upload_path = 'uploads/'.SITE_REF.'/';
  303. // Run the install method to get it into the database
  304. return $details_class->install();
  305. }
  306. /**
  307. * Uninstall
  308. *
  309. * Unnstalls a module
  310. *
  311. * @param string $module The module slug
  312. * @return bool
  313. */
  314. public function uninstall($slug, $is_core = FALSE)
  315. {
  316. if ( ! $details_class = $this->_spawn_class($slug, $is_core))
  317. {
  318. // the files are missing so let's clean the "modules" table
  319. return $this->delete($slug);
  320. }
  321. // set the site_ref and upload_path for third-party devs
  322. $details_class->site_ref = SITE_REF;
  323. $details_class->upload_path = 'uploads/'.SITE_REF.'/';
  324. // Run the uninstall method to drop the module's tables
  325. if ( ! $details_class->uninstall())
  326. {
  327. return FALSE;
  328. }
  329. if ($this->delete($slug))
  330. {
  331. // Get some info for the db
  332. $module = $details_class->info();
  333. // Now lets set some details ourselves
  334. $module['slug'] = $slug;
  335. $module['version'] = $details_class->version;
  336. $module['enabled'] = $is_core; // enable if core
  337. $module['installed'] = $is_core; // install if core
  338. $module['is_core'] = $is_core; // is core if core
  339. // We record it again here. If they really want to get rid of it they'll use Delete
  340. return $this->add($module);
  341. }
  342. return FALSE;
  343. }
  344. /**
  345. * Upgrade
  346. *
  347. * Upgrade a module
  348. *
  349. * @param string $module The module slug
  350. * @return bool
  351. */
  352. public function upgrade($slug)
  353. {
  354. // Get info on the new module
  355. if ( ! $details_class = $this->_spawn_class($slug) )
  356. {
  357. return FALSE;
  358. }
  359. // Get info on the old module
  360. if ( ! $old_module = $this->get($slug) )
  361. {
  362. return FALSE;
  363. }
  364. // Get the old module version number
  365. $old_version = $old_module['version'];
  366. // set the site_ref and upload_path for third-party devs
  367. $details_class->site_ref = SITE_REF;
  368. $details_class->upload_path = 'uploads/'.SITE_REF.'/';
  369. // Run the update method to get it into the database
  370. if ($details_class->upgrade($old_version))
  371. {
  372. // Update version number
  373. $this->db->where('slug', $slug)->update('modules', array('version' => $details_class->version));
  374. return TRUE;
  375. }
  376. // The upgrade failed
  377. else
  378. {
  379. return FALSE;
  380. }
  381. }
  382. public function import_unknown()
  383. {
  384. $modules = array();
  385. $is_core = TRUE;
  386. $known = $this->get_all(array(), TRUE);
  387. $known_array = array();
  388. // Loop through the known array and assign it to a single dimension because
  389. // in_array can not search a multi array.
  390. if (is_array($known) && count($known) > 0)
  391. {
  392. foreach ($known AS $item)
  393. {
  394. $known_array = array_merge(array($item['slug']), $known_array);
  395. }
  396. }
  397. foreach (array(APPPATH, ADDONPATH, SHARED_ADDONPATH) AS $directory)
  398. {
  399. foreach (glob($directory.'modules/*', GLOB_ONLYDIR) as $module_name)
  400. {
  401. $slug = basename($module_name);
  402. // This doesnt have a valid details.php file! :o
  403. if ( ! $details_class = $this->_spawn_class($slug, $is_core))
  404. {
  405. continue;
  406. }
  407. // Yeah yeah we know
  408. if (in_array($slug, $known_array))
  409. {
  410. continue;
  411. }
  412. // Get some basic info
  413. $module = $details_class->info();
  414. // Now lets set some details ourselves
  415. $module['slug'] = $slug;
  416. $module['version'] = $details_class->version;
  417. $module['enabled'] = $is_core; // enable if core
  418. $module['installed'] = $is_core; // install if core
  419. $module['is_core'] = $is_core; // is core if core
  420. // Looks like it installed ok, add a record
  421. $this->add($module);
  422. }
  423. // Going back around, 2nd time is addons
  424. $is_core = FALSE;
  425. }
  426. return TRUE;
  427. }
  428. /**
  429. * Spawn Class
  430. *
  431. * Checks to see if a details.php exists and returns a class
  432. *
  433. * @param string $slug The folder name of the module
  434. * @access private
  435. * @return array
  436. */
  437. private function _spawn_class($slug, $is_core = FALSE)
  438. {
  439. $path = $is_core ? APPPATH : ADDONPATH;
  440. // Before we can install anything we need to know some details about the module
  441. $details_file = $path . 'modules/' . $slug . '/details'.EXT;
  442. // Check the details file exists
  443. if ( ! is_file($details_file))
  444. {
  445. $details_file = SHARED_ADDONPATH . 'modules/' . $slug . '/details'.EXT;
  446. if ( ! is_file($details_file))
  447. {
  448. return FALSE;
  449. }
  450. }
  451. // Sweet, include the file
  452. include_once $details_file;
  453. // Now call the details class
  454. $class = 'Module_'.ucfirst(strtolower($slug));
  455. // Now we need to talk to it
  456. return class_exists($class) ? new $class : FALSE;
  457. }
  458. /**
  459. * Help
  460. *
  461. * Retrieves help string from details.php
  462. *
  463. * @param string $slug The module slug
  464. * @return bool
  465. */
  466. public function help($slug)
  467. {
  468. foreach (array(0, 1) AS $is_core)
  469. {
  470. $path = $is_core ? APPPATH : ADDONPATH;
  471. $languages = $this->config->item('supported_languages');
  472. $default = $languages[$this->config->item('default_language')]['folder'];
  473. //first try it as a core module
  474. if ($details_class = $this->_spawn_class($slug, $is_core))
  475. {
  476. // if the file doesn't exist then we first check the shared folder and if it
  477. // still doesn't exist we show the default help text from the details.php file
  478. if (file_exists($path . 'modules/' . $slug . '/language/' . $default . '/help_lang.php'))
  479. {
  480. $this->lang->load($slug . '/help');
  481. if (lang('help_body'))
  482. {
  483. return lang('help_body');
  484. }
  485. }
  486. elseif (file_exists(SHARED_ADDONPATH . 'modules/' . $slug . '/language/' . $default . '/help_lang.php'))
  487. {
  488. $this->lang->load($slug . '/help');
  489. if (lang('help_body'))
  490. {
  491. return lang('help_body');
  492. }
  493. }
  494. else
  495. {
  496. return $details_class->help();
  497. }
  498. }
  499. }
  500. return FALSE;
  501. }
  502. /**
  503. * Roles
  504. *
  505. * Retrieves roles for a specific module
  506. *
  507. * @param string $slug The module slug
  508. * @return bool
  509. */
  510. public function roles($slug)
  511. {
  512. foreach (array(0, 1) as $is_core)
  513. {
  514. //first try it as a core module
  515. if ($details_class = $this->_spawn_class($slug, $is_core))
  516. {
  517. $info = $details_class->info();
  518. if ( ! empty($info['roles']))
  519. {
  520. $this->lang->load($slug . '/permission');
  521. return $info['roles'];
  522. }
  523. }
  524. }
  525. return array();
  526. }
  527. /**
  528. * Help
  529. *
  530. * Retrieves version number from details.php
  531. *
  532. * @param string $slug The module slug
  533. * @return bool
  534. */
  535. public function version($slug)
  536. {
  537. if ($details_class = $this->_spawn_class($slug))
  538. {
  539. return $details_class->version;
  540. }
  541. return FALSE;
  542. }
  543. }