Source for file template.php

Documentation is available at template.php

  1. <?php
  2. /**
  3.  * @package     Joomla.Libraries
  4.  * @subpackage  Installer
  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
  8.  */
  9.  
  10. defined('JPATH_PLATFORM'or die;
  11.  
  12. jimport('joomla.base.adapterinstance');
  13. jimport('joomla.filesystem.folder');
  14.  
  15. /**
  16.  * Template installer
  17.  *
  18.  * @package     Joomla.Libraries
  19.  * @subpackage  Installer
  20.  * @since       3.1
  21.  */
  22. {
  23.     /**
  24.      * Copy of the XML manifest file
  25.      *
  26.      * @var    string 
  27.      * @since  3.1
  28.      */
  29.     protected $manifest = null;
  30.  
  31.     /**
  32.      * Name of the extension
  33.      *
  34.      * @var    string 
  35.      * @since  3.1
  36.      *  */
  37.     protected $name = null;
  38.  
  39.     /**
  40.      * The unique identifier for the extension (e.g. mod_login)
  41.      *
  42.      * @var    string 
  43.      * @since  3.1
  44.      *  */
  45.     protected $element = null;
  46.  
  47.     /**
  48.      * Method of system
  49.      *
  50.      * @var    string 
  51.      *
  52.      * @since  3.1
  53.      */
  54.     protected $route = 'install';
  55.  
  56.     /**
  57.      * Custom loadLanguage method
  58.      *
  59.      * @param   string  $path  The path where to find language files.
  60.      *
  61.      * @return  JInstallerTemplate 
  62.      *
  63.      * @since   3.1
  64.      */
  65.     public function loadLanguage($path null)
  66.     {
  67.         $source $this->parent->getPath('source');
  68.  
  69.         if (!$source)
  70.         {
  71.             $this->parent
  72.                 ->setPath(
  73.                 'source',
  74.                 ($this->parent->extension->client_id JPATH_ADMINISTRATOR JPATH_SITE'/templates/' $this->parent->extension->element
  75.             );
  76.         }
  77.  
  78.         $this->manifest = $this->parent->getManifest();
  79.         $name strtolower(JFilterInput::getInstance()->clean((string) $this->manifest->name'cmd'));
  80.         $client = (string) $this->manifest->attributes()->client;
  81.  
  82.         // Load administrator language if not set.
  83.         if (!$client)
  84.         {
  85.             $client 'ADMINISTRATOR';
  86.         }
  87.  
  88.         $extension "tpl_$name";
  89.         $lang JFactory::getLanguage();
  90.         $source $path $path ($this->parent->extension->client_id JPATH_ADMINISTRATOR JPATH_SITE'/templates/' $name;
  91.         $lang->load($extension '.sys'$sourcenullfalsetrue)
  92.             || $lang->load($extension '.sys'constant('JPATH_' strtoupper($client))nullfalsetrue);
  93.     }
  94.  
  95.     /**
  96.      * Custom install method
  97.      *
  98.      * @return  boolean  True on success
  99.      *
  100.      * @since   3.1
  101.      */
  102.     public function install()
  103.     {
  104.         // Get a database connector object
  105.         $db $this->parent->getDbo();
  106.  
  107.         $lang JFactory::getLanguage();
  108.         $xml $this->parent->getManifest();
  109.  
  110.         // Get the client application target
  111.         if ($cname = (string) $xml->attributes()->client)
  112.         {
  113.             // Attempt to map the client to a base path
  114.             $client JApplicationHelper::getClientInfo($cnametrue);
  115.  
  116.             if ($client === false)
  117.             {
  118.                 $this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT_TPL_INSTALL_UNKNOWN_CLIENT'$cname));
  119.  
  120.                 return false;
  121.             }
  122.             $basePath $client->path;
  123.             $clientId $client->id;
  124.         }
  125.         else
  126.         {
  127.             // No client attribute was found so we assume the site as the client
  128.             $basePath JPATH_SITE;
  129.             $clientId 0;
  130.         }
  131.  
  132.         // Set the extension's name
  133.         $name JFilterInput::getInstance()->clean((string) $xml->name'cmd');
  134.  
  135.         $element strtolower(str_replace(" ""_"$name));
  136.         $this->set('name'$name);
  137.         $this->set('element'$element);
  138.  
  139.         // Check to see if a template by the same name is already installed.
  140.         $query $db->getQuery(true)
  141.             ->select($db->quoteName('extension_id'))
  142.             ->from($db->quoteName('#__extensions'))
  143.             ->where($db->quoteName('type'' = ' $db->quote('template'))
  144.             ->where($db->quoteName('element'' = ' $db->quote($element));
  145.         $db->setQuery($query);
  146.  
  147.         try
  148.         {
  149.             $id $db->loadResult();
  150.         }
  151.         catch (RuntimeException $e)
  152.         {
  153.             // Install failed, roll back changes
  154.             $this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT_TPL_INSTALL_ROLLBACK')$e->getMessage());
  155.  
  156.             return false;
  157.         }
  158.  
  159.         // Set the template root path
  160.         $this->parent->setPath('extension_root'$basePath '/templates/' $element);
  161.  
  162.         // If it's on the fs...
  163.         if (file_exists($this->parent->getPath('extension_root')) && (!$this->parent->isOverwrite(|| $this->parent->isUpgrade()))
  164.         {
  165.             $updateElement $xml->update;
  166.  
  167.             // Upgrade manually set or update tag detected
  168.             if ($this->parent->isUpgrade(|| $updateElement)
  169.             {
  170.                 // Force this one
  171.                 $this->parent->setOverwrite(true);
  172.                 $this->parent->setUpgrade(true);
  173.  
  174.                 if ($id)
  175.                 {
  176.                     // If there is a matching extension mark this as an update; semantics really
  177.                     $this->route = 'update';
  178.                 }
  179.             }
  180.             elseif (!$this->parent->isOverwrite())
  181.             {
  182.                 // Overwrite is not set
  183.                 // If we didn't have overwrite set, find an update function or find an update tag so let's call it safe
  184.                 $this->parent
  185.                     ->abort(
  186.                     JText::sprintf(
  187.                         'JLIB_INSTALLER_ABORT_TPL_INSTALL_ANOTHER_TEMPLATE_USING_DIRECTORY'JText::_('JLIB_INSTALLER_' $this->route),
  188.                         $this->parent->getPath('extension_root')
  189.                     )
  190.                 );
  191.  
  192.                 return false;
  193.             }
  194.         }
  195.  
  196.         /*
  197.          * If the template directory already exists, then we will assume that the template is already
  198.          * installed or another template is using that directory.
  199.          */
  200.         if (file_exists($this->parent->getPath('extension_root')) && !$this->parent->isOverwrite())
  201.         {
  202.             JLog::add(
  203.                 JText::sprintf('JLIB_INSTALLER_ABORT_TPL_INSTALL_ANOTHER_TEMPLATE_USING_DIRECTORY'$this->parent->getPath('extension_root')),
  204.                 JLog::WARNING'jerror'
  205.             );
  206.  
  207.             return false;
  208.         }
  209.  
  210.         // If the template directory does not exist, let's create it
  211.         $created false;
  212.  
  213.         if (!file_exists($this->parent->getPath('extension_root')))
  214.         {
  215.             if (!$created JFolder::create($this->parent->getPath('extension_root')))
  216.             {
  217.                 $this->parent
  218.                     ->abort(JText::sprintf('JLIB_INSTALLER_ABORT_TPL_INSTALL_FAILED_CREATE_DIRECTORY'$this->parent->getPath('extension_root')));
  219.  
  220.                 return false;
  221.             }
  222.         }
  223.  
  224.         // If we created the template directory and will want to remove it if we have to roll back
  225.         // the installation, let's add it to the installation step stack
  226.         if ($created)
  227.         {
  228.             $this->parent->pushStep(array('type' => 'folder''path' => $this->parent->getPath('extension_root')));
  229.         }
  230.  
  231.         // Copy all the necessary files
  232.         if ($this->parent->parseFiles($xml->files-1=== false)
  233.         {
  234.             // Install failed, rollback changes
  235.             $this->parent->abort();
  236.  
  237.             return false;
  238.         }
  239.  
  240.         if ($this->parent->parseFiles($xml->images-1=== false)
  241.         {
  242.             // Install failed, rollback changes
  243.             $this->parent->abort();
  244.  
  245.             return false;
  246.         }
  247.  
  248.         if ($this->parent->parseFiles($xml->css-1=== false)
  249.         {
  250.             // Install failed, rollback changes
  251.             $this->parent->abort();
  252.  
  253.             return false;
  254.         }
  255.  
  256.         // Parse optional tags
  257.         $this->parent->parseMedia($xml->media);
  258.         $this->parent->parseLanguages($xml->languages$clientId);
  259.  
  260.         // Get the template description
  261.         $this->parent->set('message'JText::_((string) $xml->description));
  262.  
  263.         // Lastly, we will copy the manifest file to its appropriate place.
  264.         if (!$this->parent->copyManifest(-1))
  265.         {
  266.             // Install failed, rollback changes
  267.             $this->parent->abort(JText::_('JLIB_INSTALLER_ABORT_TPL_INSTALL_COPY_SETUP'));
  268.  
  269.             return false;
  270.         }
  271.  
  272.         /**
  273.          * ---------------------------------------------------------------------------------------------
  274.          * Extension Registration
  275.          * ---------------------------------------------------------------------------------------------
  276.          */
  277.  
  278.         $row JTable::getInstance('extension');
  279.  
  280.         if ($this->route == 'update' && $id)
  281.         {
  282.             $row->load($id);
  283.         }
  284.         else
  285.         {
  286.             $row->type 'template';
  287.             $row->element $this->get('element');
  288.  
  289.             // There is no folder for templates
  290.             $row->folder '';
  291.             $row->enabled 1;
  292.             $row->protected 0;
  293.             $row->access 1;
  294.             $row->client_id $clientId;
  295.             $row->params $this->parent->getParams();
  296.  
  297.             // Custom data
  298.             $row->custom_data '';
  299.         }
  300.  
  301.         // Name might change in an update
  302.         $row->name $this->get('name');
  303.         $row->manifest_cache $this->parent->generateManifestCache();
  304.  
  305.         if (!$row->store())
  306.         {
  307.             // Install failed, roll back changes
  308.             $this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT_TPL_INSTALL_ROLLBACK'$db->stderr(true)));
  309.  
  310.             return false;
  311.         }
  312.  
  313.         if ($this->route == 'install')
  314.         {
  315.             $debug $lang->setDebug(false);
  316.  
  317.             $columns array($db->quoteName('template'),
  318.                 $db->quoteName('client_id'),
  319.                 $db->quoteName('home'),
  320.                 $db->quoteName('title'),
  321.                 $db->quoteName('params')
  322.             );
  323.  
  324.             $values array(
  325.                 $db->quote($row->element)$clientId$db->quote(0),
  326.                 $db->quote(JText::sprintf('JLIB_INSTALLER_DEFAULT_STYLE'JText::_($this->get('name')))),
  327.                 $db->quote($row->params) );
  328.  
  329.             $lang->setDebug($debug);
  330.  
  331.             // Insert record in #__template_styles
  332.             $query->clear()
  333.                 ->insert($db->quoteName('#__template_styles'))
  334.                 ->columns($columns)
  335.                 ->values(implode(','$values));
  336.  
  337.             $db->setQuery($query);
  338.  
  339.             // There is a chance this could fail but we don't care...
  340.             $db->execute();
  341.         }
  342.  
  343.         return $row->get('extension_id');
  344.     }
  345.  
  346.     /**
  347.      * Custom update method for components
  348.      *
  349.      * @return  boolean  True on success
  350.      *
  351.      * @since   3.1
  352.      */
  353.     public function update()
  354.     {
  355.         $this->route = 'update';
  356.  
  357.         return $this->install();
  358.     }
  359.  
  360.     /**
  361.      * Custom uninstall method
  362.      *
  363.      * @param   integer  $id  The extension ID
  364.      *
  365.      * @return  boolean  True on success
  366.      *
  367.      * @since   3.1
  368.      */
  369.     public function uninstall($id)
  370.     {
  371.         // First order of business will be to load the template object table from the database.
  372.         // This should give us the necessary information to proceed.
  373.         $row JTable::getInstance('extension');
  374.  
  375.         if (!$row->load((int) $id|| !strlen($row->element))
  376.         {
  377.             JLog::add(JText::_('JLIB_INSTALLER_ERROR_TPL_UNINSTALL_ERRORUNKOWNEXTENSION')JLog::WARNING'jerror');
  378.  
  379.             return false;
  380.         }
  381.  
  382.         // Is the template we are trying to uninstall a core one?
  383.         // Because that is not a good idea...
  384.         if ($row->protected)
  385.         {
  386.             JLog::add(JText::sprintf('JLIB_INSTALLER_ERROR_TPL_UNINSTALL_WARNCORETEMPLATE'$row->name)JLog::WARNING'jerror');
  387.  
  388.             return false;
  389.         }
  390.  
  391.         $name $row->element;
  392.         $clientId $row->client_id;
  393.  
  394.         // For a template the id will be the template name which represents the subfolder of the templates folder that the template resides in.
  395.         if (!$name)
  396.         {
  397.             JLog::add(JText::_('JLIB_INSTALLER_ERROR_TPL_UNINSTALL_TEMPLATE_ID_EMPTY')JLog::WARNING'jerror');
  398.  
  399.             return false;
  400.         }
  401.  
  402.         // Deny remove default template
  403.         $db $this->parent->getDbo();
  404.         $query "SELECT COUNT(*) FROM #__template_styles WHERE home = '1' AND template = " $db->quote($name);
  405.         $db->setQuery($query);
  406.  
  407.         if ($db->loadResult(!= 0)
  408.         {
  409.             JLog::add(JText::_('JLIB_INSTALLER_ERROR_TPL_UNINSTALL_TEMPLATE_DEFAULT')JLog::WARNING'jerror');
  410.  
  411.             return false;
  412.         }
  413.  
  414.         // Get the template root path
  415.         $client JApplicationHelper::getClientInfo($clientId);
  416.  
  417.         if (!$client)
  418.         {
  419.             JLog::add(JText::_('JLIB_INSTALLER_ERROR_TPL_UNINSTALL_INVALID_CLIENT')JLog::WARNING'jerror');
  420.  
  421.             return false;
  422.         }
  423.  
  424.         $this->parent->setPath('extension_root'$client->path '/templates/' strtolower($name));
  425.         $this->parent->setPath('source'$this->parent->getPath('extension_root'));
  426.  
  427.         // We do findManifest to avoid problem when uninstalling a list of extensions: getManifest cache its manifest file
  428.         $this->parent->findManifest();
  429.         $manifest $this->parent->getManifest();
  430.  
  431.         if (!($manifest instanceof SimpleXMLElement))
  432.         {
  433.             // Kill the extension entry
  434.             $row->delete($row->extension_id);
  435.             unset($row);
  436.  
  437.             // Make sure we delete the folders
  438.             JFolder::delete($this->parent->getPath('extension_root'));
  439.             JLog::add(JText::_('JLIB_INSTALLER_ERROR_TPL_UNINSTALL_INVALID_NOTFOUND_MANIFEST')JLog::WARNING'jerror');
  440.  
  441.             return false;
  442.         }
  443.  
  444.         // Remove files
  445.         $this->parent->removeFiles($manifest->media);
  446.         $this->parent->removeFiles($manifest->languages$clientId);
  447.  
  448.         // Delete the template directory
  449.         if (JFolder::exists($this->parent->getPath('extension_root')))
  450.         {
  451.             $retval JFolder::delete($this->parent->getPath('extension_root'));
  452.         }
  453.         else
  454.         {
  455.             JLog::add(JText::_('JLIB_INSTALLER_ERROR_TPL_UNINSTALL_TEMPLATE_DIRECTORY')JLog::WARNING'jerror');
  456.             $retval false;
  457.         }
  458.  
  459.         // Set menu that assigned to the template back to default template
  460.         $query 'UPDATE #__menu'
  461.             . ' SET template_style_id = 0'
  462.             . ' WHERE template_style_id in ('
  463.             . '    SELECT s.id FROM #__template_styles s'
  464.             . ' WHERE s.template = ' $db->quote(strtolower($name)) ' AND s.client_id = ' $clientId ')';
  465.  
  466.         $db->setQuery($query);
  467.         $db->execute();
  468.  
  469.         $query 'DELETE FROM #__template_styles WHERE template = ' $db->quote($name' AND client_id = ' $clientId;
  470.         $db->setQuery($query);
  471.         $db->execute();
  472.  
  473.         $row->delete($row->extension_id);
  474.         unset($row);
  475.  
  476.         return $retval;
  477.     }
  478.  
  479.     /**
  480.      * Discover existing but uninstalled templates
  481.      *
  482.      * @return  array  JExtensionTable list
  483.      */
  484.     public function discover()
  485.     {
  486.         $results array();
  487.         $site_list JFolder::folders(JPATH_SITE '/templates');
  488.         $admin_list JFolder::folders(JPATH_ADMINISTRATOR '/templates');
  489.         $site_info JApplicationHelper::getClientInfo('site'true);
  490.         $admin_info JApplicationHelper::getClientInfo('administrator'true);
  491.  
  492.         foreach ($site_list as $template)
  493.         {
  494.             if ($template == 'system')
  495.             {
  496.                 // Ignore special system template
  497.                 continue;
  498.             }
  499.             $manifest_details JInstaller::parseXMLInstallFile(JPATH_SITE "/templates/$template/templateDetails.xml");
  500.             $extension JTable::getInstance('extension');
  501.             $extension->set('type''template');
  502.             $extension->set('client_id'$site_info->id);
  503.             $extension->set('element'$template);
  504.             $extension->set('folder''');
  505.             $extension->set('name'$template);
  506.             $extension->set('state'-1);
  507.             $extension->set('manifest_cache'json_encode($manifest_details));
  508.             $extension->set('params''{}');
  509.             $results[$extension;
  510.         }
  511.  
  512.         foreach ($admin_list as $template)
  513.         {
  514.             if ($template == 'system')
  515.             {
  516.                 // Ignore special system template
  517.                 continue;
  518.             }
  519.  
  520.             $manifest_details JInstaller::parseXMLInstallFile(JPATH_ADMINISTRATOR "/templates/$template/templateDetails.xml");
  521.             $extension JTable::getInstance('extension');
  522.             $extension->set('type''template');
  523.             $extension->set('client_id'$admin_info->id);
  524.             $extension->set('element'$template);
  525.             $extension->set('folder''');
  526.             $extension->set('name'$template);
  527.             $extension->set('state'-1);
  528.             $extension->set('manifest_cache'json_encode($manifest_details));
  529.             $extension->set('params''{}');
  530.             $results[$extension;
  531.         }
  532.  
  533.         return $results;
  534.     }
  535.  
  536.     /**
  537.      * Discover_install
  538.      * Perform an install for a discovered extension
  539.      *
  540.      * @return boolean 
  541.      *
  542.      * @since 3.1
  543.      */
  544.     public function discover_install()
  545.     {
  546.         // Templates are one of the easiest
  547.         // If its not in the extensions table we just add it
  548.         $client JApplicationHelper::getClientInfo($this->parent->extension->client_id);
  549.         $manifestPath $client->path '/templates/' $this->parent->extension->element '/templateDetails.xml';
  550.         $this->parent->manifest $this->parent->isManifest($manifestPath);
  551.         $description = (string) $this->parent->manifest->description;
  552.  
  553.         if ($description)
  554.         {
  555.             $this->parent->set('message'JText::_($description));
  556.         }
  557.         else
  558.         {
  559.             $this->parent->set('message''');
  560.         }
  561.  
  562.         $this->parent->setPath('manifest'$manifestPath);
  563.         $manifest_details JInstaller::parseXMLInstallFile($this->parent->getPath('manifest'));
  564.         $this->parent->extension->manifest_cache json_encode($manifest_details);
  565.         $this->parent->extension->state 0;
  566.         $this->parent->extension->name $manifest_details['name'];
  567.         $this->parent->extension->enabled 1;
  568.  
  569.         $data new JObject;
  570.  
  571.         foreach ($manifest_details as $key => $value)
  572.         {
  573.             $data->set($key$value);
  574.         }
  575.  
  576.         $this->parent->extension->params $this->parent->getParams();
  577.  
  578.         if ($this->parent->extension->store())
  579.         {
  580.             $db $this->parent->getDbo();
  581.  
  582.             // Insert record in #__template_styles
  583.             $lang JFactory::getLanguage();
  584.             $debug $lang->setDebug(false);
  585.             $columns array($db->quoteName('template'),
  586.                 $db->quoteName('client_id'),
  587.                 $db->quoteName('home'),
  588.                 $db->quoteName('title'),
  589.                 $db->quoteName('params')
  590.             );
  591.             $query $db->getQuery(true)
  592.                 ->insert($db->quoteName('#__template_styles'))
  593.                 ->columns($columns)
  594.                 ->values(
  595.                     $db->quote($this->parent->extension->element)
  596.                         . ',' $db->quote($this->parent->extension->client_id)
  597.                         . ',' $db->quote(0)
  598.                         . ',' $db->quote(JText::sprintf('JLIB_INSTALLER_DEFAULT_STYLE'$this->parent->extension->name))
  599.                         . ',' $db->quote($this->parent->extension->params)
  600.                 );
  601.             $lang->setDebug($debug);
  602.             $db->setQuery($query);
  603.             $db->execute();
  604.  
  605.             return $this->parent->extension->get('extension_id');
  606.         }
  607.         else
  608.         {
  609.             JLog::add(JText::_('JLIB_INSTALLER_ERROR_TPL_DISCOVER_STORE_DETAILS')JLog::WARNING'jerror');
  610.  
  611.             return false;
  612.         }
  613.     }
  614.  
  615.     /**
  616.      * Refreshes the extension table cache
  617.      *
  618.      * @return  boolean  Result of operation, true if updated, false on failure
  619.      *
  620.      * @since   3.1
  621.      */
  622.     public function refreshManifestCache()
  623.     {
  624.         // Need to find to find where the XML file is since we don't store this normally.
  625.         $client JApplicationHelper::getClientInfo($this->parent->extension->client_id);
  626.         $manifestPath $client->path '/templates/' $this->parent->extension->element '/templateDetails.xml';
  627.         $this->parent->manifest $this->parent->isManifest($manifestPath);
  628.         $this->parent->setPath('manifest'$manifestPath);
  629.  
  630.         $manifest_details JInstaller::parseXMLInstallFile($this->parent->getPath('manifest'));
  631.         $this->parent->extension->manifest_cache json_encode($manifest_details);
  632.         $this->parent->extension->name $manifest_details['name'];
  633.  
  634.         try
  635.         {
  636.             return $this->parent->extension->store();
  637.         }
  638.         catch (RuntimeException $e)
  639.         {
  640.             JLog::add(JText::_('JLIB_INSTALLER_ERROR_TPL_REFRESH_MANIFEST_CACHE')JLog::WARNING'jerror');
  641.  
  642.             return false;
  643.         }
  644.     }
  645. }
  646.  
  647. /**
  648.  * Deprecated class placeholder. You should use JInstallerAdapterTemplate instead.
  649.  *
  650.  * @package     Joomla.Libraries
  651.  * @subpackage  Installer
  652.  * @since       3.1
  653.  * @deprecated  4.0
  654.  * @codeCoverageIgnore
  655.  */
  656. {
  657. }

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