first commit

This commit is contained in:
alazhar
2020-01-02 22:20:31 +07:00
commit 10eb3340ad
5753 changed files with 631345 additions and 0 deletions

View File

@ -0,0 +1 @@
<!DOCTYPE html><title></title>

View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<form>
<fieldset>
<field
name="extension_id"
type="hidden" />
<field
name="filename"
type="hidden" />
<field
name="source"
type="editor"
editor="codemirror|none"
buttons="no"
label="COM_TEMPLATES_FIELD_SOURCE_LABEL"
description="COM_TEMPLATES_FIELD_SOURCE_DESC"
height="500px"
rows="20"
cols="80"
filter="raw" />
</fieldset>
</form>

View File

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="utf-8"?>
<form>
<fieldset>
<field
id="id"
name="id"
type="text"
default="0"
readonly="true"
class="readonly"
label="JGLOBAL_FIELD_ID_LABEL"
description ="JGLOBAL_FIELD_ID_DESC" />
<field
name="template"
type="text"
label="COM_TEMPLATES_FIELD_TEMPLATE_LABEL"
description="COM_TEMPLATES_FIELD_TEMPLATE_DESC"
class="readonly"
size="30"
readonly="true" />
<field
name="client_id"
type="hidden"
label="COM_TEMPLATES_FIELD_CLIENT_LABEL"
description="COM_TEMPLATES_FIELD_CLIENT_DESC"
class="readonly"
default="0"
readonly="true" />
<field
name="title"
type="text"
class="inputbox"
size="50"
label="COM_TEMPLATES_FIELD_TITLE_LABEL"
description="COM_TEMPLATES_FIELD_TITLE_DESC"
required="true" />
<field name="assigned" type="hidden" />
</fieldset>
</form>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<form>
<fieldset>
<field
name="home"
type="radio"
label="COM_TEMPLATES_FIELD_HOME_LABEL"
description="COM_TEMPLATES_FIELD_HOME_ADMINISTRATOR_DESC"
class="btn-group"
default="0">
<option value="0">JNO</option>
<option value="1">JYES</option>
</field>
</fieldset>
</form>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<form>
<fieldset>
<field
name="home"
type="contentlanguage"
label="COM_TEMPLATES_FIELD_HOME_LABEL"
description="COM_TEMPLATES_FIELD_HOME_SITE_DESC"
class="inputbox"
default="0">
<option value="0">JNO</option>
<option value="1">JALL</option>
</field>
</fieldset>
</form>

View File

@ -0,0 +1 @@
<!DOCTYPE html><title></title>

View File

@ -0,0 +1,256 @@
<?php
/**
* @package Joomla.Administrator
* @subpackage com_templates
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
/**
* @package Joomla.Administrator
* @subpackage com_templates
* @since 1.5
*/
class TemplatesModelSource extends JModelForm
{
/**
* Cache for the template information.
*
* @var object
*/
private $_template = null;
/**
* Method to auto-populate the model state.
*
* Note. Calling getState in this method will result in recursion.
*
* @since 1.6
*/
protected function populateState()
{
jimport('joomla.filesystem.file');
$app = JFactory::getApplication('administrator');
// Load the User state.
$id = $app->getUserState('com_templates.edit.source.id');
// Parse the template id out of the compound reference.
$temp = explode(':', base64_decode($id));
$this->setState('extension.id', (int) array_shift($temp));
$fileName = array_shift($temp);
$this->setState('filename', $fileName);
// Save the syntax for later use
$app->setUserState('editor.source.syntax', JFile::getExt($fileName));
// Load the parameters.
$params = JComponentHelper::getParams('com_templates');
$this->setState('params', $params);
}
/**
* Method to get the record form.
*
* @param array $data Data for the form.
* @param boolean $loadData True if the form is to load its own data (default case), false if not.
* @return JForm A JForm object on success, false on failure
* @since 1.6
*/
public function getForm($data = array(), $loadData = true)
{
$app = JFactory::getApplication();
// Codemirror or Editor None should be enabled
$db = JFactory::getDbo();
$query = $db->getQuery(true)
->select('COUNT(*)')
->from('#__extensions as a')
->where('(a.name =' . $db->quote('plg_editors_codemirror') . ' AND a.enabled = 1) OR (a.name =' . $db->quote('plg_editors_none') . ' AND a.enabled = 1)');
$db->setQuery($query);
$state = $db->loadResult();
if ((int) $state < 1)
{
$app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_EDITOR_DISABLED'), 'warning');
}
// Get the form.
$form = $this->loadForm('com_templates.source', 'source', array('control' => 'jform', 'load_data' => $loadData));
if (empty($form))
{
return false;
}
return $form;
}
/**
* Method to get the data that should be injected in the form.
*
* @return mixed The data for the form.
* @since 1.6
*/
protected function loadFormData()
{
// Check the session for previously entered form data.
$data = JFactory::getApplication()->getUserState('com_templates.edit.source.data', array());
if (empty($data))
{
$data = $this->getSource();
}
$this->preprocessData('com_templates.source', $data);
return $data;
}
/**
* Method to get a single record.
*
* @return mixed Object on success, false on failure.
* @since 1.6
*/
public function &getSource()
{
$item = new stdClass;
if (!$this->_template)
{
$this->getTemplate();
}
if ($this->_template)
{
$fileName = $this->getState('filename');
$client = JApplicationHelper::getClientInfo($this->_template->client_id);
$filePath = JPath::clean($client->path . '/templates/' . $this->_template->element . '/' . $fileName);
if (file_exists($filePath))
{
$item->extension_id = $this->getState('extension.id');
$item->filename = $this->getState('filename');
$item->source = file_get_contents($filePath);
}
else
{
$this->setError(JText::_('COM_TEMPLATES_ERROR_SOURCE_FILE_NOT_FOUND'));
}
}
return $item;
}
/**
* Method to get the template information.
*
* @return mixed Object if successful, false if not and internal error is set.
* @since 1.6
*/
public function &getTemplate()
{
$pk = $this->getState('extension.id');
$db = $this->getDbo();
// Get the template information.
$db->setQuery(
'SELECT extension_id, client_id, element' .
' FROM #__extensions' .
' WHERE extension_id = ' . (int) $pk .
' AND type = ' . $db->quote('template')
);
try
{
$result = $db->loadObject();
}
catch (RuntimeException $e)
{
$this->setError($e->getMessage());
$this->_template = false;
return false;
}
if (empty($result))
{
$this->setError(JText::_('COM_TEMPLATES_ERROR_EXTENSION_RECORD_NOT_FOUND'));
$this->_template = false;
}
else
{
$this->_template = $result;
}
return $this->_template;
}
/**
* Method to store the source file contents.
*
* @param array The souce data to save.
*
* @return boolean True on success, false otherwise and internal error set.
* @since 1.6
*/
public function save($data)
{
jimport('joomla.filesystem.file');
// Get the template.
$template = $this->getTemplate();
if (empty($template))
{
return false;
}
$dispatcher = JEventDispatcher::getInstance();
$fileName = $this->getState('filename');
$client = JApplicationHelper::getClientInfo($template->client_id);
$filePath = JPath::clean($client->path . '/templates/' . $template->element . '/' . $fileName);
// Include the extension plugins for the save events.
JPluginHelper::importPlugin('extension');
// Set FTP credentials, if given.
JClientHelper::setCredentialsFromRequest('ftp');
$ftp = JClientHelper::getCredentials('ftp');
// Try to make the template file writeable.
if (!$ftp['enabled'] && JPath::isOwner($filePath) && !JPath::setPermissions($filePath, '0644'))
{
$this->setError(JText::_('COM_TEMPLATES_ERROR_SOURCE_FILE_NOT_WRITABLE'));
return false;
}
// Trigger the onExtensionBeforeSave event.
$result = $dispatcher->trigger('onExtensionBeforeSave', array('com_templates.source', &$data, false));
if (in_array(false, $result, true))
{
$this->setError($table->getError());
return false;
}
$return = JFile::write($filePath, $data['source']);
// Try to make the template file unwriteable.
if (!$ftp['enabled'] && JPath::isOwner($filePath) && !JPath::setPermissions($filePath, '0444'))
{
$this->setError(JText::_('COM_TEMPLATES_ERROR_SOURCE_FILE_NOT_UNWRITABLE'));
return false;
}
elseif (!$return)
{
$this->setError(JText::sprintf('COM_TEMPLATES_ERROR_FAILED_TO_SAVE_FILENAME', $fileName));
return false;
}
// Trigger the onExtensionAfterSave event.
$dispatcher->trigger('onExtensionAfterSave', array('com_templates.source', &$table, false));
return true;
}
}

View File

@ -0,0 +1,629 @@
<?php
/**
* @package Joomla.Administrator
* @subpackage com_templates
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
/**
* Template style model.
*
* @package Joomla.Administrator
* @subpackage com_templates
* @since 1.6
*/
class TemplatesModelStyle extends JModelAdmin
{
/**
* @var string The help screen key for the module.
* @since 1.6
*/
protected $helpKey = 'JHELP_EXTENSIONS_TEMPLATE_MANAGER_STYLES_EDIT';
/**
* @var string The help screen base URL for the module.
* @since 1.6
*/
protected $helpURL;
/**
* Item cache.
*/
private $_cache = array();
/**
* Method to auto-populate the model state.
*
* Note. Calling getState in this method will result in recursion.
*
* @since 1.6
*/
protected function populateState()
{
$app = JFactory::getApplication('administrator');
// Load the User state.
$pk = $app->input->getInt('id');
$this->setState('style.id', $pk);
// Load the parameters.
$params = JComponentHelper::getParams('com_templates');
$this->setState('params', $params);
}
/**
* Method to delete rows.
*
* @param array An array of item ids.
*
* @return boolean Returns true on success, false on failure.
*/
public function delete(&$pks)
{
$pks = (array) $pks;
$user = JFactory::getUser();
$table = $this->getTable();
// Iterate the items to delete each one.
foreach ($pks as $pk)
{
if ($table->load($pk))
{
// Access checks.
if (!$user->authorise('core.delete', 'com_templates'))
{
throw new Exception(JText::_('JERROR_CORE_DELETE_NOT_PERMITTED'));
}
// You should not delete a default style
if ($table->home != '0'){
JError::raiseWarning(SOME_ERROR_NUMBER, Jtext::_('COM_TEMPLATES_STYLE_CANNOT_DELETE_DEFAULT_STYLE'));
return false;
}
if (!$table->delete($pk))
{
$this->setError($table->getError());
return false;
}
}
else {
$this->setError($table->getError());
return false;
}
}
// Clean cache
$this->cleanCache();
return true;
}
/**
* Method to duplicate styles.
*
* @param array An array of primary key IDs.
*
* @return boolean True if successful.
* @throws Exception
*/
public function duplicate(&$pks)
{
$user = JFactory::getUser();
// Access checks.
if (!$user->authorise('core.create', 'com_templates'))
{
throw new Exception(JText::_('JERROR_CORE_CREATE_NOT_PERMITTED'));
}
$table = $this->getTable();
foreach ($pks as $pk)
{
if ($table->load($pk, true))
{
// Reset the id to create a new record.
$table->id = 0;
// Reset the home (don't want dupes of that field).
$table->home = 0;
// Alter the title.
$m = null;
$table->title = $this->generateNewTitle(null, null, $table->title);
if (!$table->check() || !$table->store())
{
throw new Exception($table->getError());
}
}
else {
throw new Exception($table->getError());
}
}
// Clean cache
$this->cleanCache();
return true;
}
/**
* Method to change the title.
*
* @param integer $category_id The id of the category.
* @param string $alias The alias.
* @param string $title The title.
*
* @return string New title.
* @since 1.7.1
*/
protected function generateNewTitle($category_id, $alias, $title)
{
// Alter the title
$table = $this->getTable();
while ($table->load(array('title' => $title)))
{
$title = JString::increment($title);
}
return $title;
}
/**
* Method to get the record form.
*
* @param array $data An optional array of data for the form to interogate.
* @param boolean $loadData True if the form is to load its own data (default case), false if not.
* @return JForm A JForm object on success, false on failure
* @since 1.6
*/
public function getForm($data = array(), $loadData = true)
{
// The folder and element vars are passed when saving the form.
if (empty($data))
{
$item = $this->getItem();
$clientId = $item->client_id;
$template = $item->template;
}
else
{
$clientId = JArrayHelper::getValue($data, 'client_id');
$template = JArrayHelper::getValue($data, 'template');
}
// These variables are used to add data from the plugin XML files.
$this->setState('item.client_id', $clientId);
$this->setState('item.template', $template);
// Get the form.
$form = $this->loadForm('com_templates.style', 'style', array('control' => 'jform', 'load_data' => $loadData));
if (empty($form))
{
return false;
}
// Modify the form based on access controls.
if (!$this->canEditState((object) $data))
{
// Disable fields for display.
$form->setFieldAttribute('home', 'disabled', 'true');
// Disable fields while saving.
// The controller has already verified this is a record you can edit.
$form->setFieldAttribute('home', 'filter', 'unset');
}
return $form;
}
/**
* Method to get the data that should be injected in the form.
*
* @return mixed The data for the form.
* @since 1.6
*/
protected function loadFormData()
{
// Check the session for previously entered form data.
$data = JFactory::getApplication()->getUserState('com_templates.edit.style.data', array());
if (empty($data))
{
$data = $this->getItem();
}
$this->preprocessData('com_templates.style', $data);
return $data;
}
/**
* Method to get a single record.
*
* @param integer The id of the primary key.
*
* @return mixed Object on success, false on failure.
*/
public function getItem($pk = null)
{
$pk = (!empty($pk)) ? $pk : (int) $this->getState('style.id');
if (!isset($this->_cache[$pk]))
{
$false = false;
// Get a row instance.
$table = $this->getTable();
// Attempt to load the row.
$return = $table->load($pk);
// Check for a table object error.
if ($return === false && $table->getError())
{
$this->setError($table->getError());
return $false;
}
// Convert to the JObject before adding other data.
$properties = $table->getProperties(1);
$this->_cache[$pk] = JArrayHelper::toObject($properties, 'JObject');
// Convert the params field to an array.
$registry = new JRegistry;
$registry->loadString($table->params);
$this->_cache[$pk]->params = $registry->toArray();
// Get the template XML.
$client = JApplicationHelper::getClientInfo($table->client_id);
$path = JPath::clean($client->path.'/templates/'.$table->template.'/templateDetails.xml');
if (file_exists($path))
{
$this->_cache[$pk]->xml = simplexml_load_file($path);
}
else {
$this->_cache[$pk]->xml = null;
}
}
return $this->_cache[$pk];
}
/**
* Returns a reference to the a Table object, always creating it.
*
* @param type The table type to instantiate
* @param string A prefix for the table class name. Optional.
* @param array Configuration array for model. Optional.
* @return JTable A database object
*/
public function getTable($type = 'Style', $prefix = 'TemplatesTable', $config = array())
{
return JTable::getInstance($type, $prefix, $config);
}
/**
* @param object A form object.
* @param mixed The data expected for the form.
* @throws Exception if there is an error in the form event.
* @since 1.6
*/
protected function preprocessForm(JForm $form, $data, $group = 'content')
{
$clientId = $this->getState('item.client_id');
$template = $this->getState('item.template');
$lang = JFactory::getLanguage();
$client = JApplicationHelper::getClientInfo($clientId);
if (!$form->loadFile('style_'.$client->name, true))
{
throw new Exception(JText::_('JERROR_LOADFILE_FAILED'));
}
jimport('joomla.filesystem.path');
$formFile = JPath::clean($client->path.'/templates/'.$template.'/templateDetails.xml');
// Load the core and/or local language file(s).
$lang->load('tpl_'.$template, $client->path, null, false, false)
|| $lang->load('tpl_'.$template, $client->path.'/templates/'.$template, null, false, false)
|| $lang->load('tpl_'.$template, $client->path, $lang->getDefault(), false, false)
|| $lang->load('tpl_'.$template, $client->path.'/templates/'.$template, $lang->getDefault(), false, false);
if (file_exists($formFile))
{
// Get the template form.
if (!$form->loadFile($formFile, false, '//config'))
{
throw new Exception(JText::_('JERROR_LOADFILE_FAILED'));
}
}
// Disable home field if it is default style
if ((is_array($data) && array_key_exists('home', $data) && $data['home'] == '1')
|| ((is_object($data) && isset($data->home) && $data->home == '1')))
{
$form->setFieldAttribute('home', 'readonly', 'true');
}
// Attempt to load the xml file.
if (!$xml = simplexml_load_file($formFile))
{
throw new Exception(JText::_('JERROR_LOADFILE_FAILED'));
}
// Get the help data from the XML file if present.
$help = $xml->xpath('/extension/help');
if (!empty($help))
{
$helpKey = trim((string) $help[0]['key']);
$helpURL = trim((string) $help[0]['url']);
$this->helpKey = $helpKey ? $helpKey : $this->helpKey;
$this->helpURL = $helpURL ? $helpURL : $this->helpURL;
}
// Trigger the default form events.
parent::preprocessForm($form, $data, $group);
}
/**
* Method to save the form data.
*
* @param array The form data.
* @return boolean True on success.
*/
public function save($data)
{
// Detect disabled extension
$extension = JTable::getInstance('Extension');
if ($extension->load(array('enabled' => 0, 'type' => 'template', 'element' => $data['template'], 'client_id' => $data['client_id'])))
{
$this->setError(JText::_('COM_TEMPLATES_ERROR_SAVE_DISABLED_TEMPLATE'));
return false;
}
$app = JFactory::getApplication();
$dispatcher = JEventDispatcher::getInstance();
$table = $this->getTable();
$pk = (!empty($data['id'])) ? $data['id'] : (int) $this->getState('style.id');
$isNew = true;
// Include the extension plugins for the save events.
JPluginHelper::importPlugin('extension');
// Load the row if saving an existing record.
if ($pk > 0)
{
$table->load($pk);
$isNew = false;
}
if ($app->input->get('task') == 'save2copy')
{
$data['title'] = $this->generateNewTitle(null, null, $data['title']);
$data['home'] = 0;
$data['assigned'] = '';
}
// Bind the data.
if (!$table->bind($data))
{
$this->setError($table->getError());
return false;
}
// Prepare the row for saving
$this->prepareTable($table);
// Check the data.
if (!$table->check())
{
$this->setError($table->getError());
return false;
}
// Trigger the onExtensionBeforeSave event.
$result = $dispatcher->trigger('onExtensionBeforeSave', array('com_templates.style', &$table, $isNew));
if (in_array(false, $result, true))
{
$this->setError($table->getError());
return false;
}
// Store the data.
if (!$table->store())
{
$this->setError($table->getError());
return false;
}
$user = JFactory::getUser();
if ($user->authorise('core.edit', 'com_menus') && $table->client_id == 0)
{
$n = 0;
$db = JFactory::getDbo();
$user = JFactory::getUser();
if (!empty($data['assigned']) && is_array($data['assigned']))
{
JArrayHelper::toInteger($data['assigned']);
// Update the mapping for menu items that this style IS assigned to.
$query = $db->getQuery(true)
->update('#__menu')
->set('template_style_id='.(int) $table->id)
->where('id IN ('.implode(',', $data['assigned']).')')
->where('template_style_id!='.(int) $table->id)
->where('checked_out in (0,'.(int) $user->id.')');
$db->setQuery($query);
$db->execute();
$n += $db->getAffectedRows();
}
// Remove style mappings for menu items this style is NOT assigned to.
// If unassigned then all existing maps will be removed.
$query = $db->getQuery(true)
->update('#__menu')
->set('template_style_id=0');
if (!empty($data['assigned']))
{
$query->where('id NOT IN ('.implode(',', $data['assigned']).')');
}
$query->where('template_style_id='.(int) $table->id)
->where('checked_out in (0,'.(int) $user->id.')');
$db->setQuery($query);
$db->execute();
$n += $db->getAffectedRows();
if ($n > 0)
{
$app->enQueueMessage(JText::plural('COM_TEMPLATES_MENU_CHANGED', $n));
}
}
// Clean the cache.
$this->cleanCache();
// Trigger the onExtensionAfterSave event.
$dispatcher->trigger('onExtensionAfterSave', array('com_templates.style', &$table, $isNew));
$this->setState('style.id', $table->id);
return true;
}
/**
* Method to set a template style as home.
*
* @param integer The primary key ID for the style.
*
* @return boolean True if successful.
* @throws Exception
*/
public function setHome($id = 0)
{
$user = JFactory::getUser();
$db = $this->getDbo();
// Access checks.
if (!$user->authorise('core.edit.state', 'com_templates'))
{
throw new Exception(JText::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED'));
}
$style = JTable::getInstance('Style', 'TemplatesTable');
if (!$style->load((int) $id))
{
throw new Exception(JText::_('COM_TEMPLATES_ERROR_STYLE_NOT_FOUND'));
}
// Detect disabled extension
$extension = JTable::getInstance('Extension');
if ($extension->load(array('enabled' => 0, 'type' => 'template', 'element' => $style->template, 'client_id' => $style->client_id)))
{
throw new Exception(JText::_('COM_TEMPLATES_ERROR_SAVE_DISABLED_TEMPLATE'));
}
// Reset the home fields for the client_id.
$db->setQuery(
'UPDATE #__template_styles' .
' SET home = \'0\'' .
' WHERE client_id = '.(int) $style->client_id .
' AND home = \'1\''
);
$db->execute();
// Set the new home style.
$db->setQuery(
'UPDATE #__template_styles' .
' SET home = \'1\'' .
' WHERE id = '.(int) $id
);
$db->execute();
// Clean the cache.
$this->cleanCache();
return true;
}
/**
* Method to unset a template style as default for a language.
*
* @param integer The primary key ID for the style.
*
* @return boolean True if successful.
* @throws Exception
*/
public function unsetHome($id = 0)
{
$user = JFactory::getUser();
$db = $this->getDbo();
// Access checks.
if (!$user->authorise('core.edit.state', 'com_templates'))
{
throw new Exception(JText::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED'));
}
// Lookup the client_id.
$db->setQuery(
'SELECT client_id, home' .
' FROM #__template_styles' .
' WHERE id = '.(int) $id
);
$style = $db->loadObject();
if (!is_numeric($style->client_id))
{
throw new Exception(JText::_('COM_TEMPLATES_ERROR_STYLE_NOT_FOUND'));
}
elseif ($style->home == '1')
{
throw new Exception(JText::_('COM_TEMPLATES_ERROR_CANNOT_UNSET_DEFAULT_STYLE'));
}
// Set the new home style.
$db->setQuery(
'UPDATE #__template_styles' .
' SET home = \'0\'' .
' WHERE id = '.(int) $id
);
$db->execute();
// Clean the cache.
$this->cleanCache();
return true;
}
/**
* Get the necessary data to load an item help screen.
*
* @return object An object with key, url, and local properties for loading the item help screen.
* @since 1.6
*/
public function getHelp()
{
return (object) array('key' => $this->helpKey, 'url' => $this->helpURL);
}
/**
* Custom clean cache method
*
* @since 1.6
*/
protected function cleanCache($group = null, $client_id = 0)
{
parent::cleanCache('com_templates');
parent::cleanCache('_system');
}
}

View File

@ -0,0 +1,165 @@
<?php
/**
* @package Joomla.Administrator
* @subpackage com_templates
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
/**
* Methods supporting a list of template style records.
*
* @package Joomla.Administrator
* @subpackage com_templates
* @since 1.6
*/
class TemplatesModelStyles extends JModelList
{
/**
* Constructor.
*
* @param array An optional associative array of configuration settings.
* @see JController
* @since 1.6
*/
public function __construct($config = array())
{
if (empty($config['filter_fields']))
{
$config['filter_fields'] = array(
'id', 'a.id',
'title', 'a.title',
'client_id', 'a.client_id',
'template', 'a.template',
'home', 'a.home',
);
}
parent::__construct($config);
}
/**
* Method to auto-populate the model state.
*
* Note. Calling getState in this method will result in recursion.
*
* @param string $ordering An optional ordering field.
* @param string $direction An optional direction (asc|desc).
*
* @return void
*
* @since 1.6
*/
protected function populateState($ordering = null, $direction = null)
{
// Load the filter state.
$search = $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search');
$this->setState('filter.search', $search);
$template = $this->getUserStateFromRequest($this->context . '.filter.template', 'filter_template');
$this->setState('filter.template', $template);
$clientId = $this->getUserStateFromRequest($this->context . '.filter.client_id', 'filter_client_id', null);
$this->setState('filter.client_id', $clientId);
// Load the parameters.
$params = JComponentHelper::getParams('com_templates');
$this->setState('params', $params);
// List state information.
parent::populateState('a.template', 'asc');
}
/**
* Method to get a store id based on model configuration state.
*
* This is necessary because the model is used by the component and
* different modules that might need different sets of data or different
* ordering requirements.
*
* @param string $id A prefix for the store id.
*
* @return string A store id.
*/
protected function getStoreId($id = '')
{
// Compile the store id.
$id .= ':' . $this->getState('filter.search');
$id .= ':' . $this->getState('filter.template');
$id .= ':' . $this->getState('filter.client_id');
return parent::getStoreId($id);
}
/**
* Build an SQL query to load the list data.
*
* @return JDatabaseQuery
*/
protected function getListQuery()
{
// Create a new query object.
$db = $this->getDbo();
$query = $db->getQuery(true);
// Select the required fields from the table.
$query->select(
$this->getState(
'list.select',
'a.id, a.template, a.title, a.home, a.client_id, l.title AS language_title, l.image as image'
)
);
$query->from($db->quoteName('#__template_styles') . ' AS a');
// Join on menus.
$query->select('COUNT(m.template_style_id) AS assigned')
->join('LEFT', '#__menu AS m ON m.template_style_id = a.id')
->group('a.id, a.template, a.title, a.home, a.client_id, l.title, l.image, e.extension_id');
// Join over the language
$query->join('LEFT', '#__languages AS l ON l.lang_code = a.home');
// Filter by extension enabled
$query->select('extension_id AS e_id')
->join('LEFT', '#__extensions AS e ON e.element = a.template')
->where('e.enabled = 1')
->where('e.type=' . $db->quote('template'));
// Filter by template.
if ($template = $this->getState('filter.template'))
{
$query->where('a.template = ' . $db->quote($template));
}
// Filter by client.
$clientId = $this->getState('filter.client_id');
if (is_numeric($clientId))
{
$query->where('a.client_id = ' . (int) $clientId);
}
// Filter by search in title
$search = $this->getState('filter.search');
if (!empty($search))
{
if (stripos($search, 'id:') === 0)
{
$query->where('a.id = ' . (int) substr($search, 3));
}
else
{
$search = $db->quote('%' . $db->escape($search, true) . '%');
$query->where('a.template LIKE ' . $search . ' OR a.title LIKE ' . $search);
}
}
// Add the list ordering clause.
$query->order($db->escape($this->getState('list.ordering', 'a.title')) . ' ' . $db->escape($this->getState('list.direction', 'ASC')));
//echo nl2br(str_replace('#__','jos_',$query));
return $query;
}
}

View File

@ -0,0 +1,286 @@
<?php
/**
* @package Joomla.Administrator
* @subpackage com_templates
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
/**
* @package Joomla.Administrator
* @subpackage com_templates
* @since 1.6
*/
class TemplatesModelTemplate extends JModelLegacy
{
protected $template = null;
/**
* Internal method to get file properties.
*
* @param string The base path.
* @param string The file name.
* @return object
* @since 1.6
*/
protected function getFile($path, $name)
{
$temp = new stdClass;
if ($template = $this->getTemplate())
{
$temp->name = $name;
$temp->exists = file_exists($path.$name);
$temp->id = urlencode(base64_encode($template->extension_id.':'.$name));
return $temp;
}
}
/**
* Method to get a list of all the files to edit in a template.
*
* @return array A nested array of relevant files.
* @since 1.6
*/
public function getFiles()
{
$result = array();
if ($template = $this->getTemplate())
{
jimport('joomla.filesystem.folder');
$client = JApplicationHelper::getClientInfo($template->client_id);
$path = JPath::clean($client->path.'/templates/'.$template->element.'/');
$lang = JFactory::getLanguage();
// Load the core and/or local language file(s).
$lang->load('tpl_'.$template->element, $client->path, null, false, false)
|| $lang->load('tpl_'.$template->element, $client->path.'/templates/'.$template->element, null, false, false)
|| $lang->load('tpl_'.$template->element, $client->path, $lang->getDefault(), false, false)
|| $lang->load('tpl_'.$template->element, $client->path.'/templates/'.$template->element, $lang->getDefault(), false, false);
// Check if the template path exists.
if (is_dir($path))
{
$result['main'] = array();
$result['css'] = array();
$result['clo'] = array();
$result['mlo'] = array();
$result['html'] = array();
// Handle the main PHP files.
$result['main']['index'] = $this->getFile($path, 'index.php');
$result['main']['error'] = $this->getFile($path, 'error.php');
$result['main']['print'] = $this->getFile($path, 'component.php');
$result['main']['offline'] = $this->getFile($path, 'offline.php');
// Handle the CSS files.
$files = JFolder::files($path.'/css', '\.css$', false, false);
foreach ($files as $file)
{
$result['css'][] = $this->getFile($path.'/css/', 'css/'.$file);
}
} else {
$this->setError(JText::_('COM_TEMPLATES_ERROR_TEMPLATE_FOLDER_NOT_FOUND'));
return false;
}
}
return $result;
}
/**
* Method to auto-populate the model state.
*
* Note. Calling getState in this method will result in recursion.
*
* @since 1.6
*/
protected function populateState()
{
$app = JFactory::getApplication('administrator');
// Load the User state.
$pk = $app->input->getInt('id');
$this->setState('extension.id', $pk);
// Load the parameters.
$params = JComponentHelper::getParams('com_templates');
$this->setState('params', $params);
}
/**
* Method to get the template information.
*
* @return mixed Object if successful, false if not and internal error is set.
* @since 1.6
*/
public function &getTemplate()
{
if (empty($this->template))
{
$pk = $this->getState('extension.id');
$db = $this->getDbo();
// Get the template information.
$query = $db->getQuery(true)
->select('extension_id, client_id, element')
->from('#__extensions')
->where($db->quoteName('extension_id') . ' = ' . (int) $pk)
->where($db->quoteName('type') . ' = ' . $db->quote('template'));
$db->setQuery($query);
try
{
$result = $db->loadObject();
}
catch (RuntimeException $e)
{
$this->setError($e->getMessage());
$this->template = false;
return false;
}
if (empty($result))
{
$this->setError(JText::_('COM_TEMPLATES_ERROR_EXTENSION_RECORD_NOT_FOUND'));
$this->template = false;
} else {
$this->template = $result;
}
}
return $this->template;
}
/**
* Method to check if new template name already exists
*
* @return boolean true if name is not used, false otherwise
* @since 2.5
*/
public function checkNewName()
{
$db = $this->getDbo();
$query = $db->getQuery(true)
->select('COUNT(*)')
->from('#__extensions')
->where('name = ' . $db->quote($this->getState('new_name')));
$db->setQuery($query);
return ($db->loadResult() == 0);
}
/**
* Method to check if new template name already exists
*
* @return string name of current template
* @since 2.5
*/
public function getFromName()
{
return $this->getTemplate()->element;
}
/**
* Method to check if new template name already exists
*
* @return boolean true if name is not used, false otherwise
* @since 2.5
*/
public function copy()
{
if ($template = $this->getTemplate())
{
jimport('joomla.filesystem.folder');
$client = JApplicationHelper::getClientInfo($template->client_id);
$fromPath = JPath::clean($client->path.'/templates/'.$template->element.'/');
// Delete new folder if it exists
$toPath = $this->getState('to_path');
if (JFolder::exists($toPath))
{
if (!JFolder::delete($toPath))
{
JError::raiseWarning(403, JText::_('COM_TEMPLATES_ERROR_COULD_NOT_WRITE'));
return false;
}
}
// Copy all files from $fromName template to $newName folder
if (!JFolder::copy($fromPath, $toPath) || !$this->fixTemplateName())
{
return false;
}
return true;
}
else
{
JError::raiseWarning(403, JText::_('COM_TEMPLATES_ERROR_INVALID_FROM_NAME'));
return false;
}
}
/**
* Method to delete tmp folder
*
* @return boolean true if delete successful, false otherwise
* @since 2.5
*/
public function cleanup()
{
// Clear installation messages
$app = JFactory::getApplication();
$app->setUserState('com_installer.message', '');
$app->setUserState('com_installer.extension_message', '');
// Delete temporary directory
return JFolder::delete($this->getState('to_path'));
}
/**
* Method to rename the template in the XML files and rename the language files
*
* @return boolean true if successful, false otherwise
* @since 2.5
*/
protected function fixTemplateName()
{
// Rename Language files
// Get list of language files
$result = true;
$files = JFolder::files($this->getState('to_path'), '.ini', true, true);
$newName = strtolower($this->getState('new_name'));
$oldName = $this->getTemplate()->element;
jimport('joomla.filesystem.file');
foreach ($files as $file)
{
$newFile = str_replace($oldName, $newName, $file);
$result = JFile::move($file, $newFile) && $result;
}
// Edit XML file
$xmlFile = $this->getState('to_path') . '/templateDetails.xml';
if (JFile::exists($xmlFile))
{
$contents = file_get_contents($xmlFile);
$pattern[] = '#<name>\s*' . $oldName . '\s*</name>#i';
$replace[] = '<name>'. $newName . '</name>';
$pattern[] = '#<language(.*)' . $oldName . '(.*)</language>#';
$replace[] = '<language${1}' . $newName . '${2}</language>';
$contents = preg_replace($pattern, $replace, $contents);
$result = JFile::write($xmlFile, $contents) && $result;
}
return $result;
}
}

View File

@ -0,0 +1,162 @@
<?php
/**
* @package Joomla.Administrator
* @subpackage com_templates
*
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
/**
* Methods supporting a list of template extension records.
*
* @package Joomla.Administrator
* @subpackage com_templates
* @since 1.6
*/
class TemplatesModelTemplates extends JModelList
{
/**
* Constructor.
*
* @param array An optional associative array of configuration settings.
* @see JController
* @since 1.6
*/
public function __construct($config = array())
{
if (empty($config['filter_fields']))
{
$config['filter_fields'] = array(
'id', 'a.id',
'name', 'a.name',
'folder', 'a.folder',
'element', 'a.element',
'checked_out', 'a.checked_out',
'checked_out_time', 'a.checked_out_time',
'state', 'a.state',
'enabled', 'a.enabled',
'access', 'a.access', 'access_level',
'ordering', 'a.ordering',
'client_id', 'a.client_id',
);
}
parent::__construct($config);
}
/**
* Override parent getItems to add extra XML metadata.
*
* @since 1.6
*/
public function getItems()
{
$items = parent::getItems();
foreach ($items as &$item)
{
$client = JApplicationHelper::getClientInfo($item->client_id);
$item->xmldata = TemplatesHelper::parseXMLTemplateFile($client->path, $item->element);
}
return $items;
}
/**
* Build an SQL query to load the list data.
*
* @return JDatabaseQuery
* @since 1.6
*/
protected function getListQuery()
{
// Create a new query object.
$db = $this->getDbo();
$query = $db->getQuery(true);
// Select the required fields from the table.
$query->select(
$this->getState(
'list.select',
'a.extension_id, a.name, a.element, a.client_id'
)
);
$query->from($db->quoteName('#__extensions') . ' AS a');
// Filter by extension type.
$query->where($db->quoteName('type') . ' = ' . $db->quote('template'));
// Filter by client.
$clientId = $this->getState('filter.client_id');
if (is_numeric($clientId))
{
$query->where('a.client_id = ' . (int) $clientId);
}
// Filter by search in title
$search = $this->getState('filter.search');
if (!empty($search))
{
if (stripos($search, 'id:') === 0)
{
$query->where('a.id = ' . (int) substr($search, 3));
}
else
{
$search = $db->quote('%' . $db->escape($search, true) . '%');
$query->where('a.element LIKE ' . $search . ' OR a.name LIKE ' . $search);
}
}
// Add the list ordering clause.
$query->order($db->escape($this->getState('list.ordering', 'a.folder')) . ' ' . $db->escape($this->getState('list.direction', 'ASC')));
return $query;
}
/**
* Method to get a store id based on model configuration state.
*
* This is necessary because the model is used by the component and
* different modules that might need different sets of data or different
* ordering requirements.
*
* @param string $id A prefix for the store id.
* @return string A store id.
* @since 1.6
*/
protected function getStoreId($id = '')
{
// Compile the store id.
$id .= ':' . $this->getState('filter.search');
$id .= ':' . $this->getState('filter.client_id');
return parent::getStoreId($id);
}
/**
* Method to auto-populate the model state.
*
* Note. Calling getState in this method will result in recursion.
*
* @since 1.6
*/
protected function populateState($ordering = null, $direction = null)
{
// Load the filter state.
$search = $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search');
$this->setState('filter.search', $search);
$clientId = $this->getUserStateFromRequest($this->context . '.filter.client_id', 'filter_client_id', null);
$this->setState('filter.client_id', $clientId);
// Load the parameters.
$params = JComponentHelper::getParams('com_templates');
$this->setState('params', $params);
// List state information.
parent::populateState('a.element', 'asc');
}
}