Source for file style.php

Documentation is available at style.php

  1. <?php
  2. /**
  3.  * @package     Joomla.Administrator
  4.  * @subpackage  com_templates
  5.  *
  6.  * @copyright   Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
  7.  * @license     GNU General Public License version 2 or later; see LICENSE.txt
  8.  */
  9.  
  10. defined('_JEXEC'or die;
  11.  
  12. /**
  13.  * Template style model.
  14.  *
  15.  * @package     Joomla.Administrator
  16.  * @subpackage  com_templates
  17.  * @since       1.6
  18.  */
  19. {
  20.     /**
  21.      * @var        string    The help screen key for the module.
  22.      * @since   1.6
  23.      */
  24.     protected $helpKey = 'JHELP_EXTENSIONS_TEMPLATE_MANAGER_STYLES_EDIT';
  25.  
  26.     /**
  27.      * @var        string    The help screen base URL for the module.
  28.      * @since   1.6
  29.      */
  30.     protected $helpURL;
  31.  
  32.     /**
  33.      * Item cache.
  34.      */
  35.     private $_cache array();
  36.  
  37.     /**
  38.      * Method to auto-populate the model state.
  39.      *
  40.      * Note. Calling getState in this method will result in recursion.
  41.      *
  42.      * @return  void 
  43.      *
  44.      * @since   1.6
  45.      */
  46.     protected function populateState()
  47.     {
  48.         $app JFactory::getApplication('administrator');
  49.  
  50.         // Load the User state.
  51.         $pk $app->input->getInt('id');
  52.         $this->setState('style.id'$pk);
  53.  
  54.         // Load the parameters.
  55.         $params    JComponentHelper::getParams('com_templates');
  56.         $this->setState('params'$params);
  57.     }
  58.  
  59.     /**
  60.      * Method to delete rows.
  61.      *
  62.      * @param   array  &$pks  An array of item ids.
  63.      *
  64.      * @return  boolean  Returns true on success, false on failure.
  65.      */
  66.     public function delete(&$pks)
  67.     {
  68.         $pks    = (array) $pks;
  69.         $user    JFactory::getUser();
  70.         $table    $this->getTable();
  71.  
  72.         // Iterate the items to delete each one.
  73.         foreach ($pks as $pk)
  74.         {
  75.             if ($table->load($pk))
  76.             {
  77.                 // Access checks.
  78.                 if (!$user->authorise('core.delete''com_templates'))
  79.                 {
  80.                     throw new Exception(JText::_('JERROR_CORE_DELETE_NOT_PERMITTED'));
  81.                 }
  82.  
  83.                 // You should not delete a default style
  84.                 if ($table->home != '0')
  85.                 {
  86.                     JError::raiseWarning(SOME_ERROR_NUMBERJtext::_('COM_TEMPLATES_STYLE_CANNOT_DELETE_DEFAULT_STYLE'));
  87.  
  88.                     return false;
  89.                 }
  90.  
  91.                 if (!$table->delete($pk))
  92.                 {
  93.                     $this->setError($table->getError());
  94.  
  95.                     return false;
  96.                 }
  97.             }
  98.             else
  99.             {
  100.                 $this->setError($table->getError());
  101.  
  102.                 return false;
  103.             }
  104.         }
  105.  
  106.         // Clean cache
  107.         $this->cleanCache();
  108.  
  109.         return true;
  110.     }
  111.  
  112.     /**
  113.      * Method to duplicate styles.
  114.      *
  115.      * @param   array  &$pks  An array of primary key IDs.
  116.      *
  117.      * @return  boolean  True if successful.
  118.      *
  119.      * @throws    Exception
  120.      */
  121.     public function duplicate(&$pks)
  122.     {
  123.         $user    JFactory::getUser();
  124.  
  125.         // Access checks.
  126.         if (!$user->authorise('core.create''com_templates'))
  127.         {
  128.             throw new Exception(JText::_('JERROR_CORE_CREATE_NOT_PERMITTED'));
  129.         }
  130.  
  131.         $table $this->getTable();
  132.  
  133.         foreach ($pks as $pk)
  134.         {
  135.             if ($table->load($pktrue))
  136.             {
  137.                 // Reset the id to create a new record.
  138.                 $table->id 0;
  139.  
  140.                 // Reset the home (don't want dupes of that field).
  141.                 $table->home 0;
  142.  
  143.                 // Alter the title.
  144.                 $m null;
  145.                 $table->title $this->generateNewTitle(nullnull$table->title);
  146.  
  147.                 if (!$table->check(|| !$table->store())
  148.                 {
  149.                     throw new Exception($table->getError());
  150.                 }
  151.             }
  152.             else
  153.             {
  154.                 throw new Exception($table->getError());
  155.             }
  156.         }
  157.  
  158.         // Clean cache
  159.         $this->cleanCache();
  160.  
  161.         return true;
  162.     }
  163.  
  164.     /**
  165.      * Method to change the title.
  166.      *
  167.      * @param   integer  $category_id  The id of the category.
  168.      * @param   string   $alias        The alias.
  169.      * @param   string   $title        The title.
  170.      *
  171.      * @return  string  New title.
  172.      *
  173.      * @since   1.7.1
  174.      */
  175.     protected function generateNewTitle($category_id$alias$title)
  176.     {
  177.         // Alter the title
  178.         $table $this->getTable();
  179.  
  180.         while ($table->load(array('title' => $title)))
  181.         {
  182.             $title JString::increment($title);
  183.         }
  184.  
  185.         return $title;
  186.     }
  187.  
  188.     /**
  189.      * Method to get the record form.
  190.      *
  191.      * @param   array    $data      An optional array of data for the form to interogate.
  192.      * @param   boolean  $loadData  True if the form is to load its own data (default case), false if not.
  193.      *
  194.      * @return  JForm  A JForm object on success, false on failure
  195.      *
  196.      * @since   1.6
  197.      */
  198.     public function getForm($data array()$loadData true)
  199.     {
  200.         // The folder and element vars are passed when saving the form.
  201.         if (empty($data))
  202.         {
  203.             $item        $this->getItem();
  204.             $clientId    $item->client_id;
  205.             $template    $item->template;
  206.         }
  207.         else
  208.         {
  209.             $clientId    JArrayHelper::getValue($data'client_id');
  210.             $template    JArrayHelper::getValue($data'template');
  211.         }
  212.  
  213.         // These variables are used to add data from the plugin XML files.
  214.         $this->setState('item.client_id',    $clientId);
  215.         $this->setState('item.template',    $template);
  216.  
  217.         // Get the form.
  218.         $form $this->loadForm('com_templates.style''style'array('control' => 'jform''load_data' => $loadData));
  219.  
  220.         if (empty($form))
  221.         {
  222.             return false;
  223.         }
  224.  
  225.         // Modify the form based on access controls.
  226.         if (!$this->canEditState((object) $data))
  227.         {
  228.             // Disable fields for display.
  229.             $form->setFieldAttribute('home''disabled''true');
  230.  
  231.             // Disable fields while saving.
  232.             // The controller has already verified this is a record you can edit.
  233.             $form->setFieldAttribute('home''filter''unset');
  234.         }
  235.  
  236.         return $form;
  237.     }
  238.  
  239.     /**
  240.      * Method to get the data that should be injected in the form.
  241.      *
  242.      * @return  mixed  The data for the form.
  243.      *
  244.      * @since   1.6
  245.      */
  246.     protected function loadFormData()
  247.     {
  248.         // Check the session for previously entered form data.
  249.         $data JFactory::getApplication()->getUserState('com_templates.edit.style.data'array());
  250.  
  251.         if (empty($data))
  252.         {
  253.             $data $this->getItem();
  254.         }
  255.  
  256.         $this->preprocessData('com_templates.style'$data);
  257.  
  258.         return $data;
  259.     }
  260.  
  261.     /**
  262.      * Method to get a single record.
  263.      *
  264.      * @param   integer  $pk  The id of the primary key.
  265.      *
  266.      * @return  mixed  Object on success, false on failure.
  267.      */
  268.     public function getItem($pk null)
  269.     {
  270.         $pk (!empty($pk)) $pk : (int) $this->getState('style.id');
  271.  
  272.         if (!isset($this->_cache[$pk]))
  273.         {
  274.             $false    false;
  275.  
  276.             // Get a row instance.
  277.             $table $this->getTable();
  278.  
  279.             // Attempt to load the row.
  280.             $return $table->load($pk);
  281.  
  282.             // Check for a table object error.
  283.             if ($return === false && $table->getError())
  284.             {
  285.                 $this->setError($table->getError());
  286.  
  287.                 return $false;
  288.             }
  289.  
  290.             // Convert to the JObject before adding other data.
  291.             $properties $table->getProperties(1);
  292.             $this->_cache[$pkJArrayHelper::toObject($properties'JObject');
  293.  
  294.             // Convert the params field to an array.
  295.             $registry new JRegistry;
  296.             $registry->loadString($table->params);
  297.             $this->_cache[$pk]->params $registry->toArray();
  298.  
  299.             // Get the template XML.
  300.             $client    JApplicationHelper::getClientInfo($table->client_id);
  301.             $path    JPath::clean($client->path.'/templates/'.$table->template.'/templateDetails.xml');
  302.  
  303.             if (file_exists($path))
  304.             {
  305.                 $this->_cache[$pk]->xml simplexml_load_file($path);
  306.             }
  307.             else
  308.             {
  309.                 $this->_cache[$pk]->xml null;
  310.             }
  311.         }
  312.  
  313.         return $this->_cache[$pk];
  314.     }
  315.  
  316.     /**
  317.      * Returns a reference to the a Table object, always creating it.
  318.      *
  319.      * @param   type    $type    The table type to instantiate
  320.      * @param   string  $prefix  A prefix for the table class name. Optional.
  321.      * @param   array   $config  Configuration array for model. Optional.
  322.      *
  323.      * @return  JTable  A database object
  324.     */
  325.     public function getTable($type 'Style'$prefix 'TemplatesTable'$config array())
  326.     {
  327.         return JTable::getInstance($type$prefix$config);
  328.     }
  329.  
  330.     /**
  331.      * TODO
  332.      *
  333.      * @param   object  $form   A form object.
  334.      * @param   mixed   $data   The data expected for the form.
  335.      * @param   string  $group  TODO
  336.      *
  337.      * @return  void 
  338.      *
  339.      * @since   1.6
  340.      * @throws    Exception if there is an error in the form event.
  341.      */
  342.     protected function preprocessForm(JForm $form$data$group 'content')
  343.     {
  344.         $clientId $this->getState('item.client_id');
  345.         $template $this->getState('item.template');
  346.         $lang     JFactory::getLanguage();
  347.         $client   JApplicationHelper::getClientInfo($clientId);
  348.  
  349.         if (!$form->loadFile('style_'.$client->nametrue))
  350.         {
  351.             throw new Exception(JText::_('JERROR_LOADFILE_FAILED'));
  352.         }
  353.  
  354.         jimport('joomla.filesystem.path');
  355.  
  356.         $formFile    JPath::clean($client->path.'/templates/'.$template.'/templateDetails.xml');
  357.  
  358.         // Load the core and/or local language file(s).
  359.             $lang->load('tpl_'.$template$client->pathnullfalsetrue)
  360.         ||    $lang->load('tpl_'.$template$client->path.'/templates/'.$templatenullfalsetrue);
  361.  
  362.         if (file_exists($formFile))
  363.         {
  364.             // Get the template form.
  365.             if (!$form->loadFile($formFilefalse'//config'))
  366.             {
  367.                 throw new Exception(JText::_('JERROR_LOADFILE_FAILED'));
  368.             }
  369.         }
  370.  
  371.         // Disable home field if it is default style
  372.  
  373.         if ((is_array($data&& array_key_exists('home'$data&& $data['home'== '1')
  374.             || ((is_object($data&& isset($data->home&& $data->home == '1')))
  375.         {
  376.             $form->setFieldAttribute('home''readonly''true');
  377.         }
  378.  
  379.         // Attempt to load the xml file.
  380.         if (!$xml simplexml_load_file($formFile))
  381.         {
  382.             throw new Exception(JText::_('JERROR_LOADFILE_FAILED'));
  383.         }
  384.  
  385.         // Get the help data from the XML file if present.
  386.         $help $xml->xpath('/extension/help');
  387.  
  388.         if (!empty($help))
  389.         {
  390.             $helpKey trim((string) $help[0]['key']);
  391.             $helpURL trim((string) $help[0]['url']);
  392.  
  393.             $this->helpKey = $helpKey $helpKey $this->helpKey;
  394.             $this->helpURL = $helpURL $helpURL $this->helpURL;
  395.         }
  396.  
  397.         // Trigger the default form events.
  398.         parent::preprocessForm($form$data$group);
  399.     }
  400.  
  401.     /**
  402.      * Method to save the form data.
  403.      *
  404.      * @param   array  $data  The form data.
  405.      *
  406.      * @return  boolean  True on success.
  407.      */
  408.     public function save($data)
  409.     {
  410.         // Detect disabled extension
  411.         $extension JTable::getInstance('Extension');
  412.  
  413.         if ($extension->load(array('enabled' => 0'type' => 'template''element' => $data['template']'client_id' => $data['client_id'])))
  414.         {
  415.             $this->setError(JText::_('COM_TEMPLATES_ERROR_SAVE_DISABLED_TEMPLATE'));
  416.  
  417.             return false;
  418.         }
  419.  
  420.         $app        JFactory::getApplication();
  421.         $dispatcher JEventDispatcher::getInstance();
  422.         $table      $this->getTable();
  423.         $pk         (!empty($data['id'])) $data['id': (int) $this->getState('style.id');
  424.         $isNew      true;
  425.  
  426.         // Include the extension plugins for the save events.
  427.         JPluginHelper::importPlugin('extension');
  428.  
  429.         // Load the row if saving an existing record.
  430.         if ($pk 0)
  431.         {
  432.             $table->load($pk);
  433.             $isNew false;
  434.         }
  435.  
  436.         if ($app->input->get('task'== 'save2copy')
  437.         {
  438.             $data['title'$this->generateNewTitle(nullnull$data['title']);
  439.             $data['home'0;
  440.             $data['assigned''';
  441.         }
  442.  
  443.         // Bind the data.
  444.         if (!$table->bind($data))
  445.         {
  446.             $this->setError($table->getError());
  447.  
  448.             return false;
  449.         }
  450.  
  451.         // Prepare the row for saving
  452.         $this->prepareTable($table);
  453.  
  454.         // Check the data.
  455.         if (!$table->check())
  456.         {
  457.             $this->setError($table->getError());
  458.  
  459.             return false;
  460.         }
  461.  
  462.         // Trigger the onExtensionBeforeSave event.
  463.         $result $dispatcher->trigger('onExtensionBeforeSave'array('com_templates.style'&$table$isNew));
  464.  
  465.         if (in_array(false$resulttrue))
  466.         {
  467.             $this->setError($table->getError());
  468.  
  469.             return false;
  470.         }
  471.  
  472.         // Store the data.
  473.         if (!$table->store())
  474.         {
  475.             $this->setError($table->getError());
  476.  
  477.             return false;
  478.         }
  479.  
  480.         $user JFactory::getUser();
  481.  
  482.         if ($user->authorise('core.edit''com_menus'&& $table->client_id == 0)
  483.         {
  484.             $n    0;
  485.             $db   JFactory::getDbo();
  486.             $user JFactory::getUser();
  487.  
  488.             if (!empty($data['assigned']&& is_array($data['assigned']))
  489.             {
  490.                 JArrayHelper::toInteger($data['assigned']);
  491.  
  492.                 // Update the mapping for menu items that this style IS assigned to.
  493.                 $query $db->getQuery(true)
  494.                     ->update('#__menu')
  495.                     ->set('template_style_id = ' . (int) $table->id)
  496.                     ->where('id IN (' implode(','$data['assigned']')')
  497.                     ->where('template_style_id != ' . (int) $table->id)
  498.                     ->where('checked_out IN (0,' . (int) $user->id ')');
  499.                 $db->setQuery($query);
  500.                 $db->execute();
  501.                 $n += $db->getAffectedRows();
  502.             }
  503.  
  504.             // Remove style mappings for menu items this style is NOT assigned to.
  505.             // If unassigned then all existing maps will be removed.
  506.             $query $db->getQuery(true)
  507.                 ->update('#__menu')
  508.                 ->set('template_style_id = 0');
  509.  
  510.             if (!empty($data['assigned']))
  511.             {
  512.                 $query->where('id NOT IN (' implode(','$data['assigned']')');
  513.             }
  514.  
  515.             $query->where('template_style_id = ' . (int) $table->id)
  516.                 ->where('checked_out IN (0,' . (int) $user->id ')');
  517.             $db->setQuery($query);
  518.             $db->execute();
  519.  
  520.             $n += $db->getAffectedRows();
  521.  
  522.             if ($n 0)
  523.             {
  524.                 $app->enQueueMessage(JText::plural('COM_TEMPLATES_MENU_CHANGED'$n));
  525.             }
  526.         }
  527.  
  528.         // Clean the cache.
  529.         $this->cleanCache();
  530.  
  531.         // Trigger the onExtensionAfterSave event.
  532.         $dispatcher->trigger('onExtensionAfterSave'array('com_templates.style'&$table$isNew));
  533.  
  534.         $this->setState('style.id'$table->id);
  535.  
  536.         return true;
  537.     }
  538.  
  539.     /**
  540.      * Method to set a template style as home.
  541.      *
  542.      * @param   integer  $id  The primary key ID for the style.
  543.      *
  544.      * @return  boolean  True if successful.
  545.      *
  546.      * @throws    Exception
  547.      */
  548.     public function setHome($id 0)
  549.     {
  550.         $user JFactory::getUser();
  551.         $db   $this->getDbo();
  552.  
  553.         // Access checks.
  554.         if (!$user->authorise('core.edit.state''com_templates'))
  555.         {
  556.             throw new Exception(JText::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED'));
  557.         }
  558.  
  559.         $style JTable::getInstance('Style''TemplatesTable');
  560.  
  561.         if (!$style->load((int) $id))
  562.         {
  563.             throw new Exception(JText::_('COM_TEMPLATES_ERROR_STYLE_NOT_FOUND'));
  564.         }
  565.  
  566.         // Detect disabled extension
  567.         $extension JTable::getInstance('Extension');
  568.  
  569.         if ($extension->load(array('enabled' => 0'type' => 'template''element' => $style->template'client_id' => $style->client_id)))
  570.         {
  571.             throw new Exception(JText::_('COM_TEMPLATES_ERROR_SAVE_DISABLED_TEMPLATE'));
  572.         }
  573.  
  574.         // Reset the home fields for the client_id.
  575.         $db->setQuery(
  576.             'UPDATE #__template_styles' .
  577.             ' SET home = \'0\'' .
  578.             ' WHERE client_id = ' . (int) $style->client_id .
  579.             ' AND home = \'1\''
  580.         );
  581.         $db->execute();
  582.  
  583.         // Set the new home style.
  584.         $db->setQuery(
  585.             'UPDATE #__template_styles' .
  586.             ' SET home = \'1\'' .
  587.             ' WHERE id = ' . (int) $id
  588.         );
  589.         $db->execute();
  590.  
  591.         // Clean the cache.
  592.         $this->cleanCache();
  593.  
  594.         return true;
  595.     }
  596.  
  597.     /**
  598.      * Method to unset a template style as default for a language.
  599.      *
  600.      * @param   integer  $id  The primary key ID for the style.
  601.      *
  602.      * @return  boolean  True if successful.
  603.      *
  604.      * @throws    Exception
  605.      */
  606.     public function unsetHome($id 0)
  607.     {
  608.         $user JFactory::getUser();
  609.         $db   $this->getDbo();
  610.  
  611.         // Access checks.
  612.         if (!$user->authorise('core.edit.state''com_templates'))
  613.         {
  614.             throw new Exception(JText::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED'));
  615.         }
  616.  
  617.         // Lookup the client_id.
  618.         $db->setQuery(
  619.             'SELECT client_id, home' .
  620.             ' FROM #__template_styles' .
  621.             ' WHERE id = ' . (int) $id
  622.         );
  623.         $style $db->loadObject();
  624.  
  625.         if (!is_numeric($style->client_id))
  626.         {
  627.             throw new Exception(JText::_('COM_TEMPLATES_ERROR_STYLE_NOT_FOUND'));
  628.         }
  629.         elseif ($style->home == '1')
  630.         {
  631.             throw new Exception(JText::_('COM_TEMPLATES_ERROR_CANNOT_UNSET_DEFAULT_STYLE'));
  632.         }
  633.  
  634.         // Set the new home style.
  635.         $db->setQuery(
  636.             'UPDATE #__template_styles' .
  637.             ' SET home = \'0\'' .
  638.             ' WHERE id = ' . (int) $id
  639.         );
  640.         $db->execute();
  641.  
  642.         // Clean the cache.
  643.         $this->cleanCache();
  644.  
  645.         return true;
  646.     }
  647.  
  648.     /**
  649.      * Get the necessary data to load an item help screen.
  650.      *
  651.      * @return  object  An object with key, url, and local properties for loading the item help screen.
  652.      *
  653.      * @since   1.6
  654.      */
  655.     public function getHelp()
  656.     {
  657.         return (object) array('key' => $this->helpKey'url' => $this->helpURL);
  658.     }
  659.  
  660.     /**
  661.      * Custom clean cache method
  662.      *
  663.      * @param   string   $group      The cache group
  664.      * @param   integer  $client_id  The ID of the client
  665.      *
  666.      * @return  void 
  667.      *
  668.      * @since   1.6
  669.      */
  670.     protected function cleanCache($group null$client_id 0)
  671.     {
  672.         parent::cleanCache('com_templates');
  673.         parent::cleanCache('_system');
  674.     }
  675. }

Documentation generated on Tue, 19 Nov 2013 15:14:40 +0100 by phpDocumentor 1.4.3