PageRenderTime 43ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/tmp/busines13_bundle_installer/com_gantry/admin/models/template.php

https://bitbucket.org/izubizarreta/https-bitbucket.org-bityvip
PHP | 692 lines | 403 code | 106 blank | 183 comment | 71 complexity | d682847194c605107c304f7cf5f3d68f MD5 | raw file
Possible License(s): LGPL-3.0, LGPL-2.0, JSON, GPL-2.0, BSD-3-Clause, LGPL-2.1, MIT
  1. <?php
  2. /**
  3. * @package gantry
  4. * @subpackage core
  5. * @version 3.2.22 August 3, 2012
  6. * @author RocketTheme http://www.rockettheme.com
  7. * @copyright Copyright (C) 2007 - 2012 RocketTheme, LLC
  8. * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPLv2 only
  9. *
  10. * Gantry uses the Joomla Framework (http://www.joomla.org), a GNU/GPLv2 content management system
  11. *
  12. */
  13. // No direct access.
  14. defined('_JEXEC') or die;
  15. jimport('joomla.application.component.modeladmin');
  16. /**
  17. * Template style model.
  18. *
  19. * @package Joomla.Administrator
  20. * @subpackage com_templates
  21. * @since 1.6
  22. */
  23. class GantryModelTemplate extends JModelAdmin
  24. {
  25. /**
  26. * @var string The help screen key for the module.
  27. * @since 1.6
  28. */
  29. protected $helpKey = 'JHELP_EXTENSIONS_TEMPLATE_MANAGER_STYLES_EDIT';
  30. /**
  31. * @var string The help screen base URL for the module.
  32. * @since 1.6
  33. */
  34. protected $helpURL;
  35. /**
  36. * Item cache.
  37. */
  38. private $_cache = array();
  39. private $_formCache = array();
  40. /**
  41. * Method to auto-populate the model state.
  42. *
  43. * Note. Calling getState in this method will result in recursion.
  44. *
  45. * @since 1.6
  46. */
  47. protected function populateState()
  48. {
  49. $app = JFactory::getApplication('administrator');
  50. // Load the User state.
  51. $pk = (int) JRequest::getInt('id');
  52. $this->setState('template.id', $pk);
  53. // Load the parameters.
  54. $params = JComponentHelper::getParams('com_gantry');
  55. $this->setState('params', $params);
  56. }
  57. /**
  58. * Method to get the record form.
  59. *
  60. * @param array $data An optional array of data for the form to interogate.
  61. * @param boolean $loadData True if the form is to load its own data (default case), false if not.
  62. * @return JForm A JForm object on success, false on failure
  63. * @since 1.6
  64. */
  65. public function getForm($data = array(), $loadData = true)
  66. {
  67. // Initialise variables.
  68. $app = JFactory::getApplication();
  69. // The folder and element vars are passed when saving the form.
  70. if (empty($data)) {
  71. $item = $this->getItem();
  72. $clientId = $item->client_id;
  73. $template = $item->template;
  74. }
  75. else {
  76. $clientId = JArrayHelper::getValue($data, 'client_id');
  77. $template = JArrayHelper::getValue($data, 'template');
  78. }
  79. // These variables are used to add data from the plugin XML files.
  80. $this->setState('item.client_id', $clientId);
  81. $this->setState('item.template', $template);
  82. // Get the form.
  83. $form = $this->loadForm('com_gantry.template', 'template', array('control' => 'jform', 'load_data' => $loadData));
  84. if (empty($form)) {
  85. return false;
  86. }
  87. // Modify the form based on access controls.
  88. if (!$this->canEditState((object) $data)) {
  89. // Disable fields for display.
  90. $form->setFieldAttribute('home', 'disabled', 'true');
  91. // Disable fields while saving.
  92. // The controller has already verified this is a record you can edit.
  93. $form->setFieldAttribute('home', 'filter', 'unset');
  94. }
  95. return $form;
  96. }
  97. public function getGantryForm(){
  98. gantry_import('core.config.gantryform');
  99. gantry_import('core.config.gantryformnaminghelper');
  100. $pk = (!empty($pk)) ? $pk : (int) $this->getState('template.id');
  101. $item = $this->getItem($pk);
  102. $item->params['current_id']= $pk;
  103. if (!isset($this->_formCache[$pk])) {
  104. $form = GantryForm::getInstance(GantryFormNamingHelper::getInstance(), 'template-options', 'template-options', array(), true, "//form");
  105. $form->bind($item->params);
  106. $this->_formCache[$pk] = $form;
  107. }
  108. return $this->_formCache[$pk];
  109. }
  110. public function checkForGantryUpdate()
  111. {
  112. gantry_import('core.gantryupdates');
  113. $gantry_updates = GantryUpdates::getInstance();
  114. $last_updated = $gantry_updates->getLastUpdated();
  115. $diff = time() - $last_updated;
  116. if ($diff > (60*60*24)){
  117. jimport('joomla.updater.updater');
  118. // check for update
  119. $updater = JUpdater::getInstance();
  120. $results = @$updater->findUpdates($gantry_updates->getGantryExtensionId());
  121. $gantry_updates->setLastChecked(time());
  122. }
  123. }
  124. /**
  125. * Method to get the data that should be injected in the form.
  126. *
  127. * @return mixed The data for the form.
  128. * @since 1.6
  129. */
  130. protected function loadFormData()
  131. {
  132. // Check the session for previously entered form data.
  133. $data = JFactory::getApplication()->getUserState('com_templates.edit.style.data', array());
  134. if (empty($data)) {
  135. $data = $this->getItem();
  136. }
  137. return $data;
  138. }
  139. /**
  140. * Method to get a single record.
  141. *
  142. * @param integer The id of the primary key.
  143. *
  144. * @return mixed Object on success, false on failure.
  145. */
  146. public function &getItem($pk = null)
  147. {
  148. // Initialise variables.
  149. $pk = (!empty($pk)) ? $pk : (int) $this->getState('template.id');
  150. if (!isset($this->_cache[$pk])) {
  151. $false = false;
  152. // Get a row instance.
  153. $table = $this->getTable();
  154. // Attempt to load the row.
  155. $return = $table->load($pk);
  156. // Check for a table object error.
  157. if ($return === false && $table->getError()) {
  158. $this->setError($table->getError());
  159. return $false;
  160. }
  161. // Convert to the JObject before adding other data.
  162. $this->_cache[$pk] = JArrayHelper::toObject($table->getProperties(1), 'JObject');
  163. // Convert the params field to an array.
  164. $registry = new JRegistry;
  165. $registry->loadString($table->params);
  166. $item_params = $registry->toArray();
  167. if (array_key_exists('master', $item_params) && $item_params['master'] != 'true'){
  168. $master_params = $this->getItem((int)$item_params['master'])->params;
  169. $item_params = $this->array_join($master_params, $item_params);
  170. }
  171. $this->_cache[$pk]->params = $item_params;
  172. }
  173. return $this->_cache[$pk];
  174. }
  175. public function getOverride($pk = null){
  176. $pk = (!empty($pk)) ? $pk : (int) $this->getState('template.id');
  177. $params = $this->getItem($pk)->params;
  178. if (array_key_exists('master', $params) && $params['master'] != 'true'){
  179. return true;
  180. }
  181. return false;
  182. }
  183. public function getBaseData($pk = null){
  184. $pk = (!empty($pk)) ? $pk : (int) $this->getState('template.id');
  185. $params = $this->getItem($pk)->params;
  186. if ($params->get('master') != 'true'){
  187. $params = $this->getItem($params->get('master'));
  188. }
  189. return $params;
  190. }
  191. /**
  192. * Returns a reference to the a Table object, always creating it.
  193. *
  194. * @param type The table type to instantiate
  195. * @param string A prefix for the table class name. Optional.
  196. * @param array Configuration array for model. Optional.
  197. * @return JTable A database object
  198. */
  199. public function getTable($type = 'Style', $prefix = 'TemplatesTable', $config = array())
  200. {
  201. JTable::addIncludePath(JPATH_ADMINISTRATOR.'/components/com_templates/tables');
  202. return JTable::getInstance($type, $prefix, $config);
  203. }
  204. /**
  205. * Prepare and sanitise the table prior to saving.
  206. */
  207. protected function prepareTable(&$table)
  208. {
  209. $table;
  210. }
  211. /**
  212. * @param object A form object.
  213. * @param mixed The data expected for the form.
  214. * @throws Exception if there is an error in the form event.
  215. * @since 1.6
  216. */
  217. protected function preprocessForm($form, $data, $group = 'content')
  218. {
  219. // Initialise variables.
  220. $clientId = $this->getState('item.client_id');
  221. $template = $this->getState('item.template');
  222. $lang = JFactory::getLanguage();
  223. $client = JApplicationHelper::getClientInfo($clientId);
  224. if (!$form->loadFile('template_'.$client->name, true)) {
  225. throw new Exception(JText::_('JERROR_LOADFILE_FAILED'));
  226. }
  227. jimport('joomla.filesystem.file');
  228. jimport('joomla.filesystem.folder');
  229. $formFile = JPath::clean($client->path.'/templates/'.$template.'/templateDetails.xml');
  230. // Load the core and/or local language file(s).
  231. $lang->load('tpl_'.$template, $client->path, null, false, false)
  232. || $lang->load('tpl_'.$template, $client->path.'/templates/'.$template, null, false, false)
  233. || $lang->load('tpl_'.$template, $client->path, $lang->getDefault(), false, false)
  234. || $lang->load('tpl_'.$template, $client->path.'/templates/'.$template, $lang->getDefault(), false, false);
  235. if (file_exists($formFile)) {
  236. // Get the template form.
  237. if (!$form->loadFile($formFile, false, '//config')) {
  238. throw new Exception(JText::_('JERROR_LOADFILE_FAILED'));
  239. }
  240. }
  241. // Disable home field if it is default style
  242. if ((is_array($data) && array_key_exists('home',$data))
  243. || ((is_object($data) && $data->home))){
  244. $form->setFieldAttribute('home','readonly','true');
  245. }
  246. // Attempt to load the xml file.
  247. if (!$xml = simplexml_load_file($formFile)) {
  248. throw new Exception(JText::_('JERROR_LOADFILE_FAILED'));
  249. }
  250. // Get the help data from the XML file if present.
  251. $help = $xml->xpath('/extension/help');
  252. if (!empty($help)) {
  253. $helpKey = trim((string) $help[0]['key']);
  254. $helpURL = trim((string) $help[0]['url']);
  255. $this->helpKey = $helpKey ? $helpKey : $this->helpKey;
  256. $this->helpURL = $helpURL ? $helpURL : $this->helpURL;
  257. }
  258. // Trigger the default form events.
  259. parent::preprocessForm($form, $data, $group);
  260. }
  261. /**
  262. * Method to save the form data.
  263. *
  264. * @param array The form data.
  265. * @return boolean True on success.
  266. */
  267. public function save($data)
  268. {
  269. // Initialise variables;
  270. $dispatcher = JDispatcher::getInstance();
  271. $table = $this->getTable();
  272. $pk = (!empty($data['id'])) ? $data['id'] : (int)$this->getState('template.id');
  273. $isNew = true;
  274. // Include the extension plugins for the save events.
  275. JPluginHelper::importPlugin('extension');
  276. // Load the row if saving an existing record.
  277. if ($pk > 0) {
  278. $table->load($pk);
  279. $isNew = false;
  280. }
  281. if (!array_key_exists('home',$data)){
  282. $data['home'] = 0;
  283. }
  284. // see if its a override and set params to only different data
  285. if (array_key_exists('master',$data['params']) && $data['params']['master'] != 'true'){
  286. $master_params = $this->getItem($data['params']['master'])->params;
  287. $data['params'] = $this->array_diff($data['params'],$master_params );
  288. }
  289. // Bind the data.
  290. if (!$table->bind($data)) {
  291. $this->setError($table->getError());
  292. return false;
  293. }
  294. // Prepare the row for saving
  295. $this->prepareTable($table);
  296. // Check the data.
  297. if (!$table->check()) {
  298. $this->setError($table->getError());
  299. return false;
  300. }
  301. // Trigger the onExtensionBeforeSave event.
  302. $result = $dispatcher->trigger('onExtensionBeforeSave', array('com_templates.style', &$table, $isNew));
  303. if (in_array(false, $result, true)) {
  304. $this->setError($table->getError());
  305. return false;
  306. }
  307. // Store the data.
  308. if (!$table->store()) {
  309. $this->setError($table->getError());
  310. return false;
  311. }
  312. $user = JFactory::getUser();
  313. if ($user->authorise('core.edit','com_menus') && $table->client_id==0) {
  314. $n = 0;
  315. $db = JFactory::getDbo();
  316. $user = JFactory::getUser();
  317. if (empty($data['assigned']) || $data['assigned'] !== false){
  318. if (!empty($data['assigned']))
  319. {
  320. JArrayHelper::toInteger($data['assigned']);
  321. // Update the mapping for menu items that this style IS assigned to.
  322. $query = $db->getQuery(true);
  323. $query->update('#__menu');
  324. $query->set('template_style_id=' . (int)$table->id);
  325. $query->where('id IN (' . implode(',', $data['assigned']) . ')');
  326. $query->where('template_style_id!=' . (int)$table->id);
  327. $query->where('checked_out in (0,' . (int)$user->id . ')');
  328. $db->setQuery($query);
  329. $db->query();
  330. $n += $db->getAffectedRows();
  331. }
  332. // Remove style mappings for menu items this style is NOT assigned to.
  333. // If unassigned then all existing maps will be removed.
  334. $query = $db->getQuery(true);
  335. $query->update('#__menu');
  336. $query->set('template_style_id=0');
  337. if (!empty($data['assigned'])) {
  338. $query->where('id NOT IN ('.implode(',', $data['assigned']).')');
  339. }
  340. $query->where('template_style_id='.(int) $table->id);
  341. $query->where('checked_out in (0,'.(int) $user->id.')');
  342. $db->setQuery($query);
  343. $db->query();
  344. $n += $db->getAffectedRows();
  345. if ($n > 0) {
  346. $app =& JFactory::getApplication();
  347. $app->enQueueMessage(JText::plural('COM_TEMPLATES_MENU_CHANGED',$n));
  348. }
  349. }
  350. }
  351. // Clean the cache.
  352. $cache = JFactory::getCache();
  353. $cache->clean();
  354. // Trigger the onExtensionAfterSave event.
  355. $dispatcher->trigger('onExtensionAfterSave', array('com_templates.style', &$table, $isNew));
  356. $this->setState('template.id', $table->id);
  357. return true;
  358. }
  359. /**
  360. * Get the necessary data to load an item help screen.
  361. *
  362. * @return object An object with key, url, and local properties for loading the item help screen.
  363. * @since 1.6
  364. */
  365. public function getHelp()
  366. {
  367. return (object) array('key' => $this->helpKey, 'url' => $this->helpURL);
  368. }
  369. /**
  370. * Method to get a form object.
  371. *
  372. * @param string $name The name of the form.
  373. * @param string $source The form source. Can be XML string if file flag is set to false.
  374. * @param array $options Optional array of options for the form creation.
  375. * @param boolean $clear Optional argument to force load a new form.
  376. * @param string $xpath An optional xpath to search for the fields.
  377. * @return mixed JForm object on success, False on error.
  378. */
  379. protected function loadForm($name, $source = null, $options = array(), $clear = false, $xpath = false)
  380. {
  381. // Handle the optional arguments.
  382. $options['control'] = JArrayHelper::getValue($options, 'control', false);
  383. // Create a signature hash.
  384. $hash = md5($source.serialize($options));
  385. // Check if we can use a previously loaded form.
  386. if (isset($this->_forms[$hash]) && !$clear) {
  387. return $this->_forms[$hash];
  388. }
  389. // Get the form.
  390. JForm::addFormPath(JPATH_COMPONENT.'/models/forms');
  391. JForm::addFieldPath(JPATH_COMPONENT.'/models/fields');
  392. try {
  393. $form = JForm::getInstance($name, $source, $options, false, $xpath);
  394. if (isset($options['load_data']) && $options['load_data']) {
  395. // Get the data for the form.
  396. $data = $this->loadFormData();
  397. } else {
  398. $data = array();
  399. }
  400. // Allow for additional modification of the form, and events to be triggered.
  401. // We pass the data because plugins may require it.
  402. $this->preprocessForm($form, $data);
  403. // Load the data into the form after the plugins have operated.
  404. $form->bind($data);
  405. } catch (Exception $e) {
  406. $this->setError($e->getMessage());
  407. return false;
  408. }
  409. // Store the form for later.
  410. $this->_forms[$hash] = $form;
  411. return $form;
  412. }
  413. protected function array_join()
  414. {
  415. // Get array arguments
  416. $arrays = func_get_args();
  417. // Define the original array
  418. $original = array_shift($arrays);
  419. // Loop through arrays
  420. foreach ($arrays as $array)
  421. {
  422. // Loop through array key/value pairs
  423. foreach ($array as $key => $value)
  424. {
  425. // Value is an array
  426. if (is_array($value))
  427. {
  428. // Traverse the array; replace or add result to original array
  429. @$original[$key] = $this->array_join($original[$key], $array[$key]);
  430. }
  431. // Value is not an array
  432. else
  433. {
  434. // Replace or add current value to original array
  435. @$original[$key] = $value;
  436. }
  437. }
  438. }
  439. // Return the joined array
  440. return $original;
  441. }
  442. protected function array_diff($aArray1, $aArray2)
  443. {
  444. $aReturn = array();
  445. foreach ($aArray1 as $mKey => $mValue)
  446. {
  447. if (array_key_exists($mKey, $aArray2))
  448. {
  449. if (is_array($mValue))
  450. {
  451. $aRecursiveDiff = $this->array_diff($mValue, $aArray2[$mKey]);
  452. if (count($aRecursiveDiff))
  453. {
  454. $aReturn[$mKey] = $aRecursiveDiff;
  455. }
  456. } else
  457. {
  458. if ($mValue != $aArray2[$mKey])
  459. {
  460. $aReturn[$mKey] = $mValue;
  461. }
  462. }
  463. } else
  464. {
  465. $aReturn[$mKey] = $mValue;
  466. }
  467. }
  468. return $aReturn;
  469. }
  470. /**
  471. * Method to duplicate styles.
  472. *
  473. * @param array An array of primary key IDs.
  474. *
  475. * @return boolean True if successful.
  476. * @throws Exception
  477. */
  478. public function duplicate(&$pks)
  479. {
  480. // Initialise variables.
  481. $user = JFactory::getUser();
  482. $db = $this->getDbo();
  483. // Access checks.
  484. if (!$user->authorise('core.create', 'com_templates')) {
  485. throw new Exception(JText::_('JERROR_CORE_CREATE_NOT_PERMITTED'));
  486. }
  487. $table = $this->getTable();
  488. foreach ($pks as $pk)
  489. {
  490. if ($table->load($pk, true)) {
  491. // Reset the id to create a new record.
  492. $table->id = 0;
  493. // Reset the home (don't want dupes of that field).
  494. $table->home = 0;
  495. // Alter the title.
  496. $m = null;
  497. if (preg_match('#\((\d+)\)$#', $table->title, $m)) {
  498. $table->title = preg_replace('#\(\d+\)$#', '('.($m[1] + 1).')', $table->title);
  499. }
  500. else {
  501. $table->title .= ' (2)';
  502. }
  503. if ($this->isGantryTemplate($table)){
  504. $template_params = new JRegistry();
  505. $template_params->loadString($table->params);
  506. if ($template_params->get('master') == 'true'){
  507. $base_params = $template_params->toArray();
  508. $template_params->set('master',$pk);
  509. $copy_params = $template_params->toArray();
  510. $copy_params = $this->array_diff($copy_params, $base_params);
  511. $template_params = new JRegistry();
  512. $template_params->loadArray($copy_params);
  513. }
  514. $table->params = $template_params->toString();
  515. }
  516. if (!$table->check() || !$table->store()) {
  517. throw new Exception($table->getError());
  518. }
  519. }
  520. else {
  521. throw new Exception($table->getError());
  522. }
  523. }
  524. $cache = JFactory::getCache();
  525. $cache->clean('com_templates');
  526. $cache->clean('_system');
  527. return true;
  528. }
  529. /**
  530. * Method to delete rows.
  531. *
  532. * @param array An array of item ids.
  533. *
  534. * @return boolean Returns true on success, false on failure.
  535. */
  536. public function delete(&$pks)
  537. {
  538. // Initialise variables.
  539. $pks = (array) $pks;
  540. $user = JFactory::getUser();
  541. $table = $this->getTable();
  542. $language =& JFactory::getLanguage();
  543. $language->load('com_gantry');
  544. // Iterate the items to delete each one.
  545. foreach ($pks as $i => $pk)
  546. {
  547. if ($table->load($pk)) {
  548. // Access checks.
  549. if (!$user->authorise('core.delete', 'com_templates')) {
  550. throw new Exception(JText::_('JERROR_CORE_DELETE_NOT_PERMITTED'));
  551. }
  552. if ($this->isGantryTemplate($table)){
  553. $template_params = new JRegistry();
  554. $template_params->loadString($table->params);
  555. if ($template_params->get('master') == 'true'){
  556. $this->setError(JText::_('Cannot delete a Gantry Template Master Style'));
  557. return false;
  558. }
  559. }
  560. if (!$table->delete($pk)) {
  561. $this->setError($table->getError());
  562. return false;
  563. }
  564. }
  565. else {
  566. $this->setError($table->getError());
  567. return false;
  568. }
  569. }
  570. $cache = JFactory::getCache();
  571. $cache->clean('com_templates');
  572. $cache->clean('_system');
  573. return true;
  574. }
  575. /**
  576. * Check if template is based on gantry
  577. *
  578. * @param string $id
  579. * @return boolean
  580. */
  581. private function isGantryTemplate($table)
  582. {
  583. $template = $table->template;
  584. return file_exists(JPATH_SITE . DS . 'templates' . DS . $template . DS . 'lib' . DS . 'gantry' . DS . 'gantry.php');
  585. }
  586. }