Merge branch 'development' of https://github.com/PrestaShop/PrestaShop into development

This commit is contained in:
vAugagneur committed 2013-02-15 11:33:06 +01:00
commit 70f4142fbd
61 files changed
+2397 -1952

No files matched your search

+1
View File
@@ -546,6 +546,7 @@ form#product_form h4 { font-size:18px; font-weight:normal;}
.default_modules_list_display_type #modules_list_container_content li table tr td{border: none} .default_modules_list_display_type #modules_list_container_content li table tr td{border: none}
.default_modules_list_display_type #modules_list_container_content li table {border: solid 1px #ccc; height: 115px} .default_modules_list_display_type #modules_list_container_content li table {border: solid 1px #ccc; height: 115px}
#modules_list_container_tab ul li {margin:5px;height:140px}
/*MODULE POSITION*/ /*MODULE POSITION*/
.blocLiveEdit { float:right; clear:right; background-color: #EBEDF4; border: 1px solid #C2C4D9;display: block; width:250px;} .blocLiveEdit { float:right; clear:right; background-color: #EBEDF4; border: 1px solid #C2C4D9;display: block; width:250px;}
@@ -35,7 +35,7 @@
if (this.value !== "") if (this.value !== "")
location.href = base_url + '&id_category=' + parseInt(this.value); location.href = base_url + '&id_category=' + parseInt(this.value);
else else
location.href = base_url; location.href = base_url + '&reset_filter_category=1';
}); });
// Make sure the checkbox is checked/unchecked when the link is clicked // Make sure the checkbox is checked/unchecked when the link is clicked
@@ -47,7 +47,7 @@
else else
{ {
$(this).find('input').removeAttr('checked'); $(this).find('input').removeAttr('checked');
location.href = base_url; location.href = base_url + '&reset_filter_category=1';
} }
}); });
}); });
@@ -0,0 +1,29 @@
{*
* 2007-2013 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2013 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*}
{foreach from=$export_headers item=header}{$header};{/foreach}
{foreach from=$export_content item=line}
{foreach from=$line item=content}{$content};{/foreach}
{/foreach}
+4 -2
View File
@@ -2325,7 +2325,7 @@ class CartCore extends ObjectModel
public function getDeliveryOption($default_country = null, $dontAutoSelectOptions = false, $use_cache = true) public function getDeliveryOption($default_country = null, $dontAutoSelectOptions = false, $use_cache = true)
{ {
static $cache = array(); static $cache = array();
$cache_id = (int)$default_country.'-'.(int)$dontAutoSelectOptions; $cache_id = (int)(is_object($default_country) ? $default_country->id : 0).'-'.(int)$dontAutoSelectOptions;
if (isset($cache[$cache_id]) && $use_cache) if (isset($cache[$cache_id]) && $use_cache)
return $cache[$cache_id]; return $cache[$cache_id];
@@ -2865,7 +2865,9 @@ class CartCore extends ObjectModel
if ($cart_rule['free_shipping'] && (empty($cart_rule['code']) || preg_match('/^'.CartRule::BO_ORDER_CODE_PREFIX.'[0-9]+/', $cart_rule['code']))) if ($cart_rule['free_shipping'] && (empty($cart_rule['code']) || preg_match('/^'.CartRule::BO_ORDER_CODE_PREFIX.'[0-9]+/', $cart_rule['code'])))
{ {
$cart_rule['value_real'] -= $total_shipping; $cart_rule['value_real'] -= $total_shipping;
$cart_rule['value_tax_exc'] = $total_shipping_tax_exc; $cart_rule['value_tax_exc'] -= $total_shipping_tax_exc;
$total_discounts -= $total_shipping;
$total_discounts_tax_exc -= $total_shipping_tax_exc;
// Update total shipping // Update total shipping
$total_shipping = 0; $total_shipping = 0;
+1 -1
View File
@@ -1048,7 +1048,7 @@ class CategoryCore extends ObjectModel
$result = Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow(' $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow('
SELECT ctg.`id_group` SELECT ctg.`id_group`
FROM '._DB_PREFIX_.'category_group ctg FROM '._DB_PREFIX_.'category_group ctg
WHERE ctg.`id_category` = '.(int)$this->id.' AND ctg.`id_group` = 1 WHERE ctg.`id_category` = '.(int)$this->id.' AND ctg.`id_group` = '.(int)Group::getCurrent()->id.'
'); ');
} else { } else {
$result = Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow(' $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow('
+9 -3
View File
@@ -128,12 +128,18 @@ class MediaCore
public static function packJS($js_content) public static function packJS($js_content)
{ {
if (strlen($js_content) > 0) if (!empty($js_content))
{ {
require_once(_PS_TOOL_DIR_.'js_minify/jsmin.php'); require_once(_PS_TOOL_DIR_.'js_minify/jsmin.php');
return JSMin::minify($js_content); try {
$js_content = JSMin::minify($js_content);
} catch (Exception $e) {
if (_PS_MODE_DEV_)
echo $e->getMessage();
return $js_content;
}
} }
return false; return $js_content;
} }
public static function minifyCSS($css_content, $fileuri = false, &$import_url = array()) public static function minifyCSS($css_content, $fileuri = false, &$import_url = array())
+4 -6
View File
@@ -2668,7 +2668,6 @@ class ProductCore extends ObjectModel
// Add Tax // Add Tax
if ($use_tax) if ($use_tax)
$price = $product_tax_calculator->addTaxes($price); $price = $product_tax_calculator->addTaxes($price);
$price = Tools::ps_round($price, $decimals);
// Reduction // Reduction
$reduc = 0; $reduc = 0;
@@ -2680,14 +2679,14 @@ class ProductCore extends ObjectModel
if (!$specific_price['id_currency']) if (!$specific_price['id_currency'])
$reduction_amount = Tools::convertPrice($reduction_amount, $id_currency); $reduction_amount = Tools::convertPrice($reduction_amount, $id_currency);
$reduc = Tools::ps_round(!$use_tax ? $product_tax_calculator->removeTaxes($reduction_amount) : $reduction_amount, $decimals); $reduc = !$use_tax ? $product_tax_calculator->removeTaxes($reduction_amount) : $reduction_amount;
} }
else else
$reduc = Tools::ps_round($price * $specific_price['reduction'], $decimals); $reduc = $price * $specific_price['reduction'];
} }
if ($only_reduc) if ($only_reduc)
return $reduc; return Tools::ps_round($reduc, $decimals);
if ($use_reduc) if ($use_reduc)
$price -= $reduc; $price -= $reduc;
@@ -2700,7 +2699,6 @@ class ProductCore extends ObjectModel
$price *= ((100 - Group::getReductionByIdGroup($id_group)) / 100); $price *= ((100 - Group::getReductionByIdGroup($id_group)) / 100);
} }
$price = Tools::ps_round($price, $decimals);
// Eco Tax // Eco Tax
if (($result['ecotax'] || isset($result['attribute_ecotax'])) && $with_ecotax) if (($result['ecotax'] || isset($result['attribute_ecotax'])) && $with_ecotax)
{ {
@@ -4236,7 +4234,7 @@ class ProductCore extends ObjectModel
SELECT ctg.`id_group` SELECT ctg.`id_group`
FROM `'._DB_PREFIX_.'category_product` cp FROM `'._DB_PREFIX_.'category_product` cp
INNER JOIN `'._DB_PREFIX_.'category_group` ctg ON (ctg.`id_category` = cp.`id_category`) INNER JOIN `'._DB_PREFIX_.'category_group` ctg ON (ctg.`id_category` = cp.`id_category`)
WHERE cp.`id_product` = '.(int)$this->id.' AND ctg.`id_group` = 1'); WHERE cp.`id_product` = '.(int)$this->id.' AND ctg.`id_group` ='.(int)Group::getCurrent()->id);
else else
return (bool)Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue(' return (bool)Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue('
SELECT cg.`id_group` SELECT cg.`id_group`
+7 -9
View File
@@ -978,11 +978,11 @@ class ToolsCore
if ($allow_accented_chars === null) if ($allow_accented_chars === null)
$allow_accented_chars = Configuration::get('PS_ALLOW_ACCENTED_CHARS_URL'); $allow_accented_chars = Configuration::get('PS_ALLOW_ACCENTED_CHARS_URL');
$str = trim($str);
if (function_exists('mb_strtolower')) if (function_exists('mb_strtolower'))
$str = mb_strtolower($str, 'utf-8'); $str = mb_strtolower($str, 'utf-8');
elseif (!$allow_accented_chars)
$str = trim($str);
if (!function_exists('mb_strtolower') || !$allow_accented_chars)
$str = Tools::replaceAccentedChars($str); $str = Tools::replaceAccentedChars($str);
// Remove all non-whitelist chars. // Remove all non-whitelist chars.
@@ -990,7 +990,7 @@ class ToolsCore
$str = preg_replace('/[^a-zA-Z0-9\s\'\:\/\[\]-\pL]/u', '', $str); $str = preg_replace('/[^a-zA-Z0-9\s\'\:\/\[\]-\pL]/u', '', $str);
else else
$str = preg_replace('/[^a-zA-Z0-9\s\'\:\/\[\]-]/','', $str); $str = preg_replace('/[^a-zA-Z0-9\s\'\:\/\[\]-]/','', $str);
$str = preg_replace('/[\s\'\:\/\[\]-]+/', ' ', $str); $str = preg_replace('/[\s\'\:\/\[\]-]+/', ' ', $str);
$str = str_replace(array(' ', '/'), '-', $str); $str = str_replace(array(' ', '/'), '-', $str);
@@ -1691,11 +1691,9 @@ class ToolsCore
FileETag INode MTime Size FileETag INode MTime Size
<IfModule mod_deflate.c> <IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html <IfModule mod_filter.c>
AddOutputFilterByType DEFLATE text/css AddOutputFilterByType DEFLATE text/html text/css text/javascript application/javascript application/x-javascript
AddOutputFilterByType DEFLATE text/javascript </IfModule>
AddOutputFilterByType DEFLATE application/javascript
AddOutputFilterByType DEFLATE application/x-javascript
</IfModule>\n\n"; </IfModule>\n\n";
fwrite($write_fd, $cache_control); fwrite($write_fd, $cache_control);
} }
+45
View File
@@ -170,6 +170,8 @@ class AdminControllerCore extends Controller
/** @var bool boolean List content lines are clickable if true */ /** @var bool boolean List content lines are clickable if true */
protected $list_no_link = false; protected $list_no_link = false;
protected $allow_export = false;
/** @var array $cache_lang cache for traduction */ /** @var array $cache_lang cache for traduction */
public static $cache_lang = array(); public static $cache_lang = array();
@@ -564,6 +566,39 @@ class AdminControllerCore extends Controller
$this->errors[] = Tools::displayError('An error occurred during image deletion (cannot load object).'); $this->errors[] = Tools::displayError('An error occurred during image deletion (cannot load object).');
return $object; return $object;
} }
public function processExport()
{
// clean buffer
ob_clean();
$this->getList($this->context->language->id);
if (!count($this->_list))
return;
header('Content-type: text/csv');
header('Content-Type: application/force-download; charset=UTF-8');
header('Cache-Control: no-store, no-cache');
header('Content-disposition: attachment; filename="'.$this->table.'_'.date('Y-m-d_His').'.csv"');
$headers = array();
foreach ($this->fields_list as $datas)
$headers[] = $datas['title'];
$content = array();
foreach ($this->_list as $i => $row)
{
$content[$i] = array();
foreach ($this->fields_list as $key => $value)
$content[$i][] = $row[$key];
}
$this->context->smarty->assign(array(
'export_headers' => $headers,
'export_content' => $content
)
);
$this->layout = 'layout-export.tpl';
}
/** /**
* Object Delete * Object Delete
@@ -1025,6 +1060,11 @@ class AdminControllerCore extends Controller
'href' => self::$currentIndex.'&amp;add'.$this->table.'&amp;token='.$this->token, 'href' => self::$currentIndex.'&amp;add'.$this->table.'&amp;token='.$this->token,
'desc' => $this->l('Add new') 'desc' => $this->l('Add new')
); );
if ($this->allow_export)
$this->toolbar_btn['export'] = array(
'href' => self::$currentIndex.'&amp;export'.$this->table.'&amp;token='.$this->token,
'desc' => $this->l('Export')
);
} }
$this->addToolBarModulesListButton(); $this->addToolBarModulesListButton();
} }
@@ -1929,6 +1969,11 @@ class AdminControllerCore extends Controller
else else
$this->errors[] = Tools::displayError('You do not have permission to view here.'); $this->errors[] = Tools::displayError('You do not have permission to view here.');
} }
elseif (isset($_GET['export'.$this->table]))
{
if ($this->tabAccess['view'] === '1')
$this->action = 'export';
}
/* Cancel all filters for this tab */ /* Cancel all filters for this tab */
elseif (isset($_POST['submitReset'.$this->table])) elseif (isset($_POST['submitReset'.$this->table]))
$this->action = 'reset_filters'; $this->action = 'reset_filters';
+6 -1
View File
@@ -68,7 +68,12 @@ class MySQLCore extends Db
*/ */
public function nextRow($result = false) public function nextRow($result = false)
{ {
return mysql_fetch_assoc($result ? $result : $this->result); $return = false;
if(is_resource($result) && $result)
$return = mysql_fetch_assoc($result);
elseif(is_resource($this->_result) && $this->_result)
$return = mysql_fetch_assoc($this->_result);
return $return;
} }
/** /**
-5
View File
@@ -55,11 +55,6 @@ if (defined('_PS_ADMIN_DIR_'))
else else
require_once (dirname(__FILE__).'/smartyfront.config.inc.php'); require_once (dirname(__FILE__).'/smartyfront.config.inc.php');
if (Configuration::get('PS_HTML_THEME_COMPRESSION'))
$smarty->registerFilter('output', 'smartyMinifyHTML');
if (Configuration::get('PS_JS_HTML_THEME_COMPRESSION'))
$smarty->registerFilter('output', 'smartyPackJSinHTML');
smartyRegisterFunction($smarty, 'modifier', 'truncate', 'smarty_modifier_truncate'); smartyRegisterFunction($smarty, 'modifier', 'truncate', 'smarty_modifier_truncate');
smartyRegisterFunction($smarty, 'modifier', 'secureReferrer', array('Tools', 'secureReferrer')); smartyRegisterFunction($smarty, 'modifier', 'secureReferrer', array('Tools', 'secureReferrer'));
+5
View File
@@ -27,6 +27,11 @@
global $smarty; global $smarty;
$smarty->setTemplateDir(_PS_THEME_DIR_.'tpl'); $smarty->setTemplateDir(_PS_THEME_DIR_.'tpl');
if (Configuration::get('PS_HTML_THEME_COMPRESSION'))
$smarty->registerFilter('output', 'smartyMinifyHTML');
if (Configuration::get('PS_JS_HTML_THEME_COMPRESSION'))
$smarty->registerFilter('output', 'smartyPackJSinHTML');
function smartyTranslate($params, &$smarty) function smartyTranslate($params, &$smarty)
{ {
global $_LANG; global $_LANG;
+10 -13
View File
@@ -44,6 +44,8 @@ class AdminAddressesControllerCore extends AdminController
$this->addRowAction('delete'); $this->addRowAction('delete');
$this->bulk_actions = array('delete' => array('text' => $this->l('Delete selected'), 'confirm' => $this->l('Delete selected items?'))); $this->bulk_actions = array('delete' => array('text' => $this->l('Delete selected'), 'confirm' => $this->l('Delete selected items?')));
$this->allow_export = true;
if (!Tools::getValue('realedit')) if (!Tools::getValue('realedit'))
$this->deleted = true; $this->deleted = true;
@@ -61,8 +63,15 @@ class AdminAddressesControllerCore extends AdminController
'country' => array('title' => $this->l('Country'), 'width' => 100, 'type' => 'select', 'list' => $this->countries_array, 'filter_key' => 'cl!id_country')); 'country' => array('title' => $this->l('Country'), 'width' => 100, 'type' => 'select', 'list' => $this->countries_array, 'filter_key' => 'cl!id_country'));
parent::__construct(); parent::__construct();
$this->_select = 'cl.`name` as country';
$this->_join = '
LEFT JOIN `'._DB_PREFIX_.'country_lang` cl ON (cl.`id_country` = a.`id_country` AND cl.`id_lang` = '.(int)$this->context->language->id.')
LEFT JOIN `'._DB_PREFIX_.'customer` c ON a.id_customer = c.id_customer
';
$this->_where = 'AND a.id_customer != 0 '.Shop::addSqlRestriction(Shop::SHARE_CUSTOMER, 'c');
} }
public function initToolbar() public function initToolbar()
{ {
parent::initToolbar(); parent::initToolbar();
@@ -71,18 +80,6 @@ class AdminAddressesControllerCore extends AdminController
'desc' => $this->l('Import') 'desc' => $this->l('Import')
); );
} }
public function renderList()
{
$this->_select = 'cl.`name` as country';
$this->_join = '
LEFT JOIN `'._DB_PREFIX_.'country_lang` cl ON (cl.`id_country` = a.`id_country` AND cl.`id_lang` = '.(int)$this->context->language->id.')
LEFT JOIN `'._DB_PREFIX_.'customer` c ON a.id_customer = c.id_customer
';
$this->_where = 'AND a.id_customer != 0 '.Shop::addSqlRestriction(Shop::SHARE_CUSTOMER, 'c');
return parent::renderList();
}
public function renderForm() public function renderForm()
{ {
@@ -35,6 +35,7 @@ class AdminCartsControllerCore extends AdminController
$this->addRowAction('view'); $this->addRowAction('view');
$this->addRowAction('delete'); $this->addRowAction('delete');
$this->allow_export = true;
$this->_select = 'CONCAT(LEFT(c.`firstname`, 1), \'. \', c.`lastname`) `customer`, a.id_cart total, ca.name carrier, o.id_order, IF(co.id_guest, 1, 0) id_guest'; $this->_select = 'CONCAT(LEFT(c.`firstname`, 1), \'. \', c.`lastname`) `customer`, a.id_cart total, ca.name carrier, o.id_order, IF(co.id_guest, 1, 0) id_guest';
$this->_join = 'LEFT JOIN '._DB_PREFIX_.'customer c ON (c.id_customer = a.id_customer) $this->_join = 'LEFT JOIN '._DB_PREFIX_.'customer c ON (c.id_customer = a.id_customer)
@@ -45,6 +45,7 @@ class AdminCategoriesControllerCore extends AdminController
$this->lang = true; $this->lang = true;
$this->deleted = false; $this->deleted = false;
$this->explicitSelect = true; $this->explicitSelect = true;
$this->allow_export = true;
$this->context = Context::getContext(); $this->context = Context::getContext();
@@ -42,6 +42,8 @@ class AdminCustomersControllerCore extends AdminController
$this->deleted = true; $this->deleted = true;
$this->explicitSelect = true; $this->explicitSelect = true;
$this->allow_export = true;
$this->addRowAction('edit'); $this->addRowAction('edit');
$this->addRowAction('view'); $this->addRowAction('view');
$this->addRowAction('delete'); $this->addRowAction('delete');
@@ -35,6 +35,7 @@ class AdminManufacturersControllerCore extends AdminController
$this->className = 'Manufacturer'; $this->className = 'Manufacturer';
$this->lang = false; $this->lang = false;
$this->deleted = false; $this->deleted = false;
$this->allow_export = true;
$this->bulk_actions = array('delete' => array('text' => $this->l('Delete selected'), 'confirm' => $this->l('Delete selected items?'))); $this->bulk_actions = array('delete' => array('text' => $this->l('Delete selected'), 'confirm' => $this->l('Delete selected items?')));
@@ -64,6 +64,13 @@ class AdminMetaControllerCore extends AdminController
'type' => 'rewriting_settings', 'type' => 'rewriting_settings',
'mod_rewrite' => $mod_rewrite 'mod_rewrite' => $mod_rewrite
), ),
'PS_ALLOW_ACCENTED_CHARS_URL' => array(
'title' => $this->l('Accented URL'),
'desc' => $this->l('Enable if you want to allow accented characters in your friendly URLs.'),
'validation' => 'isBool',
'cast' => 'intval',
'type' => 'bool'
),
'PS_CANONICAL_REDIRECT' => array( 'PS_CANONICAL_REDIRECT' => array(
'title' => $this->l('Automatically redirect to the canonical URL.'), 'title' => $this->l('Automatically redirect to the canonical URL.'),
'desc' => $this->l('Recommended, but your theme must be compliant.'), 'desc' => $this->l('Recommended, but your theme must be compliant.'),
+7 -1
View File
@@ -1072,6 +1072,12 @@ class AdminModulesControllerCore extends AdminController
unset($object); unset($object);
} }
// Don't display categories without modules
$cleaned_list = array();
foreach ($this->list_modules_categories as $k => $list)
if ($list['nb'] > 0)
$cleaned_list[$k] = $list;
// Actually used for the report of the upgraded errors // Actually used for the report of the upgraded errors
if (count($module_errors)) if (count($module_errors))
{ {
@@ -1109,7 +1115,7 @@ class AdminModulesControllerCore extends AdminController
$tpl_vars['nb_modules_uninstalled'] = $tpl_vars['nb_modules'] - $tpl_vars['nb_modules_installed']; $tpl_vars['nb_modules_uninstalled'] = $tpl_vars['nb_modules'] - $tpl_vars['nb_modules_installed'];
$tpl_vars['nb_modules_activated'] = $this->nb_modules_activated; $tpl_vars['nb_modules_activated'] = $this->nb_modules_activated;
$tpl_vars['nb_modules_unactivated'] = $tpl_vars['nb_modules_installed'] - $tpl_vars['nb_modules_activated']; $tpl_vars['nb_modules_unactivated'] = $tpl_vars['nb_modules_installed'] - $tpl_vars['nb_modules_activated'];
$tpl_vars['list_modules_categories'] = $this->list_modules_categories; $tpl_vars['list_modules_categories'] = $cleaned_list;
$tpl_vars['list_modules_authors'] = $this->modules_authors; $tpl_vars['list_modules_authors'] = $this->modules_authors;
$tpl_vars['check_url_fopen'] = (ini_get('allow_url_fopen') ? 'ok' : 'ko'); $tpl_vars['check_url_fopen'] = (ini_get('allow_url_fopen') ? 'ok' : 'ko');
+1 -1
View File
@@ -35,7 +35,7 @@ class AdminOrdersControllerCore extends AdminController
$this->lang = false; $this->lang = false;
$this->addRowAction('view'); $this->addRowAction('view');
$this->explicitSelect = true; $this->explicitSelect = true;
$this->allow_export = true;
$this->deleted = false; $this->deleted = false;
$this->context = Context::getContext(); $this->context = Context::getContext();
+25 -9
View File
@@ -53,6 +53,8 @@ class AdminProductsControllerCore extends AdminController
protected $position_identifier = 'id_product'; protected $position_identifier = 'id_product';
protected $submitted_tabs; protected $submitted_tabs;
protected $id_current_category;
public function __construct() public function __construct()
{ {
@@ -71,6 +73,7 @@ class AdminProductsControllerCore extends AdminController
$this->_defaultOrderBy = 'position'; $this->_defaultOrderBy = 'position';
$this->max_file_size = (int)(Configuration::get('PS_LIMIT_UPLOAD_FILE_VALUE') * 1000000); $this->max_file_size = (int)(Configuration::get('PS_LIMIT_UPLOAD_FILE_VALUE') * 1000000);
$this->max_image_size = (int)Configuration::get('PS_PRODUCT_PICTURE_MAX_SIZE'); $this->max_image_size = (int)Configuration::get('PS_PRODUCT_PICTURE_MAX_SIZE');
$this->allow_export = true;
// @since 1.5 : translations for tabs // @since 1.5 : translations for tabs
$this->available_tabs_lang = array ( $this->available_tabs_lang = array (
@@ -121,17 +124,28 @@ class AdminProductsControllerCore extends AdminController
$this->available_tabs_lang['Module'.ucfirst($m['module'])] = Module::getModuleName($m['module']); $this->available_tabs_lang['Module'.ucfirst($m['module'])] = Module::getModuleName($m['module']);
} }
if (Tools::getValue('reset_filter_category'))
$this->context->cookie->id_category_products_filter = false;
/* Join categories table */ /* Join categories table */
if ($id_category = (int)Tools::getValue('productFilter_cl!name')) if ($id_category = (int)Tools::getValue('productFilter_cl!name'))
{ {
$this->_category = new Category((int)$id_category); $this->_category = new Category((int)$id_category);
$_POST['productFilter_cl!name'] = $this->_category->name[$this->context->language->id]; $_POST['productFilter_cl!name'] = $this->_category->name[$this->context->language->id];
} }
elseif ($id_category = Tools::getvalue('id_category'))
$this->_category = new Category((int)$id_category);
else else
$this->_category = new Category(); {
if ($id_category = (int)Tools::getValue('id_category'))
{
$this->id_current_category = $id_category;
$this->context->cookie->id_category_products_filter = $id_category;
}
elseif ($id_category = $this->context->cookie->id_category_products_filter)
$this->id_current_category = $id_category;
if ($this->id_current_category)
$this->_category = new Category((int)$this->id_current_category);
else
$this->_category = new Category();
}
$join_category = false; $join_category = false;
if (Validate::isLoadedObject($this->_category) && empty($this->_filter)) if (Validate::isLoadedObject($this->_category) && empty($this->_filter))
@@ -241,7 +255,8 @@ class AdminProductsControllerCore extends AdminController
'type' => 'bool', 'type' => 'bool',
'orderby' => false 'orderby' => false
); );
if ((int)Tools::getValue('id_category'))
if ((int)$this->id_current_category)
$this->fields_list['position'] = array( $this->fields_list['position'] = array(
'title' => $this->l('Position'), 'title' => $this->l('Position'),
'width' => 70, 'width' => 70,
@@ -2126,8 +2141,8 @@ class AdminProductsControllerCore extends AdminController
} }
else else
{ {
if ($id_category = (int)Tools::getValue('id_category')) if ($id_category = (int)$this->id_current_category)
self::$currentIndex .= '&id_category='.(int)$id_category; self::$currentIndex .= '&id_category='.(int)$this->id_current_category;
// If products from all categories are displayed, we don't want to use sorting by position // If products from all categories are displayed, we don't want to use sorting by position
if (!$id_category) if (!$id_category)
@@ -2139,8 +2154,9 @@ class AdminProductsControllerCore extends AdminController
unset($this->context->cookie->{$this->table.'Orderway'}); unset($this->context->cookie->{$this->table.'Orderway'});
} }
} }
$id_category = (int)Tools::getValue('id_category', 1); if (!$id_category)
$this->tpl_list_vars['is_category_filter'] = Tools::getValue('id_category') ? true : false; $id_category = 1;
$this->tpl_list_vars['is_category_filter'] = (bool)$this->id_current_category;
// Generate category selection tree // Generate category selection tree
$helper = new Helper(); $helper = new Helper();
@@ -34,6 +34,8 @@ class AdminSuppliersControllerCore extends AdminController
$this->addRowAction('view'); $this->addRowAction('view');
$this->addRowAction('edit'); $this->addRowAction('edit');
$this->addRowAction('delete'); $this->addRowAction('delete');
$this->allow_export = true;
$this->bulk_actions = array('delete' => array('text' => $this->l('Delete selected'), 'confirm' => $this->l('Delete selected items?'))); $this->bulk_actions = array('delete' => array('text' => $this->l('Delete selected'), 'confirm' => $this->l('Delete selected items?')));
$this->_select = 'COUNT(DISTINCT ps.`id_product`) AS products'; $this->_select = 'COUNT(DISTINCT ps.`id_product`) AS products';
+2 -11
View File
@@ -340,19 +340,10 @@ class OrderControllerCore extends ParentOrderController
parent::_assignCarrier(); parent::_assignCarrier();
// Assign wrapping and TOS // Assign wrapping and TOS
$this->_assignWrappingAndTOS(); $this->_assignWrappingAndTOS();
// If a rule offer free-shipping, force hidding shipping prices
$free_shipping = false;
foreach ($this->context->cart->getCartRules() as $rule)
if ($rule['free_shipping'])
{
$free_shipping = true;
break;
}
$this->context->smarty->assign( $this->context->smarty->assign(
array( array(
'free_shipping' => $free_shipping, 'free_shipping' => false, // Deprecated since a cart rule can be applied the specific carriers only
'is_guest' => (isset($this->context->customer->is_guest) ? $this->context->customer->is_guest : 0) 'is_guest' => (isset($this->context->customer->is_guest) ? $this->context->customer->is_guest : 0)
)); ));
} }
+1 -10
View File
@@ -480,15 +480,6 @@ class OrderOpcControllerCore extends ParentOrderController
else else
$link_conditions .= '&content_only=1'; $link_conditions .= '&content_only=1';
// If a rule offer free-shipping, force hidding shipping prices
$free_shipping = false;
foreach ($this->context->cart->getCartRules() as $rule)
if ($rule['free_shipping'])
{
$free_shipping = true;
break;
}
$carriers = $this->context->cart->simulateCarriersOutput(); $carriers = $this->context->cart->simulateCarriersOutput();
$delivery_option = $this->context->cart->getDeliveryOption(null, false, false); $delivery_option = $this->context->cart->getDeliveryOption(null, false, false);
@@ -496,7 +487,7 @@ class OrderOpcControllerCore extends ParentOrderController
$wrapping_fees_tax_inc = $wrapping_fees = $this->context->cart->getGiftWrappingPrice(); $wrapping_fees_tax_inc = $wrapping_fees = $this->context->cart->getGiftWrappingPrice();
$vars = array( $vars = array(
'free_shipping' => $free_shipping, 'free_shipping' => false, // Deprecated since a cart rule can be applied the specific carriers only
'checkedTOS' => (int)($this->context->cookie->checkedTOS), 'checkedTOS' => (int)($this->context->cookie->checkedTOS),
'recyclablePackAllowed' => (int)(Configuration::get('PS_RECYCLABLE_PACK')), 'recyclablePackAllowed' => (int)(Configuration::get('PS_RECYCLABLE_PACK')),
'giftAllowed' => (int)(Configuration::get('PS_GIFT_WRAPPING')), 'giftAllowed' => (int)(Configuration::get('PS_GIFT_WRAPPING')),
@@ -37,6 +37,16 @@ class PageNotFoundControllerCore extends FrontController
{ {
header('HTTP/1.1 404 Not Found'); header('HTTP/1.1 404 Not Found');
header('Status: 404 Not Found'); header('Status: 404 Not Found');
if (in_array(Tools::strtolower(substr($_SERVER['REQUEST_URI'], -3)), array('png', 'jpg', 'gif')))
{
header('Content-Type: image/gif');
readfile(_PS_IMG_DIR_.'img/404.gif');
exit;
}
elseif (in_array(Tools::strtolower(substr($_SERVER['REQUEST_URI'], -3)), array('.js', 'css')))
exit;
parent::initContent(); parent::initContent();
$this->setTemplate(_PS_THEME_DIR_.'404.tpl'); $this->setTemplate(_PS_THEME_DIR_.'404.tpl');
+20 -19
View File
@@ -87,19 +87,11 @@ class ProductControllerCore extends FrontController
{ {
header('HTTP/1.1 404 Not Found'); header('HTTP/1.1 404 Not Found');
header('Status: 404 Not Found'); header('Status: 404 Not Found');
$this->errors[] = Tools::displayError('Product not found');
} }
else
$this->canonicalRedirection();
if (!Validate::isLoadedObject($this->product))
$this->errors[] = Tools::displayError('Product not found');
else else
{ {
if (Pack::isPack((int)$this->product->id) && !Pack::isInStock((int)$this->product->id)) $this->canonicalRedirection();
$this->product->quantity = 0;
$this->product->description = $this->transformDescriptionWithImg($this->product->description);
/* /*
* If the product is associated to the shop * If the product is associated to the shop
* and is active or not active but preview mode (need token + file_exists) * and is active or not active but preview mode (need token + file_exists)
@@ -181,11 +173,14 @@ class ProductControllerCore extends FrontController
if (!$this->errors) if (!$this->errors)
{ {
if (Pack::isPack((int)$this->product->id) && !Pack::isInStock((int)$this->product->id))
$this->product->quantity = 0;
$this->product->description = $this->transformDescriptionWithImg($this->product->description);
// Assign to the template the id of the virtual product. "0" if the product is not downloadable. // Assign to the template the id of the virtual product. "0" if the product is not downloadable.
$this->context->smarty->assign('virtual', ProductDownload::getIdFromIdProduct((int)$this->product->id)); $this->context->smarty->assign('virtual', ProductDownload::getIdFromIdProduct((int)$this->product->id));
// Product pictures management
require_once('images.inc.php');
$this->context->smarty->assign('customizationFormTarget', Tools::safeOutput(urldecode($_SERVER['REQUEST_URI']))); $this->context->smarty->assign('customizationFormTarget', Tools::safeOutput(urldecode($_SERVER['REQUEST_URI'])));
if (Tools::isSubmit('submitCustomizedDatas')) if (Tools::isSubmit('submitCustomizedDatas'))
@@ -204,15 +199,21 @@ class ProductControllerCore extends FrontController
else if (Tools::getIsset('deletePicture') && !$this->context->cart->deleteCustomizationToProduct($this->product->id, Tools::getValue('deletePicture'))) else if (Tools::getIsset('deletePicture') && !$this->context->cart->deleteCustomizationToProduct($this->product->id, Tools::getValue('deletePicture')))
$this->errors[] = Tools::displayError('An error occurred while deleting the selected picture'); $this->errors[] = Tools::displayError('An error occurred while deleting the selected picture');
$files = $this->context->cart->getProductCustomization($this->product->id, Product::CUSTOMIZE_FILE, true);
$pictures = array(); $pictures = array();
foreach ($files as $file)
$pictures['pictures_'.$this->product->id.'_'.$file['index']] = $file['value'];
$texts = $this->context->cart->getProductCustomization($this->product->id, Product::CUSTOMIZE_TEXTFIELD, true);
$text_fields = array(); $text_fields = array();
foreach ($texts as $text_field) if ($this->product->customizable)
$text_fields['textFields_'.$this->product->id.'_'.$text_field['index']] = str_replace('<br />', "\n", $text_field['value']); {
$files = $this->context->cart->getProductCustomization($this->product->id, Product::CUSTOMIZE_FILE, true);
foreach ($files as $file)
$pictures['pictures_'.$this->product->id.'_'.$file['index']] = $file['value'];
$texts = $this->context->cart->getProductCustomization($this->product->id, Product::CUSTOMIZE_TEXTFIELD, true);
foreach ($texts as $text_field)
$text_fields['textFields_'.$this->product->id.'_'.$text_field['index']] = str_replace('<br />', "\n", $text_field['value']);
}
$this->context->smarty->assign(array( $this->context->smarty->assign(array(
'pictures' => $pictures, 'pictures' => $pictures,
'textFields' => $text_fields)); 'textFields' => $text_fields));
+1 -1
View File
@@ -2,5 +2,5 @@
<entity_gender> <entity_gender>
<gender id="Mr" name="M."/> <gender id="Mr" name="M."/>
<gender id="Ms" name="Mme"/> <gender id="Ms" name="Mme"/>
<gender id="Miss" name="Melle"/> <gender id="Miss" name="Mlle"/>
</entity_gender> </entity_gender>
+4 -4
View File
@@ -101,11 +101,11 @@
</div> </div>
<div> <div>
<label><input type="checkbox" id="set_license" class="required" name="licence_agrement" value="1" style="vertical-align: middle;float:left" <?php if ($this->session->licence_agrement): ?>checked="checked"<?php endif; ?> /> <input type="checkbox" id="set_license" class="required" name="licence_agrement" value="1" style="vertical-align: middle;float:left" <?php if ($this->session->licence_agrement): ?>checked="checked"<?php endif; ?> />
<div style="float:left;width:600px;margin-left:8px"><strong><?php echo $this->l('I agree to the above terms and conditions.') ?></strong></div></label> <div style="float:left;width:600px;margin-left:8px"><label for="set_license"><strong><?php echo $this->l('I agree to the above terms and conditions.') ?></strong></label></div>
<br /> <br />
<label><input type="checkbox" name="configuration_agrement" value="1" style="vertical-align: middle;float:left" <?php if ($this->session->configuration_agrement): ?>checked="checked"<?php endif; ?> /> <input type="checkbox" id="configuration_agrement" name="configuration_agrement" value="1" style="vertical-align: middle;float:left" <?php if ($this->session->configuration_agrement): ?>checked="checked"<?php endif; ?> />
<div style="float:left;width:600px;margin-left:8px"><strong><?php echo $this->l('I agree to participate in improving the solution by sending anonymous information about my configuration.') ?></strong></div></label> <div style="float:left;width:600px;margin-left:8px"><label for="configuration_agrement"><strong><?php echo $this->l('I agree to participate in improving the solution by sending anonymous information about my configuration.') ?></strong></label></div>
</div> </div>
<?php $this->displayTemplate('footer') ?> <?php $this->displayTemplate('footer') ?>
@@ -41,7 +41,7 @@ function add_default_restrictions_modules_groups()
FROM `'._DB_PREFIX_.'shop`'); FROM `'._DB_PREFIX_.'shop`');
foreach ($groups as $group) foreach ($groups as $group)
{ {
if (!is_array($modules)) if (!is_array($modules) || !is_array($shops))
return false; return false;
else else
{ {
@@ -49,10 +49,10 @@ function add_default_restrictions_modules_groups()
foreach ($modules as $mod) foreach ($modules as $mod)
foreach ($shops as $s) foreach ($shops as $s)
$sql .= '("'.(int)$mod['id_module'].'", "'.(int)$s.'", "'.(int)$group['id_group'].'"),'; $sql .= '("'.(int)$mod['id_module'].'", "'.(int)$s.'", "'.(int)$group['id_group'].'"),';
// removing last comma to avoid SQL error // removing last comma to avoid SQL error
$sql = substr($sql, 0, strlen($sql) - 1); $sql = substr($sql, 0, strlen($sql) - 1);
$res &= Db::getInstance()->execute($sql); $res &= Db::getInstance()->execute($sql);
} }
} }
return $res; return $res;
} }
@@ -54,29 +54,35 @@ function generate_root_category_for_multishop()
'); ');
$data = array(); $data = array();
foreach ($langs as $lang) if(is_array($shops) && is_array($langs))
foreach ($shops as $shop) {
$data[] = array( foreach ($langs as $lang)
'id_lang' => $lang['id_lang'], foreach ($shops as $shop)
'id_shop' => $shop['id_shop'], $data[] = array(
'id_category' => $id, 'id_lang' => $lang['id_lang'],
'name' => 'Root', 'id_shop' => $shop['id_shop'],
'link_rewrite' => '', 'id_category' => $id,
); 'name' => 'Root',
Db::getInstance()->insert('category_lang', $data); 'link_rewrite' => '',
);
Db::getInstance()->insert('category_lang', $data);
}
$categories = Db::getInstance()->executeS(' $categories = Db::getInstance()->executeS('
SELECT `id_category` SELECT `id_category`
FROM `'._DB_PREFIX_.'category` FROM `'._DB_PREFIX_.'category`
'); ');
$data = array(); $data = array();
foreach ($categories as $category) if(is_array($shops) && is_array($categories))
foreach ($shops as $shop) {
$data[] = array( foreach ($categories as $category)
'id_category' => $category['id_category'], foreach ($shops as $shop)
'id_shop' => $shop['id_shop'] $data[] = array(
); 'id_category' => $category['id_category'],
Db::getInstance()->insert('category_shop', $data); 'id_shop' => $shop['id_shop']
);
Db::getInstance()->insert('category_shop', $data);
}
Db::getInstance()->execute(' Db::getInstance()->execute('
UPDATE `'._DB_PREFIX_.'category` UPDATE `'._DB_PREFIX_.'category`
@@ -90,4 +96,4 @@ function generate_root_category_for_multishop()
'); ');
generate_ntree(); generate_ntree();
} }
@@ -160,22 +160,24 @@ function p15012_add_missing_columns()
if (empty($table)) if (empty($table))
continue; continue;
$list_fields = $db->executeS('SHOW FIELDS FROM `'._DB_PREFIX_.$table.'`'); $list_fields = $db->executeS('SHOW FIELDS FROM `'._DB_PREFIX_.$table.'`');
foreach($list_fields as $k => $field) if (is_array($list_fields))
$list_fields[$k] = $field['Field']; foreach($list_fields as $k => $field)
foreach ($cols as $col => $q) $list_fields[$k] = $field['Field'];
{ if (is_array($cols))
// do only if column exists foreach ($cols as $col => $q)
if (in_array($col, $list_fields))
$do = 'mod';
else
$do = 'add';
if (!empty($q[$do]))
{ {
if (!$db->execute($q[$do])) // do only if column exists
$errors[] = '<subquery><query>'.$q[$do].'</query><error>'.$db->getMsgError().'</error></subquery>'; if (is_array($list_fields) && in_array($col, $list_fields))
$do = 'mod';
else
$do = 'add';
if (!empty($q[$do]))
{
if (!$db->execute($q[$do]))
$errors[] = '<subquery><query>'.$q[$do].'</query><error>'.$db->getMsgError().'</error></subquery>';
}
} }
}
} }
if (sizeof($errors) > 0) if (sizeof($errors) > 0)
@@ -185,5 +187,4 @@ function p15012_add_missing_columns()
} }
else else
return true; return true;
} }
+1 -1
View File
@@ -146,7 +146,7 @@ INSERT INTO `PREFIX_gender_lang` (`id_gender`, `id_lang`, `name`) VALUES
(2, 4, 'Frau'), (2, 4, 'Frau'),
(2, 5, 'Sig.ra'), (2, 5, 'Sig.ra'),
(3, 1, 'Miss'), (3, 1, 'Miss'),
(3, 2, 'Melle'), (3, 2, 'Mlle'),
(3, 3, 'Miss'), (3, 3, 'Miss'),
(3, 4, 'Miss'), (3, 4, 'Miss'),
(3, 5, 'Miss'); (3, 5, 'Miss');
+2 -2
View File
@@ -31,9 +31,9 @@
{include file="$tpl_dir./errors.tpl"} {include file="$tpl_dir./errors.tpl"}
{if isset($confirmation) && $confirmation == 1} {if isset($confirmation) && $confirmation == 1}
<p class="success">{l s='Your password has been successfully reset and a confirmation has been sent to your email address:'} {$smarty.post.email|escape:'htmlall':'UTF-8'|stripslashes}</p> <p class="success">{l s='Your password has been successfully reset and a confirmation has been sent to your email address:'} {if isset($email)}{$email|escape:'htmlall':'UTF-8'|stripslashes}{/if}</p>
{elseif isset($confirmation) && $confirmation == 2} {elseif isset($confirmation) && $confirmation == 2}
<p class="success">{l s='A confirmation email has been sent to your address:'} {$smarty.post.email|escape:'htmlall':'UTF-8'|stripslashes}</p> <p class="success">{l s='A confirmation email has been sent to your address:'} {if isset($email)}{$email|escape:'htmlall':'UTF-8'|stripslashes}{/if}</p>
{else} {else}
<p>{l s='Please enter the email address you used to register. We will then send you a new password. '}</p> <p>{l s='Please enter the email address you used to register. We will then send you a new password. '}</p>
<form action="{$request_uri|escape:'htmlall':'UTF-8'}" method="post" class="std" id="form_forgotpassword"> <form action="{$request_uri|escape:'htmlall':'UTF-8'}" method="post" class="std" id="form_forgotpassword">
+1 -1
View File
@@ -387,7 +387,7 @@ abstract class Controller extends ControllerCore
uasort($queries, 'prestashop_querytime_sort'); uasort($queries, 'prestashop_querytime_sort');
foreach ($queries as $data) foreach ($queries as $data)
{ {
echo $hr.'<b '.$this->getTimeColor($data['time'] * 1000).'>'.round($data['time'] * 1000, 3).' ms</b> '.$data['query'].'<br />in '.$data['file'].':'.$data['line'].'<br />'; echo $hr.'<b '.$this->getTimeColor($data['time'] * 1000).'>'.round($data['time'] * 1000, 3).' ms</b> '.htmlspecialchars($data['query'], ENT_NOQUOTES, 'utf-8', false).'<br />in '.$data['file'].':'.$data['line'].'<br />';
if (preg_match('/^\s*select\s+/i', $data['query'])) if (preg_match('/^\s*select\s+/i', $data['query']))
{ {
$explain = Db::getInstance()->executeS('explain '.$data['query']); $explain = Db::getInstance()->executeS('explain '.$data['query']);
+32 -14
View File
@@ -2,7 +2,7 @@
/** /**
* Project: Smarty: the PHP compiling template engine * Project: Smarty: the PHP compiling template engine
* File: Smarty.class.php * File: Smarty.class.php
* SVN: $Id: Smarty.class.php 4551 2012-02-06 20:45:10Z rodneyrehm $ * SVN: $Id: Smarty.class.php 4694 2013-01-13 21:13:14Z uwe.tews@googlemail.com $
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@@ -28,7 +28,7 @@
* @author Uwe Tews * @author Uwe Tews
* @author Rodney Rehm * @author Rodney Rehm
* @package Smarty * @package Smarty
* @version 3.1.8 * @version 3.1.13
*/ */
/** /**
@@ -57,7 +57,7 @@ if (!defined('SMARTY_PLUGINS_DIR')) {
define('SMARTY_PLUGINS_DIR', SMARTY_DIR . 'plugins' . DS); define('SMARTY_PLUGINS_DIR', SMARTY_DIR . 'plugins' . DS);
} }
if (!defined('SMARTY_MBSTRING')) { if (!defined('SMARTY_MBSTRING')) {
define('SMARTY_MBSTRING', function_exists('mb_strlen')); define('SMARTY_MBSTRING', function_exists('mb_split'));
} }
if (!defined('SMARTY_RESOURCE_CHAR_SET')) { if (!defined('SMARTY_RESOURCE_CHAR_SET')) {
// UTF-8 can only be done properly when mbstring is available! // UTF-8 can only be done properly when mbstring is available!
@@ -113,7 +113,7 @@ class Smarty extends Smarty_Internal_TemplateBase {
/** /**
* smarty version * smarty version
*/ */
const SMARTY_VERSION = 'Smarty-3.1.8'; const SMARTY_VERSION = 'Smarty-3.1.13';
/** /**
* define variable scopes * define variable scopes
@@ -189,8 +189,12 @@ class Smarty extends Smarty_Internal_TemplateBase {
* Flag denoting if PCRE should run in UTF-8 mode * Flag denoting if PCRE should run in UTF-8 mode
*/ */
public static $_UTF8_MODIFIER = 'u'; public static $_UTF8_MODIFIER = 'u';
/**
* Flag denoting if operating system is windows
*/
public static $_IS_WINDOWS = false;
/**#@+ /**#@+
* variables * variables
*/ */
@@ -1277,7 +1281,7 @@ class Smarty extends Smarty_Internal_TemplateBase {
} }
// plugin filename is expected to be: [type].[name].php // plugin filename is expected to be: [type].[name].php
$_plugin_filename = "{$_name_parts[1]}.{$_name_parts[2]}.php"; $_plugin_filename = "{$_name_parts[1]}.{$_name_parts[2]}.php";
$_stream_resolve_include_path = function_exists('stream_resolve_include_path'); $_stream_resolve_include_path = function_exists('stream_resolve_include_path');
// loop through plugin dirs and find the plugin // loop through plugin dirs and find the plugin
@@ -1298,7 +1302,7 @@ class Smarty extends Smarty_Internal_TemplateBase {
} else { } else {
$file = Smarty_Internal_Get_Include_Path::getIncludePath($file); $file = Smarty_Internal_Get_Include_Path::getIncludePath($file);
} }
if ($file !== false) { if ($file !== false) {
require_once($file); require_once($file);
return $file; return $file;
@@ -1388,10 +1392,12 @@ class Smarty extends Smarty_Internal_TemplateBase {
// add the SMARTY_DIR to the list of muted directories // add the SMARTY_DIR to the list of muted directories
if (!isset(Smarty::$_muted_directories[SMARTY_DIR])) { if (!isset(Smarty::$_muted_directories[SMARTY_DIR])) {
$smarty_dir = realpath(SMARTY_DIR); $smarty_dir = realpath(SMARTY_DIR);
Smarty::$_muted_directories[SMARTY_DIR] = array( if ($smarty_dir !== false) {
'file' => $smarty_dir, Smarty::$_muted_directories[SMARTY_DIR] = array(
'length' => strlen($smarty_dir), 'file' => $smarty_dir,
); 'length' => strlen($smarty_dir),
);
}
} }
// walk the muted directories and test against $errfile // walk the muted directories and test against $errfile
@@ -1399,6 +1405,11 @@ class Smarty extends Smarty_Internal_TemplateBase {
if (!$dir) { if (!$dir) {
// resolve directory and length for speedy comparisons // resolve directory and length for speedy comparisons
$file = realpath($key); $file = realpath($key);
if ($file === false) {
// this directory does not exist, remove and skip it
unset(Smarty::$_muted_directories[$key]);
continue;
}
$dir = array( $dir = array(
'file' => $file, 'file' => $file,
'length' => strlen($file), 'length' => strlen($file),
@@ -1464,6 +1475,9 @@ class Smarty extends Smarty_Internal_TemplateBase {
} }
} }
// Check if we're running on windows
Smarty::$_IS_WINDOWS = strtoupper(substr(PHP_OS, 0, 3)) === 'WIN';
// let PCRE (preg_*) treat strings as ISO-8859-1 if we're not dealing with UTF-8 // let PCRE (preg_*) treat strings as ISO-8859-1 if we're not dealing with UTF-8
if (Smarty::$_CHARSET !== 'UTF-8') { if (Smarty::$_CHARSET !== 'UTF-8') {
Smarty::$_UTF8_MODIFIER = ''; Smarty::$_UTF8_MODIFIER = '';
@@ -1474,6 +1488,10 @@ if (Smarty::$_CHARSET !== 'UTF-8') {
* @package Smarty * @package Smarty
*/ */
class SmartyException extends Exception { class SmartyException extends Exception {
public static $escape = true;
public function __construct($message) {
$this->message = self::$escape ? htmlentities($message) : $message;
}
} }
/** /**
@@ -1502,8 +1520,8 @@ function smartyAutoload($class)
'smarty_resource_recompiled' => true, 'smarty_resource_recompiled' => true,
); );
if (preg_match('/^[0-9a-z_-]+$/i', $_class) && !strncmp($_class, 'smarty_internal_', 16) || isset($_classes[$_class])) { if (!strncmp($_class, 'smarty_internal_', 16) || isset($_classes[$_class])) {
include SMARTY_SYSPLUGINS_DIR . $_class . '.php'; include SMARTY_SYSPLUGINS_DIR . $_class . '.php';
} }
} }
@@ -116,6 +116,23 @@ function smarty_function_html_checkboxes($params, $template)
case 'assign': case 'assign':
break; break;
case 'strict': break;
case 'disabled':
case 'readonly':
if (!empty($params['strict'])) {
if (!is_scalar($_val)) {
trigger_error("html_options: $_key attribute must be a scalar, only boolean true or string '$_key' will actually add the attribute", E_USER_NOTICE);
}
if ($_val === true || $_val === $_key) {
$extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_key) . '"';
}
break;
}
// omit break; to fall through!
default: default:
if(!is_array($_val)) { if(!is_array($_val)) {
$extra .= ' '.$_key.'="'.smarty_function_escape_special_chars($_val).'"'; $extra .= ' '.$_key.'="'.smarty_function_escape_special_chars($_val).'"';
+20 -1
View File
@@ -90,7 +90,24 @@ function smarty_function_html_options($params, $template)
$selected = smarty_function_escape_special_chars((string) $_val); $selected = smarty_function_escape_special_chars((string) $_val);
} }
break; break;
case 'strict': break;
case 'disabled':
case 'readonly':
if (!empty($params['strict'])) {
if (!is_scalar($_val)) {
trigger_error("html_options: $_key attribute must be a scalar, only boolean true or string '$_key' will actually add the attribute", E_USER_NOTICE);
}
if ($_val === true || $_val === $_key) {
$extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_key) . '"';
}
break;
}
// omit break; to fall through!
default: default:
if (!is_array($_val)) { if (!is_array($_val)) {
$extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_val) . '"'; $extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_val) . '"';
@@ -150,6 +167,8 @@ function smarty_function_html_options_optoutput($key, $value, $selected, $id, $c
trigger_error("html_options: value is an object of class '". get_class($value) ."' without __toString() method", E_USER_NOTICE); trigger_error("html_options: value is an object of class '". get_class($value) ."' without __toString() method", E_USER_NOTICE);
return ''; return '';
} }
} else {
$value = smarty_function_escape_special_chars((string) $value);
} }
$_html_result .= $_html_class . $_html_id . '>' . $value . '</option>' . "\n"; $_html_result .= $_html_class . $_html_id . '>' . $value . '</option>' . "\n";
$idx++; $idx++;
@@ -102,6 +102,23 @@ function smarty_function_html_radios($params, $template)
case 'assign': case 'assign':
break; break;
case 'strict': break;
case 'disabled':
case 'readonly':
if (!empty($params['strict'])) {
if (!is_scalar($_val)) {
trigger_error("html_options: $_key attribute must be a scalar, only boolean true or string '$_key' will actually add the attribute", E_USER_NOTICE);
}
if ($_val === true || $_val === $_key) {
$extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_key) . '"';
}
break;
}
// omit break; to fall through!
default: default:
if (!is_array($_val)) { if (!is_array($_val)) {
$extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_val) . '"'; $extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_val) . '"';
@@ -35,7 +35,7 @@ function smarty_modifier_date_format($string, $format=null, $default_date='', $f
* Include the {@link shared.make_timestamp.php} plugin * Include the {@link shared.make_timestamp.php} plugin
*/ */
require_once(SMARTY_PLUGINS_DIR . 'shared.make_timestamp.php'); require_once(SMARTY_PLUGINS_DIR . 'shared.make_timestamp.php');
if ($string != '') { if ($string != '' && $string != '0000-00-00' && $string != '0000-00-00 00:00:00') {
$timestamp = smarty_make_timestamp($string); $timestamp = smarty_make_timestamp($string);
} elseif ($default_date != '') { } elseif ($default_date != '') {
$timestamp = smarty_make_timestamp($default_date); $timestamp = smarty_make_timestamp($default_date);
+55 -17
View File
@@ -21,38 +21,76 @@
* @param boolean $double_encode encode already encoded entitites again, used for htmlspecialchars() or htmlentities() * @param boolean $double_encode encode already encoded entitites again, used for htmlspecialchars() or htmlentities()
* @return string escaped input string * @return string escaped input string
*/ */
function smarty_modifier_escape($string, $esc_type = 'html', $char_set = null, $double_encode = true) /* PrestaShop
change double_encode to false by default
function smarty_modifier_escape($string, $esc_type = 'html', $char_set = null, $double_encode = true)
*/
function smarty_modifier_escape($string, $esc_type = 'html', $char_set = null, $double_encode = false)
/* END */
{ {
static $_double_encode = null;
if ($_double_encode === null) {
$_double_encode = version_compare(PHP_VERSION, '5.2.3', '>=');
}
if (!$char_set) { if (!$char_set) {
$char_set = Smarty::$_CHARSET; $char_set = Smarty::$_CHARSET;
} }
switch ($esc_type) { switch ($esc_type) {
case 'html': case 'html':
/* PrestaShop if ($_double_encode) {
return htmlspecialchars($string, ENT_QUOTES, $char_set, $double_encode); // php >=5.3.2 - go native
*/ return htmlspecialchars($string, ENT_QUOTES, $char_set, $double_encode);
return htmlspecialchars($string, ENT_QUOTES, $char_set); } else {
/* END */ if ($double_encode) {
// php <5.2.3 - only handle double encoding
return htmlspecialchars($string, ENT_QUOTES, $char_set);
} else {
// php <5.2.3 - prevent double encoding
$string = preg_replace('!&(#?\w+);!', '%%%SMARTY_START%%%\\1%%%SMARTY_END%%%', $string);
$string = htmlspecialchars($string, ENT_QUOTES, $char_set);
$string = str_replace(array('%%%SMARTY_START%%%', '%%%SMARTY_END%%%'), array('&', ';'), $string);
return $string;
}
}
case 'htmlall': case 'htmlall':
if (Smarty::$_MBSTRING) { if (Smarty::$_MBSTRING) {
// mb_convert_encoding ignores htmlspecialchars() // mb_convert_encoding ignores htmlspecialchars()
/* PrestaShop if ($_double_encode) {
return htmlspecialchars($string, ENT_QUOTES, $char_set, $double_encode); // php >=5.3.2 - go native
*/ $string = htmlspecialchars($string, ENT_QUOTES, $char_set, $double_encode);
return htmlspecialchars($string, ENT_QUOTES, $char_set); } else {
/* END */ if ($double_encode) {
// php <5.2.3 - only handle double encoding
$string = htmlspecialchars($string, ENT_QUOTES, $char_set);
} else {
// php <5.2.3 - prevent double encoding
$string = preg_replace('!&(#?\w+);!', '%%%SMARTY_START%%%\\1%%%SMARTY_END%%%', $string);
$string = htmlspecialchars($string, ENT_QUOTES, $char_set);
$string = str_replace(array('%%%SMARTY_START%%%', '%%%SMARTY_END%%%'), array('&', ';'), $string);
return $string;
}
}
// htmlentities() won't convert everything, so use mb_convert_encoding // htmlentities() won't convert everything, so use mb_convert_encoding
return mb_convert_encoding($string, 'HTML-ENTITIES', $char_set); return mb_convert_encoding($string, 'HTML-ENTITIES', $char_set);
} }
// no MBString fallback // no MBString fallback
/* PrestaShop if ($_double_encode) {
return htmlentities($string, ENT_QUOTES, $char_set, $double_encode); return htmlentities($string, ENT_QUOTES, $char_set, $double_encode);
*/ } else {
return htmlentities($string, ENT_QUOTES, $char_set); if ($double_encode) {
/* END */ return htmlentities($string, ENT_QUOTES, $char_set);
} else {
$string = preg_replace('!&(#?\w+);!', '%%%SMARTY_START%%%\\1%%%SMARTY_END%%%', $string);
$string = htmlentities($string, ENT_QUOTES, $char_set);
$string = str_replace(array('%%%SMARTY_START%%%', '%%%SMARTY_END%%%'), array('&', ';'), $string);
return $string;
}
}
case 'url': case 'url':
return rawurlencode($string); return rawurlencode($string);
@@ -152,4 +190,4 @@ function smarty_modifier_escape($string, $esc_type = 'html', $char_set = null, $
} }
} }
?> ?>
@@ -25,6 +25,11 @@ require_once( SMARTY_PLUGINS_DIR .'shared.literal_compiler_param.php' );
*/ */
function smarty_modifiercompiler_escape($params, $compiler) function smarty_modifiercompiler_escape($params, $compiler)
{ {
static $_double_encode = null;
if ($_double_encode === null) {
$_double_encode = version_compare(PHP_VERSION, '5.2.3', '>=');
}
try { try {
$esc_type = smarty_literal_compiler_param($params, 1, 'html'); $esc_type = smarty_literal_compiler_param($params, 1, 'html');
$char_set = smarty_literal_compiler_param($params, 2, Smarty::$_CHARSET); $char_set = smarty_literal_compiler_param($params, 2, Smarty::$_CHARSET);
@@ -36,48 +41,56 @@ function smarty_modifiercompiler_escape($params, $compiler)
switch ($esc_type) { switch ($esc_type) {
case 'html': case 'html':
/* PrestaShop if ($_double_encode) {
return 'htmlspecialchars(' return 'htmlspecialchars('
. $params[0] .', ENT_QUOTES, '
. var_export($char_set, true) . ', '
. var_export($double_encode, true) . ')';
*/
return 'htmlspecialchars('
. $params[0] .', ENT_QUOTES, '
. var_export($char_set, true) . ')';
/* END */
case 'htmlall':
/* PrestaShop
if (Smarty::$_MBSTRING) {
return 'mb_convert_encoding(htmlspecialchars('
. $params[0] .', ENT_QUOTES, ' . $params[0] .', ENT_QUOTES, '
. var_export($char_set, true) . ', ' . var_export($char_set, true) . ', '
. var_export($double_encode, true) . var_export($double_encode, true) . ')';
. '), "HTML-ENTITIES", ' } else if ($double_encode) {
. var_export($char_set, true) . ')'; return 'htmlspecialchars('
}
*/
if (Smarty::$_MBSTRING) {
return 'mb_convert_encoding(htmlspecialchars('
. $params[0] .', ENT_QUOTES, ' . $params[0] .', ENT_QUOTES, '
. var_export($char_set, true)
. '), "HTML-ENTITIES", '
. var_export($char_set, true) . ')'; . var_export($char_set, true) . ')';
} else {
// fall back to modifier.escape.php
}
case 'htmlall':
if (Smarty::$_MBSTRING) {
if ($_double_encode) {
// php >=5.2.3 - go native
return 'mb_convert_encoding(htmlspecialchars('
. $params[0] .', ENT_QUOTES, '
. var_export($char_set, true) . ', '
. var_export($double_encode, true)
. '), "HTML-ENTITIES", '
. var_export($char_set, true) . ')';
} else if ($double_encode) {
// php <5.2.3 - only handle double encoding
return 'mb_convert_encoding(htmlspecialchars('
. $params[0] .', ENT_QUOTES, '
. var_export($char_set, true)
. '), "HTML-ENTITIES", '
. var_export($char_set, true) . ')';
} else {
// fall back to modifier.escape.php
}
} }
/* END */
// no MBString fallback // no MBString fallback
/* PrestaShop if ($_double_encode) {
return 'htmlentities(' // php >=5.2.3 - go native
. $params[0] .', ENT_QUOTES, ' return 'htmlentities('
. var_export($char_set, true) . ', ' . $params[0] .', ENT_QUOTES, '
. var_export($double_encode, true) . ')'; . var_export($char_set, true) . ', '
*/ . var_export($double_encode, true) . ')';
return 'htmlentities(' } else if ($double_encode) {
. $params[0] .', ENT_QUOTES, ' // php <5.2.3 - only handle double encoding
. var_export($char_set, true) . ')'; return 'htmlentities('
/* END */ . $params[0] .', ENT_QUOTES, '
. var_export($char_set, true) . ')';
} else {
// fall back to modifier.escape.php
}
case 'url': case 'url':
return 'rawurlencode(' . $params[0] . ')'; return 'rawurlencode(' . $params[0] . ')';
@@ -40,6 +40,7 @@ function smarty_outputfilter_trimwhitespace($source, Smarty_Internal_Template $s
} }
// Strip all HTML-Comments // Strip all HTML-Comments
// yes, even the ones in <script> - see http://stackoverflow.com/a/808850/515124
$source = preg_replace( '#<!--.*?-->#ms', '', $source ); $source = preg_replace( '#<!--.*?-->#ms', '', $source );
// capture html elements not to be messed with // capture html elements not to be messed with
@@ -100,9 +100,11 @@ class Smarty_Internal_CacheResource_File extends Smarty_CacheResource {
public function writeCachedContent(Smarty_Internal_Template $_template, $content) public function writeCachedContent(Smarty_Internal_Template $_template, $content)
{ {
if (Smarty_Internal_Write_File::writeFile($_template->cached->filepath, $content, $_template->smarty) === true) { if (Smarty_Internal_Write_File::writeFile($_template->cached->filepath, $content, $_template->smarty) === true) {
$_template->cached->timestamp = filemtime($_template->cached->filepath); $_template->cached->timestamp = @filemtime($_template->cached->filepath);
$_template->cached->exists = !!$_template->cached->timestamp; $_template->cached->exists = !!$_template->cached->timestamp;
return true; if ($_template->cached->exists) {
return true;
}
} }
return false; return false;
} }
@@ -181,7 +183,7 @@ class Smarty_Internal_CacheResource_File extends Smarty_CacheResource {
if (preg_match('/^(\.|\.\.|\.svn|index\.php)$/', $_file->getFilename())) if (preg_match('/^(\.|\.\.|\.svn|index\.php)$/', $_file->getFilename()))
continue; continue;
/* End */ /* End */
// directory ? // directory ?
if ($_file->isDir()) { if ($_file->isDir()) {
if (!$_cache->isDot()) { if (!$_cache->isDot()) {
@@ -39,7 +39,11 @@ class Smarty_Internal_Compile_Assign extends Smarty_Internal_CompileBase {
if ($compiler->tag_nocache || $compiler->nocache) { if ($compiler->tag_nocache || $compiler->nocache) {
$_nocache = 'true'; $_nocache = 'true';
// create nocache var to make it know for further compiling // create nocache var to make it know for further compiling
$compiler->template->tpl_vars[trim($_attr['var'], "'")] = new Smarty_variable(null, true); if (isset($compiler->template->tpl_vars[trim($_attr['var'], "'")])) {
$compiler->template->tpl_vars[trim($_attr['var'], "'")]->nocache = true;
} else {
$compiler->template->tpl_vars[trim($_attr['var'], "'")] = new Smarty_variable(null, true);
}
} }
// scope setup // scope setup
if (isset($_attr['scope'])) { if (isset($_attr['scope'])) {
@@ -58,7 +62,14 @@ class Smarty_Internal_Compile_Assign extends Smarty_Internal_CompileBase {
if (isset($parameter['smarty_internal_index'])) { if (isset($parameter['smarty_internal_index'])) {
$output = "<?php \$_smarty_tpl->createLocalArrayVariable($_attr[var], $_nocache, $_scope);\n\$_smarty_tpl->tpl_vars[$_attr[var]]->value$parameter[smarty_internal_index] = $_attr[value];"; $output = "<?php \$_smarty_tpl->createLocalArrayVariable($_attr[var], $_nocache, $_scope);\n\$_smarty_tpl->tpl_vars[$_attr[var]]->value$parameter[smarty_internal_index] = $_attr[value];";
} else { } else {
$output = "<?php \$_smarty_tpl->tpl_vars[$_attr[var]] = new Smarty_variable($_attr[value], $_nocache, $_scope);"; // implement Smarty2's behaviour of variables assigned by reference
if ($compiler->template->smarty instanceof SmartyBC) {
$output = "<?php if (isset(\$_smarty_tpl->tpl_vars[$_attr[var]])) {\$_smarty_tpl->tpl_vars[$_attr[var]] = clone \$_smarty_tpl->tpl_vars[$_attr[var]];";
$output .= "\n\$_smarty_tpl->tpl_vars[$_attr[var]]->value = $_attr[value]; \$_smarty_tpl->tpl_vars[$_attr[var]]->nocache = $_nocache; \$_smarty_tpl->tpl_vars[$_attr[var]]->scope = $_scope;";
$output .= "\n} else \$_smarty_tpl->tpl_vars[$_attr[var]] = new Smarty_variable($_attr[value], $_nocache, $_scope);";
} else {
$output = "<?php \$_smarty_tpl->tpl_vars[$_attr[var]] = new Smarty_variable($_attr[value], $_nocache, $_scope);";
}
} }
if ($_scope == Smarty::SCOPE_PARENT) { if ($_scope == Smarty::SCOPE_PARENT) {
$output .= "\nif (\$_smarty_tpl->parent != null) \$_smarty_tpl->parent->tpl_vars[$_attr[var]] = clone \$_smarty_tpl->tpl_vars[$_attr[var]];"; $output .= "\nif (\$_smarty_tpl->parent != null) \$_smarty_tpl->parent->tpl_vars[$_attr[var]] = clone \$_smarty_tpl->tpl_vars[$_attr[var]];";
@@ -1,53 +1,55 @@
<?php <?php
/**
* Smarty Internal Plugin Compile Block
*
* Compiles the {block}{/block} tags
*
* @package Smarty
* @subpackage Compiler
* @author Uwe Tews
*/
/** /**
* Smarty Internal Plugin Compile Block Class * Smarty Internal Plugin Compile Block
* *
* @package Smarty * Compiles the {block}{/block} tags
* @subpackage Compiler *
*/ * @package Smarty
* @subpackage Compiler
* @author Uwe Tews
*/
/**
* Smarty Internal Plugin Compile Block Class
*
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_Block extends Smarty_Internal_CompileBase { class Smarty_Internal_Compile_Block extends Smarty_Internal_CompileBase {
/** /**
* Attribute definition: Overwrites base class. * Attribute definition: Overwrites base class.
* *
* @var array * @var array
* @see Smarty_Internal_CompileBase * @see Smarty_Internal_CompileBase
*/ */
public $required_attributes = array('name'); public $required_attributes = array('name');
/** /**
* Attribute definition: Overwrites base class. * Attribute definition: Overwrites base class.
* *
* @var array * @var array
* @see Smarty_Internal_CompileBase * @see Smarty_Internal_CompileBase
*/ */
public $shorttag_order = array('name', 'hide'); public $shorttag_order = array('name', 'hide');
/** /**
* Attribute definition: Overwrites base class. * Attribute definition: Overwrites base class.
* *
* @var array * @var array
* @see Smarty_Internal_CompileBase * @see Smarty_Internal_CompileBase
*/ */
public $optional_attributes = array('hide'); public $optional_attributes = array('hide');
/** /**
* Compiles code for the {block} tag * Compiles code for the {block} tag
* *
* @param array $args array with attributes from parser * @param array $args array with attributes from parser
* @param object $compiler compiler object * @param object $compiler compiler object
* @return boolean true * @return boolean true
*/ */
public function compile($args, $compiler) public function compile($args, $compiler) {
{
// check and get attributes // check and get attributes
$_attr = $this->getAttributes($compiler, $args); $_attr = $this->getAttributes($compiler, $args);
$save = array($_attr, $compiler->parser->current_buffer, $compiler->nocache, $compiler->smarty->merge_compiled_includes, $compiler->merged_templates, $compiler->smarty->merged_templates_func, $compiler->template->properties, $compiler->template->has_nocache_code); $save = array($_attr, $compiler->parser->current_buffer, $compiler->nocache, $compiler->smarty->merge_compiled_includes, $compiler->merged_templates, $compiler->smarty->merged_templates_func, $compiler->template->properties, $compiler->template->has_nocache_code);
@@ -66,18 +68,17 @@ class Smarty_Internal_Compile_Block extends Smarty_Internal_CompileBase {
} }
/** /**
* Save or replace child block source by block name during parsing * Save or replace child block source by block name during parsing
* *
* @param string $block_content block source content * @param string $block_content block source content
* @param string $block_tag opening block tag * @param string $block_tag opening block tag
* @param object $template template object * @param object $template template object
* @param string $filepath filepath of template source * @param string $filepath filepath of template source
*/ */
public static function saveBlockData($block_content, $block_tag, $template, $filepath) public static function saveBlockData($block_content, $block_tag, $template, $filepath) {
{
$_rdl = preg_quote($template->smarty->right_delimiter); $_rdl = preg_quote($template->smarty->right_delimiter);
$_ldl = preg_quote($template->smarty->left_delimiter); $_ldl = preg_quote($template->smarty->left_delimiter);
if ($template->smarty->auto_literal) { if (!$template->smarty->auto_literal) {
$al = '\s*'; $al = '\s*';
} else { } else {
$al = ''; $al = '';
@@ -88,24 +89,34 @@ class Smarty_Internal_Compile_Block extends Smarty_Internal_CompileBase {
} else { } else {
$_name = trim($_match[3], '\'"'); $_name = trim($_match[3], '\'"');
if ($_match[8] != 'hide' || isset($template->block_data[$_name])) { // replace {$smarty.block.child} if ($_match[8] != 'hide' || isset($template->block_data[$_name])) { // replace {$smarty.block.child}
// do we have {$smart.block.child} in nested {block} tags? // get nested block tags
if (0 != preg_match_all("!({$_ldl}{$al}block\s+)(name=)?(\w+|'.*'|\".*\")([\s\S]*?{$_rdl})([\s\S]*?)({$_ldl}{$al}\\\$smarty\.block\.child{$_rdl})([\s\S]*?{$_ldl}{$al}/block{$_rdl})!", $block_content, $_match2)) { if (0 != preg_match_all("!({$_ldl}{$al}block\s+)(name=)?(\w+|'.*'|\".*\")([\s\S]*?)(hide)?(\s*{$_rdl})([\s\S]*?)(.*)?({$_ldl}{$al}/block\s*{$_rdl})!", $block_content, $_match2)) {
foreach($_match2[3] as $name) { foreach ($_match2[3] as $key => $name) {
// get it's replacement // get it's replacement
$_name2 = trim($name, '\'"'); $_name2 = trim($name, '\'"');
if (isset($template->block_data[$_name2])) { if ($_match2[5][$key] != 'hide' || isset($template->block_data[$_name2])) {
$replacement = $template->block_data[$_name2]['source']; if (isset($template->block_data[$_name2])) {
$replacement = $template->block_data[$_name2]['source'];
} else {
$replacement = '';
}
// replace {$smarty.block.child} tag
if (preg_match("!{$_ldl}{$al}\\\$smarty\.block\.child\s*{$_rdl}!",$_match2[7][$key])) {
$replacement = preg_replace("!({$_ldl}{$al}\\\$smarty\.block\.child\s*{$_rdl})!", $replacement, $_match2[7][$key]);
$block_content = preg_replace("!(({$_ldl}{$al}block)(.*)?{$name}(.*)?({$_rdl}[\s\S]*?{$_ldl}{$al}/block\s*{$_rdl}))!", $replacement, $block_content);
}
if (preg_match("!{$_ldl}{$al}\\\$smarty\.block\.child\s*{$_rdl}!",$_match2[8][$key])) {
$replacement = preg_replace("!{$_ldl}{$al}\\\$smarty\.block\.child\s*{$_rdl}!", $replacement, $_match2[8][$key]);
$block_content = preg_replace("!(({$_ldl}{$al}block)(.*)?{$name}(.*)?({$_rdl})(.*)?({$_ldl}{$al}/block\s*{$_rdl}))!", $replacement, $block_content);
}
} else { } else {
$replacement = ''; // remove hidden blocks
$block_content = preg_replace("!(({$_ldl}{$al}block)(.*)?{$name}(.*)?({$_rdl}[\s\S]*?{$_ldl}{$al}/block\s*{$_rdl}))!", '', $block_content);
} }
// replace {$smarty.block.child} tag
$search = array("%({$_ldl}{$al}block[\s\S]*?{$name}[\s\S]*?{$_rdl})([\s\S]*?)({$_ldl}{$al}\\\$smarty\.block\.child{$_rdl})([\s\S]*?)({$_ldl}{$al}/block{$_rdl})%","/§§§child§§§/");
$replace = array('\2§§§child§§§\4', $replacement);
$block_content = preg_replace($search, $replace , $block_content);
} }
} }
// do we have not nested {$smart.block.child} // do we have not nested {$smart.block.child}
if (0 != preg_match("/({$_ldl}{$al}\\\$smarty\.block\.child{$_rdl})/", $block_content, $_match2)) { if (0 != preg_match("!({$_ldl}{$al}\\\$smarty\.block\.child\s*{$_rdl})!", $block_content, $_match2)) {
// get child replacement for this block // get child replacement for this block
if (isset($template->block_data[$_name])) { if (isset($template->block_data[$_name])) {
$replacement = $template->block_data[$_name]['source']; $replacement = $template->block_data[$_name]['source'];
@@ -113,12 +124,12 @@ class Smarty_Internal_Compile_Block extends Smarty_Internal_CompileBase {
} else { } else {
$replacement = ''; $replacement = '';
} }
$block_content = preg_replace("/({$_ldl}{$al}\\\$smarty\.block\.child{$_rdl})/", $replacement, $block_content); $block_content = preg_replace("!({$_ldl}{$al}\\\$smarty\.block\.child\s*{$_rdl})!", $replacement, $block_content);
} }
if (isset($template->block_data[$_name])) { if (isset($template->block_data[$_name])) {
if (strpos($template->block_data[$_name]['source'], '%%%%SMARTY_PARENT%%%%') !== false) { if (strpos($template->block_data[$_name]['source'], '%%%%SMARTY_PARENT%%%%') !== false) {
$template->block_data[$_name]['source'] = $template->block_data[$_name]['source'] =
str_replace('%%%%SMARTY_PARENT%%%%', $block_content, $template->block_data[$_name]['source']); str_replace('%%%%SMARTY_PARENT%%%%', $block_content, $template->block_data[$_name]['source']);
} elseif ($template->block_data[$_name]['mode'] == 'prepend') { } elseif ($template->block_data[$_name]['mode'] == 'prepend') {
$template->block_data[$_name]['source'] .= $block_content; $template->block_data[$_name]['source'] .= $block_content;
} elseif ($template->block_data[$_name]['mode'] == 'append') { } elseif ($template->block_data[$_name]['mode'] == 'append') {
@@ -140,21 +151,20 @@ class Smarty_Internal_Compile_Block extends Smarty_Internal_CompileBase {
} }
/** /**
* Compile saved child block source * Compile saved child block source
* *
* @param object $compiler compiler object * @param object $compiler compiler object
* @param string $_name optional name of child block * @param string $_name optional name of child block
* @return string compiled code of schild block * @return string compiled code of schild block
*/ */
public static function compileChildBlock($compiler, $_name = null) public static function compileChildBlock($compiler, $_name = null) {
{
$_output = ''; $_output = '';
// if called by {$smarty.block.child} we must search the name of enclosing {block} // if called by {$smarty.block.child} we must search the name of enclosing {block}
if ($_name == null) { if ($_name == null) {
$stack_count = count($compiler->_tag_stack); $stack_count = count($compiler->_tag_stack);
while (--$stack_count >= 0) { while (--$stack_count >= 0) {
if ($compiler->_tag_stack[$stack_count][0] == 'block') { if ($compiler->_tag_stack[$stack_count][0] == 'block') {
$_name = trim($compiler->_tag_stack[$stack_count][1][0]['name'] ,"'\""); $_name = trim($compiler->_tag_stack[$stack_count][1][0]['name'], "'\"");
break; break;
} }
} }
@@ -168,8 +178,8 @@ class Smarty_Internal_Compile_Block extends Smarty_Internal_CompileBase {
if (!isset($compiler->template->block_data[$_name]['source'])) { if (!isset($compiler->template->block_data[$_name]['source'])) {
return ''; return '';
} }
$_tpl = new Smarty_Internal_template ('string:' . $compiler->template->block_data[$_name]['source'], $compiler->smarty, $compiler->template, $compiler->template->cache_id, $_tpl = new Smarty_Internal_template('string:' . $compiler->template->block_data[$_name]['source'], $compiler->smarty, $compiler->template, $compiler->template->cache_id,
$compiler->template->compile_id = null, $compiler->template->caching, $compiler->template->cache_lifetime); $compiler->template->compile_id = null, $compiler->template->caching, $compiler->template->cache_lifetime);
$_tpl->variable_filters = $compiler->template->variable_filters; $_tpl->variable_filters = $compiler->template->variable_filters;
$_tpl->properties['nocache_hash'] = $compiler->template->properties['nocache_hash']; $_tpl->properties['nocache_hash'] = $compiler->template->properties['nocache_hash'];
$_tpl->source->filepath = $compiler->template->block_data[$_name]['file']; $_tpl->source->filepath = $compiler->template->block_data[$_name]['file'];
@@ -198,14 +208,14 @@ class Smarty_Internal_Compile_Block extends Smarty_Internal_CompileBase {
if ($_tpl->has_nocache_code) { if ($_tpl->has_nocache_code) {
$compiler->template->has_nocache_code = true; $compiler->template->has_nocache_code = true;
} }
foreach($_tpl->required_plugins as $key => $tmp1) { foreach ($_tpl->required_plugins as $key => $tmp1) {
if ($compiler->nocache) { if ($compiler->nocache && $compiler->template->caching) {
$code = 'nocache'; $code = 'nocache';
} else { } else {
$code = $key; $code = $key;
} }
foreach($tmp1 as $name => $tmp) { foreach ($tmp1 as $name => $tmp) {
foreach($tmp as $type => $data) { foreach ($tmp as $type => $data) {
$compiler->template->required_plugins[$code][$name][$type] = $data; $compiler->template->required_plugins[$code][$name][$type] = $data;
} }
} }
@@ -217,22 +227,21 @@ class Smarty_Internal_Compile_Block extends Smarty_Internal_CompileBase {
} }
/** /**
* Smarty Internal Plugin Compile BlockClose Class * Smarty Internal Plugin Compile BlockClose Class
* *
* @package Smarty * @package Smarty
* @subpackage Compiler * @subpackage Compiler
*/ */
class Smarty_Internal_Compile_Blockclose extends Smarty_Internal_CompileBase { class Smarty_Internal_Compile_Blockclose extends Smarty_Internal_CompileBase {
/** /**
* Compiles code for the {/block} tag * Compiles code for the {/block} tag
* *
* @param array $args array with attributes from parser * @param array $args array with attributes from parser
* @param object $compiler compiler object * @param object $compiler compiler object
* @return string compiled code * @return string compiled code
*/ */
public function compile($args, $compiler) public function compile($args, $compiler) {
{
$compiler->has_code = true; $compiler->has_code = true;
// check and get attributes // check and get attributes
$_attr = $this->getAttributes($compiler, $args); $_attr = $this->getAttributes($compiler, $args);
@@ -255,12 +264,12 @@ class Smarty_Internal_Compile_Blockclose extends Smarty_Internal_CompileBase {
} else { } else {
$_output = $compiler->parser->current_buffer->to_smarty_php(); $_output = $compiler->parser->current_buffer->to_smarty_php();
} }
unset ($compiler->template->block_data[$_name]['compiled']); unset($compiler->template->block_data[$_name]['compiled']);
} }
// reset flags // reset flags
$compiler->parser->current_buffer = $saved_data[1]; $compiler->parser->current_buffer = $saved_data[1];
$compiler->nocache = $saved_data[2]; $compiler->nocache = $saved_data[2];
//$compiler->smarty->merge_compiled_includes = $saved_data[3]; $compiler->smarty->merge_compiled_includes = $saved_data[3];
// reset flag for {block} tag // reset flag for {block} tag
$compiler->inheritance = false; $compiler->inheritance = false;
// $_output content has already nocache code processed // $_output content has already nocache code processed
@@ -51,6 +51,11 @@ class Smarty_Internal_Compile_Extends extends Smarty_Internal_CompileBase {
static $_is_stringy = array('string' => true, 'eval' => true); static $_is_stringy = array('string' => true, 'eval' => true);
$this->_rdl = preg_quote($compiler->smarty->right_delimiter); $this->_rdl = preg_quote($compiler->smarty->right_delimiter);
$this->_ldl = preg_quote($compiler->smarty->left_delimiter); $this->_ldl = preg_quote($compiler->smarty->left_delimiter);
if (!$compiler->smarty->auto_literal) {
$al = '\s*';
} else {
$al = '';
}
$filepath = $compiler->template->source->filepath; $filepath = $compiler->template->source->filepath;
$this->mbstring_overload = ini_get('mbstring.func_overload') & 2; $this->mbstring_overload = ini_get('mbstring.func_overload') & 2;
// check and get attributes // check and get attributes
@@ -77,12 +82,12 @@ class Smarty_Internal_Compile_Extends extends Smarty_Internal_CompileBase {
$compiler->trigger_template_error("illegal recursive call of \"{$include_file}\"", $compiler->lex->line - 1); $compiler->trigger_template_error("illegal recursive call of \"{$include_file}\"", $compiler->lex->line - 1);
} }
$compiler->template->properties['file_dependency'][$template_sha1] = array($_template->source->filepath, $_template->source->timestamp, $_template->source->type); $compiler->template->properties['file_dependency'][$template_sha1] = array($_template->source->filepath, $_template->source->timestamp, $_template->source->type);
$_content = ($this->mbstring_overload ? mb_substr($compiler->template->source->content, $compiler->lex->counter - 1, 20000000, 'latin1') : substr($compiler->template->source->content, $compiler->lex->counter - 1)); $_content = ($this->mbstring_overload ? mb_substr($compiler->lex->data, $compiler->lex->counter - 1, 20000000, 'latin1') : substr($compiler->lex->data, $compiler->lex->counter - 1));
if (preg_match_all("!({$this->_ldl}block\s(.+?){$this->_rdl})!", $_content, $s) != if (preg_match_all("!({$this->_ldl}{$al}block\s(.+?)\s*{$this->_rdl})!", $_content, $s) !=
preg_match_all("!({$this->_ldl}/block{$this->_rdl})!", $_content, $c)) { preg_match_all("!({$this->_ldl}{$al}/block\s*{$this->_rdl})!", $_content, $c)) {
$compiler->trigger_template_error('unmatched {block} {/block} pairs'); $compiler->trigger_template_error('unmatched {block} {/block} pairs');
} }
preg_match_all("!{$this->_ldl}block\s(.+?){$this->_rdl}|{$this->_ldl}/block{$this->_rdl}|{$this->_ldl}\*([\S\s]*?)\*{$this->_rdl}!", $_content, $_result, PREG_OFFSET_CAPTURE); preg_match_all("!{$this->_ldl}{$al}block\s(.+?)\s*{$this->_rdl}|{$this->_ldl}{$al}/block\s*{$this->_rdl}|{$this->_ldl}\*([\S\s]*?)\*{$this->_rdl}!", $_content, $_result, PREG_OFFSET_CAPTURE);
$_result_count = count($_result[0]); $_result_count = count($_result[0]);
$_start = 0; $_start = 0;
while ($_start+1 < $_result_count) { while ($_start+1 < $_result_count) {
@@ -149,7 +149,8 @@ class Smarty_Internal_Compile_Functionclose extends Smarty_Internal_CompileBase
$compiler->has_code = false; $compiler->has_code = false;
$output = true; $output = true;
} else { } else {
$output = $plugins_string . $compiler->parser->current_buffer->to_smarty_php() . "<?php \$_smarty_tpl->tpl_vars = \$saved_tpl_vars;}}?>\n"; $output = $plugins_string . $compiler->parser->current_buffer->to_smarty_php() . "<?php \$_smarty_tpl->tpl_vars = \$saved_tpl_vars;
foreach (Smarty::\$global_tpl_vars as \$key => \$value) if(!isset(\$_smarty_tpl->tpl_vars[\$key])) \$_smarty_tpl->tpl_vars[\$key] = \$value;}}?>\n";
} }
// reset flag that we are compiling a template function // reset flag that we are compiling a template function
$compiler->compiles_template_function = false; $compiler->compiles_template_function = false;
@@ -26,8 +26,7 @@ class Smarty_Internal_Compile_Private_Modifier extends Smarty_Internal_CompileBa
* @param array $parameter array with compilation parameter * @param array $parameter array with compilation parameter
* @return string compiled code * @return string compiled code
*/ */
public function compile($args, $compiler, $parameter) public function compile($args, $compiler, $parameter) {
{
// check and get attributes // check and get attributes
$_attr = $this->getAttributes($compiler, $args); $_attr = $this->getAttributes($compiler, $args);
$output = $parameter['value']; $output = $parameter['value'];
@@ -36,40 +35,100 @@ class Smarty_Internal_Compile_Private_Modifier extends Smarty_Internal_CompileBa
$modifier = $single_modifier[0]; $modifier = $single_modifier[0];
$single_modifier[0] = $output; $single_modifier[0] = $output;
$params = implode(',', $single_modifier); $params = implode(',', $single_modifier);
// check for registered modifier // check if we know already the type of modifier
if (isset($compiler->smarty->registered_plugins[Smarty::PLUGIN_MODIFIER][$modifier])) { if (isset($compiler->known_modifier_type[$modifier])) {
$function = $compiler->smarty->registered_plugins[Smarty::PLUGIN_MODIFIER][$modifier][0]; $modifier_types = array($compiler->known_modifier_type[$modifier]);
if (!is_array($function)) {
$output = "{$function}({$params})";
} else {
if (is_object($function[0])) {
$output = '$_smarty_tpl->smarty->registered_plugins[Smarty::PLUGIN_MODIFIER][\'' . $modifier . '\'][0][0]->' . $function[1] . '(' . $params . ')';
} else {
$output = $function[0] . '::' . $function[1] . '(' . $params . ')';
}
}
} else if (isset($compiler->smarty->registered_plugins[Smarty::PLUGIN_MODIFIERCOMPILER][$modifier][0])) {
$output = call_user_func($compiler->smarty->registered_plugins[Smarty::PLUGIN_MODIFIERCOMPILER][$modifier][0], $single_modifier, $compiler->smarty);
// check for plugin modifiercompiler
} else if ($compiler->smarty->loadPlugin('smarty_modifiercompiler_' . $modifier)) {
// check if modifier allowed
if (!is_object($compiler->smarty->security_policy) || $compiler->smarty->security_policy->isTrustedModifier($modifier, $compiler)) {
$plugin = 'smarty_modifiercompiler_' . $modifier;
$output = $plugin($single_modifier, $compiler);
}
// check for plugin modifier
} else if ($function = $compiler->getPlugin($modifier, Smarty::PLUGIN_MODIFIER)) {
// check if modifier allowed
if (!is_object($compiler->smarty->security_policy) || $compiler->smarty->security_policy->isTrustedModifier($modifier, $compiler)) {
$output = "{$function}({$params})";
}
// check if trusted PHP function
} else if (is_callable($modifier)) {
// check if modifier allowed
if (!is_object($compiler->smarty->security_policy) || $compiler->smarty->security_policy->isTrustedPhpModifier($modifier, $compiler)) {
$output = "{$modifier}({$params})";
}
} else { } else {
$modifier_types = array(1, 2, 3, 4, 5, 6);
}
foreach ($modifier_types as $type) {
switch ($type) {
case 1:
// registered modifier
if (isset($compiler->smarty->registered_plugins[Smarty::PLUGIN_MODIFIER][$modifier])) {
$function = $compiler->smarty->registered_plugins[Smarty::PLUGIN_MODIFIER][$modifier][0];
if (!is_array($function)) {
$output = "{$function}({$params})";
} else {
if (is_object($function[0])) {
$output = '$_smarty_tpl->smarty->registered_plugins[Smarty::PLUGIN_MODIFIER][\'' . $modifier . '\'][0][0]->' . $function[1] . '(' . $params . ')';
} else {
$output = $function[0] . '::' . $function[1] . '(' . $params . ')';
}
}
$compiler->known_modifier_type[$modifier] = $type;
break 2;
}
break;
case 2:
// registered modifier compiler
if (isset($compiler->smarty->registered_plugins[Smarty::PLUGIN_MODIFIERCOMPILER][$modifier][0])) {
$output = call_user_func($compiler->smarty->registered_plugins[Smarty::PLUGIN_MODIFIERCOMPILER][$modifier][0], $single_modifier, $compiler->smarty);
$compiler->known_modifier_type[$modifier] = $type;
break 2;
}
break;
case 3:
// modifiercompiler plugin
if ($compiler->smarty->loadPlugin('smarty_modifiercompiler_' . $modifier)) {
// check if modifier allowed
if (!is_object($compiler->smarty->security_policy) || $compiler->smarty->security_policy->isTrustedModifier($modifier, $compiler)) {
$plugin = 'smarty_modifiercompiler_' . $modifier;
$output = $plugin($single_modifier, $compiler);
}
$compiler->known_modifier_type[$modifier] = $type;
break 2;
}
break;
case 4:
// modifier plugin
if ($function = $compiler->getPlugin($modifier, Smarty::PLUGIN_MODIFIER)) {
// check if modifier allowed
if (!is_object($compiler->smarty->security_policy) || $compiler->smarty->security_policy->isTrustedModifier($modifier, $compiler)) {
$output = "{$function}({$params})";
}
$compiler->known_modifier_type[$modifier] = $type;
break 2;
}
break;
case 5:
// PHP function
if (is_callable($modifier)) {
// check if modifier allowed
if (!is_object($compiler->smarty->security_policy) || $compiler->smarty->security_policy->isTrustedPhpModifier($modifier, $compiler)) {
$output = "{$modifier}({$params})";
}
$compiler->known_modifier_type[$modifier] = $type;
break 2;
}
break;
case 6:
// default plugin handler
if (isset($compiler->default_handler_plugins[Smarty::PLUGIN_MODIFIER][$modifier]) || (is_callable($compiler->smarty->default_plugin_handler_func) && $compiler->getPluginFromDefaultHandler($modifier, Smarty::PLUGIN_MODIFIER))) {
$function = $compiler->default_handler_plugins[Smarty::PLUGIN_MODIFIER][$modifier][0];
// check if modifier allowed
if (!is_object($compiler->smarty->security_policy) || $compiler->smarty->security_policy->isTrustedModifier($modifier, $compiler)) {
if (!is_array($function)) {
$output = "{$function}({$params})";
} else {
if (is_object($function[0])) {
$output = '$_smarty_tpl->smarty->registered_plugins[Smarty::PLUGIN_MODIFIER][\'' . $modifier . '\'][0][0]->' . $function[1] . '(' . $params . ')';
} else {
$output = $function[0] . '::' . $function[1] . '(' . $params . ')';
}
}
}
if (isset($compiler->template->required_plugins['nocache'][$modifier][Smarty::PLUGIN_MODIFIER]['file']) || isset($compiler->template->required_plugins['compiled'][$modifier][Smarty::PLUGIN_MODIFIER]['file'])) {
// was a plugin
$compiler->known_modifier_type[$modifier] = 4;
} else {
$compiler->known_modifier_type[$modifier] = $type;
}
break 2;
}
}
}
if (!isset($compiler->known_modifier_type[$modifier])) {
$compiler->trigger_template_error("unknown modifier \"" . $modifier . "\"", $compiler->lex->taglineno); $compiler->trigger_template_error("unknown modifier \"" . $modifier . "\"", $compiler->lex->taglineno);
} }
} }
@@ -77,10 +77,14 @@ class Smarty_Internal_Compile_Private_Special_Variable extends Smarty_Internal_C
$compiler->trigger_template_error("(secure mode) constants not permitted"); $compiler->trigger_template_error("(secure mode) constants not permitted");
break; break;
} }
return '@' . trim($_index[1], "'"); return "@constant({$_index[1]})";
case 'config': case 'config':
return "\$_smarty_tpl->getConfigVariable($_index[1])"; if (isset($_index[2])) {
return "(is_array(\$tmp = \$_smarty_tpl->getConfigVariable($_index[1])) ? \$tmp[$_index[2]] : null)";
} else {
return "\$_smarty_tpl->getConfigVariable($_index[1])";
}
case 'ldelim': case 'ldelim':
$_ldelim = $compiler->smarty->left_delimiter; $_ldelim = $compiler->smarty->left_delimiter;
return "'$_ldelim'"; return "'$_ldelim'";
@@ -240,9 +240,8 @@ class Smarty_Internal_Config {
} }
// scan sections // scan sections
if (!empty($sections)) { if (!empty($sections)) {
$sections = array_flip((array) $sections); foreach ((array) $sections as $this_section) {
foreach ($_config_vars['sections'] as $this_section => $dummy) { if (isset($_config_vars['sections'][$this_section])) {
if (isset($sections[$this_section])) {
foreach ($_config_vars['sections'][$this_section]['vars'] as $variable => $value) { foreach ($_config_vars['sections'][$this_section]['vars'] as $variable => $value) {
if ($this->smarty->config_overwrite || !isset($scope_ptr->config_vars[$variable])) { if ($this->smarty->config_overwrite || !isset($scope_ptr->config_vars[$variable])) {
$scope_ptr->config_vars[$variable] = $value; $scope_ptr->config_vars[$variable] = $value;
@@ -80,6 +80,11 @@ class Smarty_Internal_Data {
{ {
if ($varname != '') { if ($varname != '') {
Smarty::$global_tpl_vars[$varname] = new Smarty_variable($value, $nocache); Smarty::$global_tpl_vars[$varname] = new Smarty_variable($value, $nocache);
$ptr = $this;
while ($ptr instanceof Smarty_Internal_Template) {
$ptr->tpl_vars[$varname] = clone Smarty::$global_tpl_vars[$varname];
$ptr = $ptr->parent;
}
} }
return $this; return $this;
@@ -89,6 +89,11 @@ class Smarty_Internal_Resource_Extends extends Smarty_Resource {
$this->mbstring_overload = ini_get('mbstring.func_overload') & 2; $this->mbstring_overload = ini_get('mbstring.func_overload') & 2;
$_rdl = preg_quote($source->smarty->right_delimiter); $_rdl = preg_quote($source->smarty->right_delimiter);
$_ldl = preg_quote($source->smarty->left_delimiter); $_ldl = preg_quote($source->smarty->left_delimiter);
if (!$source->smarty->auto_literal) {
$al = '\s*';
} else {
$al = '';
}
$_components = array_reverse($source->components); $_components = array_reverse($source->components);
$_first = reset($_components); $_first = reset($_components);
$_last = end($_components); $_last = end($_components);
@@ -105,11 +110,11 @@ class Smarty_Internal_Resource_Extends extends Smarty_Resource {
// extend sources // extend sources
if ($_component != $_last) { if ($_component != $_last) {
if (preg_match_all("!({$_ldl}block\s(.+?){$_rdl})!", $_content, $_open) != if (preg_match_all("!({$_ldl}{$al}block\s(.+?)\s*{$_rdl})!", $_content, $_open) !=
preg_match_all("!({$_ldl}/block{$_rdl})!", $_content, $_close)) { preg_match_all("!({$_ldl}{$al}/block\s*{$_rdl})!", $_content, $_close)) {
throw new SmartyException("unmatched {block} {/block} pairs in template {$_component->type} '{$_component->name}'"); throw new SmartyException("unmatched {block} {/block} pairs in template {$_component->type} '{$_component->name}'");
} }
preg_match_all("!{$_ldl}block\s(.+?){$_rdl}|{$_ldl}/block{$_rdl}|{$_ldl}\*([\S\s]*?)\*{$_rdl}!", $_content, $_result, PREG_OFFSET_CAPTURE); preg_match_all("!{$_ldl}{$al}block\s(.+?)\s*{$_rdl}|{$_ldl}{$al}/block\s*{$_rdl}|{$_ldl}\*([\S\s]*?)\*{$_rdl}!", $_content, $_result, PREG_OFFSET_CAPTURE);
$_result_count = count($_result[0]); $_result_count = count($_result[0]);
$_start = 0; $_start = 0;
while ($_start+1 < $_result_count) { while ($_start+1 < $_result_count) {
@@ -1,36 +1,40 @@
<?php <?php
/** /**
* Smarty Internal Plugin Resource Stream * Smarty Internal Plugin Resource Stream
* *
* Implements the streams as resource for Smarty template * Implements the streams as resource for Smarty template
* *
* @package Smarty * @package Smarty
* @subpackage TemplateResources * @subpackage TemplateResources
* @author Uwe Tews * @author Uwe Tews
* @author Rodney Rehm * @author Rodney Rehm
*/ */
/** /**
* Smarty Internal Plugin Resource Stream * Smarty Internal Plugin Resource Stream
* *
* Implements the streams as resource for Smarty template * Implements the streams as resource for Smarty template
* *
* @link http://php.net/streams * @link http://php.net/streams
* @package Smarty * @package Smarty
* @subpackage TemplateResources * @subpackage TemplateResources
*/ */
class Smarty_Internal_Resource_Stream extends Smarty_Resource_Recompiled { class Smarty_Internal_Resource_Stream extends Smarty_Resource_Recompiled {
/** /**
* populate Source Object with meta data from Resource * populate Source Object with meta data from Resource
* *
* @param Smarty_Template_Source $source source object * @param Smarty_Template_Source $source source object
* @param Smarty_Internal_Template $_template template object * @param Smarty_Internal_Template $_template template object
* @return void * @return void
*/ */
public function populate(Smarty_Template_Source $source, Smarty_Internal_Template $_template=null) public function populate(Smarty_Template_Source $source, Smarty_Internal_Template $_template=null)
{ {
$source->filepath = str_replace(':', '://', $source->resource); if(strpos($source->resource, '://') !== false) {
$source->filepath = $source->resource;
} else {
$source->filepath = str_replace(':', '://', $source->resource);
}
$source->uid = false; $source->uid = false;
$source->content = $this->getContent($source); $source->content = $this->getContent($source);
$source->timestamp = false; $source->timestamp = false;
@@ -38,12 +42,12 @@ class Smarty_Internal_Resource_Stream extends Smarty_Resource_Recompiled {
} }
/** /**
* Load template's source from stream into current template object * Load template's source from stream into current template object
* *
* @param Smarty_Template_Source $source source object * @param Smarty_Template_Source $source source object
* @return string template source * @return string template source
* @throws SmartyException if source cannot be loaded * @throws SmartyException if source cannot be loaded
*/ */
public function getContent(Smarty_Template_Source $source) public function getContent(Smarty_Template_Source $source)
{ {
$t = ''; $t = '';
@@ -59,18 +63,16 @@ class Smarty_Internal_Resource_Stream extends Smarty_Resource_Recompiled {
return false; return false;
} }
} }
/** /**
* modify resource_name according to resource handlers specifications * modify resource_name according to resource handlers specifications
* *
* @param Smarty $smarty Smarty instance * @param Smarty $smarty Smarty instance
* @param string $resource_name resource_name to make unique * @param string $resource_name resource_name to make unique
* @return string unique resource name * @return string unique resource name
*/ */
protected function buildUniqueResourceName(Smarty $smarty, $resource_name) protected function buildUniqueResourceName(Smarty $smarty, $resource_name)
{ {
return get_class($this) . '#' . $resource_name; return get_class($this) . '#' . $resource_name;
} }
} }
?>
@@ -266,6 +266,7 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase {
// get variables from calling scope // get variables from calling scope
if ($parent_scope == Smarty::SCOPE_LOCAL) { if ($parent_scope == Smarty::SCOPE_LOCAL) {
$tpl->tpl_vars = $this->tpl_vars; $tpl->tpl_vars = $this->tpl_vars;
$tpl->tpl_vars['smarty'] = clone $this->tpl_vars['smarty'];
} elseif ($parent_scope == Smarty::SCOPE_PARENT) { } elseif ($parent_scope == Smarty::SCOPE_PARENT) {
$tpl->tpl_vars = &$this->tpl_vars; $tpl->tpl_vars = &$this->tpl_vars;
} elseif ($parent_scope == Smarty::SCOPE_GLOBAL) { } elseif ($parent_scope == Smarty::SCOPE_GLOBAL) {
@@ -305,6 +306,7 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase {
// get variables from calling scope // get variables from calling scope
if ($parent_scope == Smarty::SCOPE_LOCAL ) { if ($parent_scope == Smarty::SCOPE_LOCAL ) {
$tpl->tpl_vars = $this->tpl_vars; $tpl->tpl_vars = $this->tpl_vars;
$tpl->tpl_vars['smarty'] = clone $this->tpl_vars['smarty'];
} elseif ($parent_scope == Smarty::SCOPE_PARENT) { } elseif ($parent_scope == Smarty::SCOPE_PARENT) {
$tpl->tpl_vars = &$this->tpl_vars; $tpl->tpl_vars = &$this->tpl_vars;
} elseif ($parent_scope == Smarty::SCOPE_GLOBAL) { } elseif ($parent_scope == Smarty::SCOPE_GLOBAL) {
@@ -342,7 +344,11 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase {
foreach ($this->required_plugins['compiled'] as $tmp) { foreach ($this->required_plugins['compiled'] as $tmp) {
foreach ($tmp as $data) { foreach ($tmp as $data) {
$file = addslashes($data['file']); $file = addslashes($data['file']);
$plugins_string .= "if (!is_callable('{$data['function']}')) include '{$file}';\n"; if (is_Array($data['function'])){
$plugins_string .= "if (!is_callable(array('{$data['function'][0]}','{$data['function'][1]}'))) include '{$file}';\n";
} else {
$plugins_string .= "if (!is_callable('{$data['function']}')) include '{$file}';\n";
}
} }
} }
$plugins_string .= '?>'; $plugins_string .= '?>';
@@ -353,7 +359,11 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase {
foreach ($this->required_plugins['nocache'] as $tmp) { foreach ($this->required_plugins['nocache'] as $tmp) {
foreach ($tmp as $data) { foreach ($tmp as $data) {
$file = addslashes($data['file']); $file = addslashes($data['file']);
$plugins_string .= addslashes("if (!is_callable('{$data['function']}')) include '{$file}';\n"); if (is_Array($data['function'])){
$plugins_string .= addslashes("if (!is_callable(array('{$data['function'][0]}','{$data['function'][1]}'))) include '{$file}';\n");
} else {
$plugins_string .= addslashes("if (!is_callable('{$data['function']}')) include '{$file}';\n");
}
} }
} }
$plugins_string .= "?>/*/%%SmartyNocache:{$this->properties['nocache_hash']}%%*/';?>\n"; $plugins_string .= "?>/*/%%SmartyNocache:{$this->properties['nocache_hash']}%%*/';?>\n";
@@ -442,7 +452,7 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase {
$mtime = $this->source->timestamp; $mtime = $this->source->timestamp;
} else { } else {
// file and php types can be checked without loading the respective resource handlers // file and php types can be checked without loading the respective resource handlers
$mtime = filemtime($_file_to_check[0]); $mtime = @filemtime($_file_to_check[0]);
} }
} elseif ($_file_to_check[2] == 'string') { } elseif ($_file_to_check[2] == 'string') {
continue; continue;
@@ -450,7 +460,7 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase {
$source = Smarty_Resource::source(null, $this->smarty, $_file_to_check[0]); $source = Smarty_Resource::source(null, $this->smarty, $_file_to_check[0]);
$mtime = $source->timestamp; $mtime = $source->timestamp;
} }
if ($mtime > $_file_to_check[1]) { if (!$mtime || $mtime > $_file_to_check[1]) {
$is_valid = false; $is_valid = false;
break; break;
} }
@@ -319,7 +319,7 @@ abstract class Smarty_Internal_TemplateBase extends Smarty_Internal_Data {
break; break;
default: default:
header('HTTP/1.1 304 Not Modified'); header($_SERVER['SERVER_PROTOCOL'].' 304 Not Modified');
break; break;
} }
} else { } else {
@@ -1,4 +1,5 @@
<?php <?php
/** /**
* Smarty Internal Plugin Smarty Template Compiler Base * Smarty Internal Plugin Smarty Template Compiler Base
* *
@@ -23,101 +24,130 @@ abstract class Smarty_Internal_TemplateCompilerBase {
* @var mixed * @var mixed
*/ */
private $nocache_hash = null; private $nocache_hash = null;
/** /**
* suppress generation of nocache code * suppress generation of nocache code
* *
* @var bool * @var bool
*/ */
public $suppressNocacheProcessing = false; public $suppressNocacheProcessing = false;
/** /**
* suppress generation of merged template code * suppress generation of merged template code
* *
* @var bool * @var bool
*/ */
public $suppressMergedTemplates = false; public $suppressMergedTemplates = false;
/** /**
* compile tag objects * compile tag objects
* *
* @var array * @var array
*/ */
public static $_tag_objects = array(); public static $_tag_objects = array();
/** /**
* tag stack * tag stack
* *
* @var array * @var array
*/ */
public $_tag_stack = array(); public $_tag_stack = array();
/** /**
* current template * current template
* *
* @var Smarty_Internal_Template * @var Smarty_Internal_Template
*/ */
public $template = null; public $template = null;
/** /**
* merged templates * merged templates
* *
* @var array * @var array
*/ */
public $merged_templates = array(); public $merged_templates = array();
/** /**
* flag when compiling {block} * flag when compiling {block}
* *
* @var bool * @var bool
*/ */
public $inheritance = false; public $inheritance = false;
/** /**
* plugins loaded by default plugin handler * plugins loaded by default plugin handler
* *
* @var array * @var array
*/ */
public $default_handler_plugins = array(); public $default_handler_plugins = array();
/** /**
* saved preprocessed modifier list * saved preprocessed modifier list
* *
* @var mixed * @var mixed
*/ */
public $default_modifier_list = null; public $default_modifier_list = null;
/** /**
* force compilation of complete template as nocache * force compilation of complete template as nocache
* @var boolean * @var boolean
*/ */
public $forceNocache = false; public $forceNocache = false;
/** /**
* suppress Smarty header code in compiled template * suppress Smarty header code in compiled template
* @var bool * @var bool
*/ */
public $suppressHeader = false; public $suppressHeader = false;
/** /**
* suppress template property header code in compiled template * suppress template property header code in compiled template
* @var bool * @var bool
*/ */
public $suppressTemplatePropertyHeader = false; public $suppressTemplatePropertyHeader = false;
/** /**
* flag if compiled template file shall we written * flag if compiled template file shall we written
* @var bool * @var bool
*/ */
public $write_compiled_code = true; public $write_compiled_code = true;
/** /**
* flag if currently a template function is compiled * flag if currently a template function is compiled
* @var bool * @var bool
*/ */
public $compiles_template_function = false; public $compiles_template_function = false;
/** /**
* called subfuntions from template function * called subfuntions from template function
* @var array * @var array
*/ */
public $called_functions = array(); public $called_functions = array();
/** /**
* flags for used modifier plugins * flags for used modifier plugins
* @var array * @var array
*/ */
public $modifier_plugins = array(); public $modifier_plugins = array();
/**
* type of already compiled modifier
* @var array
*/
public $known_modifier_type = array();
/**
* Methode to compile a Smarty template
*
* @param mixed $_content template source
* @return bool true if compiling succeeded, false if it failed
*/
abstract protected function doCompile($_content);
/** /**
* Initialize compiler * Initialize compiler
*/ */
public function __construct() public function __construct() {
{
$this->nocache_hash = str_replace('.', '-', uniqid(rand(), true)); $this->nocache_hash = str_replace('.', '-', uniqid(rand(), true));
} }
@@ -127,8 +157,7 @@ abstract class Smarty_Internal_TemplateCompilerBase {
* @param Smarty_Internal_Template $template template object to compile * @param Smarty_Internal_Template $template template object to compile
* @return bool true if compiling succeeded, false if it failed * @return bool true if compiling succeeded, false if it failed
*/ */
public function compileTemplate(Smarty_Internal_Template $template) public function compileTemplate(Smarty_Internal_Template $template) {
{
if (empty($template->properties['nocache_hash'])) { if (empty($template->properties['nocache_hash'])) {
$template->properties['nocache_hash'] = $this->nocache_hash; $template->properties['nocache_hash'] = $this->nocache_hash;
} else { } else {
@@ -156,7 +185,7 @@ abstract class Smarty_Internal_TemplateCompilerBase {
$_content = $template->source->content; $_content = $template->source->content;
// run prefilter if required // run prefilter if required
if (isset($this->smarty->autoload_filters['pre']) || isset($this->smarty->registered_filters['pre'])) { if (isset($this->smarty->autoload_filters['pre']) || isset($this->smarty->registered_filters['pre'])) {
$template->source->content = $_content = Smarty_Internal_Filter_Handler::runFilter('pre', $_content, $template); $_content = Smarty_Internal_Filter_Handler::runFilter('pre', $_content, $template);
} }
// on empty template just return header // on empty template just return header
if ($_content == '') { if ($_content == '') {
@@ -194,6 +223,8 @@ abstract class Smarty_Internal_TemplateCompilerBase {
} else { } else {
$code = $template_header . $template->createTemplateCodeFrame($_compiled_code) . $merged_code; $code = $template_header . $template->createTemplateCodeFrame($_compiled_code) . $merged_code;
} }
// unset content because template inheritance could have replace source with parent code
unset ($template->source->content);
return $code; return $code;
} }
@@ -208,8 +239,7 @@ abstract class Smarty_Internal_TemplateCompilerBase {
* @param array $parameter array with compilation parameter * @param array $parameter array with compilation parameter
* @return string compiled code * @return string compiled code
*/ */
public function compileTag($tag, $args, $parameter = array()) public function compileTag($tag, $args, $parameter = array()) {
{
// $args contains the attributes parsed and compiled by the lexer/parser // $args contains the attributes parsed and compiled by the lexer/parser
// assume that tag does compile into code, but creates no HTML output // assume that tag does compile into code, but creates no HTML output
$this->has_code = true; $this->has_code = true;
@@ -219,8 +249,8 @@ abstract class Smarty_Internal_TemplateCompilerBase {
$this->template->used_tags[] = array($tag, $args); $this->template->used_tags[] = array($tag, $args);
} }
// check nocache option flag // check nocache option flag
if (in_array("'nocache'",$args) || in_array(array('nocache'=>'true'),$args) if (in_array("'nocache'", $args) || in_array(array('nocache' => 'true'), $args)
|| in_array(array('nocache'=>'"true"'),$args) || in_array(array('nocache'=>"'true'"),$args)) { || in_array(array('nocache' => '"true"'), $args) || in_array(array('nocache' => "'true'"), $args)) {
$this->tag_nocache = true; $this->tag_nocache = true;
} }
// compile the smarty tag (required compile classes to compile the tag are autoloaded) // compile the smarty tag (required compile classes to compile the tag are autoloaded)
@@ -260,12 +290,12 @@ abstract class Smarty_Internal_TemplateCompilerBase {
if (isset($this->smarty->registered_objects[$tag]) && isset($parameter['object_methode'])) { if (isset($this->smarty->registered_objects[$tag]) && isset($parameter['object_methode'])) {
$methode = $parameter['object_methode']; $methode = $parameter['object_methode'];
if (!in_array($methode, $this->smarty->registered_objects[$tag][3]) && if (!in_array($methode, $this->smarty->registered_objects[$tag][3]) &&
(empty($this->smarty->registered_objects[$tag][1]) || in_array($methode, $this->smarty->registered_objects[$tag][1]))) { (empty($this->smarty->registered_objects[$tag][1]) || in_array($methode, $this->smarty->registered_objects[$tag][1]))) {
return $this->callTagCompiler('private_object_function', $args, $parameter, $tag, $methode); return $this->callTagCompiler('private_object_function', $args, $parameter, $tag, $methode);
} elseif (in_array($methode, $this->smarty->registered_objects[$tag][3])) { } elseif (in_array($methode, $this->smarty->registered_objects[$tag][3])) {
return $this->callTagCompiler('private_object_block_function', $args, $parameter, $tag, $methode); return $this->callTagCompiler('private_object_block_function', $args, $parameter, $tag, $methode);
} else { } else {
return $this->trigger_template_error ('unallowed methode "' . $methode . '" in registered object "' . $tag . '"', $this->lex->taglineno); return $this->trigger_template_error('unallowed methode "' . $methode . '" in registered object "' . $tag . '"', $this->lex->taglineno);
} }
} }
// check if tag is registered // check if tag is registered
@@ -275,10 +305,10 @@ abstract class Smarty_Internal_TemplateCompilerBase {
if ($plugin_type == Smarty::PLUGIN_COMPILER) { if ($plugin_type == Smarty::PLUGIN_COMPILER) {
$new_args = array(); $new_args = array();
foreach ($args as $key => $mixed) { foreach ($args as $key => $mixed) {
if (is_array($mixed)) { if (is_array($mixed)) {
$new_args = array_merge($new_args, $mixed); $new_args = array_merge($new_args, $mixed);
} else { } else {
$new_args[$key] = $mixed; $new_args[$key] = $mixed;
} }
} }
if (!$this->smarty->registered_plugins[$plugin_type][$tag][1]) { if (!$this->smarty->registered_plugins[$plugin_type][$tag][1]) {
@@ -297,7 +327,6 @@ abstract class Smarty_Internal_TemplateCompilerBase {
if ($plugin_type == Smarty::PLUGIN_FUNCTION || $plugin_type == Smarty::PLUGIN_BLOCK) { if ($plugin_type == Smarty::PLUGIN_FUNCTION || $plugin_type == Smarty::PLUGIN_BLOCK) {
return $this->callTagCompiler('private_registered_' . $plugin_type, $args, $parameter, $tag); return $this->callTagCompiler('private_registered_' . $plugin_type, $args, $parameter, $tag);
} }
} }
} }
// check plugins from plugins folder // check plugins from plugins folder
@@ -308,10 +337,10 @@ abstract class Smarty_Internal_TemplateCompilerBase {
// convert arguments format for old compiler plugins // convert arguments format for old compiler plugins
$new_args = array(); $new_args = array();
foreach ($args as $key => $mixed) { foreach ($args as $key => $mixed) {
if (is_array($mixed)) { if (is_array($mixed)) {
$new_args = array_merge($new_args, $mixed); $new_args = array_merge($new_args, $mixed);
} else { } else {
$new_args[$key] = $mixed; $new_args[$key] = $mixed;
} }
} }
return $plugin($new_args, $this->smarty); return $plugin($new_args, $this->smarty);
@@ -325,7 +354,7 @@ abstract class Smarty_Internal_TemplateCompilerBase {
throw new SmartyException("Plugin \"{$tag}\" not callable"); throw new SmartyException("Plugin \"{$tag}\" not callable");
} else { } else {
if ($function = $this->getPlugin($tag, $plugin_type)) { if ($function = $this->getPlugin($tag, $plugin_type)) {
if(!isset($this->smarty->security_policy) || $this->smarty->security_policy->isTrustedTag($tag, $this)) { if (!isset($this->smarty->security_policy) || $this->smarty->security_policy->isTrustedTag($tag, $this)) {
return $this->callTagCompiler('private_' . $plugin_type . '_plugin', $args, $parameter, $tag, $function); return $this->callTagCompiler('private_' . $plugin_type . '_plugin', $args, $parameter, $tag, $function);
} }
} }
@@ -378,7 +407,7 @@ abstract class Smarty_Internal_TemplateCompilerBase {
if (in_array($methode, $this->smarty->registered_objects[$base_tag][3])) { if (in_array($methode, $this->smarty->registered_objects[$base_tag][3])) {
return $this->callTagCompiler('private_object_block_function', $args, $parameter, $tag, $methode); return $this->callTagCompiler('private_object_block_function', $args, $parameter, $tag, $methode);
} else { } else {
return $this->trigger_template_error ('unallowed closing tag methode "' . $methode . '" in registered object "' . $base_tag . '"', $this->lex->taglineno); return $this->trigger_template_error('unallowed closing tag methode "' . $methode . '" in registered object "' . $base_tag . '"', $this->lex->taglineno);
} }
} }
// registered block tag ? // registered block tag ?
@@ -389,6 +418,22 @@ abstract class Smarty_Internal_TemplateCompilerBase {
if ($function = $this->getPlugin($base_tag, Smarty::PLUGIN_BLOCK)) { if ($function = $this->getPlugin($base_tag, Smarty::PLUGIN_BLOCK)) {
return $this->callTagCompiler('private_block_plugin', $args, $parameter, $tag, $function); return $this->callTagCompiler('private_block_plugin', $args, $parameter, $tag, $function);
} }
// registered compiler plugin ?
if (isset($this->smarty->registered_plugins[Smarty::PLUGIN_COMPILER][$tag])) {
// if compiler function plugin call it now
$args = array();
if (!$this->smarty->registered_plugins[Smarty::PLUGIN_COMPILER][$tag][1]) {
$this->tag_nocache = true;
}
$function = $this->smarty->registered_plugins[Smarty::PLUGIN_COMPILER][$tag][0];
if (!is_array($function)) {
return $function($args, $this);
} else if (is_object($function[0])) {
return $this->smarty->registered_plugins[Smarty::PLUGIN_COMPILER][$tag][0][0]->$function[1]($args, $this);
} else {
return call_user_func_array($function, array($args, $this));
}
}
if ($this->smarty->loadPlugin('smarty_compiler_' . $tag)) { if ($this->smarty->loadPlugin('smarty_compiler_' . $tag)) {
$plugin = 'smarty_compiler_' . $tag; $plugin = 'smarty_compiler_' . $tag;
if (is_callable($plugin)) { if (is_callable($plugin)) {
@@ -403,7 +448,7 @@ abstract class Smarty_Internal_TemplateCompilerBase {
throw new SmartyException("Plugin \"{$tag}\" not callable"); throw new SmartyException("Plugin \"{$tag}\" not callable");
} }
} }
$this->trigger_template_error ("unknown tag \"" . $tag . "\"", $this->lex->taglineno); $this->trigger_template_error("unknown tag \"" . $tag . "\"", $this->lex->taglineno);
} }
} }
@@ -421,8 +466,7 @@ abstract class Smarty_Internal_TemplateCompilerBase {
* @param mixed $param3 optional parameter * @param mixed $param3 optional parameter
* @return string compiled code * @return string compiled code
*/ */
public function callTagCompiler($tag, $args, $param1 = null, $param2 = null, $param3 = null) public function callTagCompiler($tag, $args, $param1 = null, $param2 = null, $param3 = null) {
{
// re-use object if already exists // re-use object if already exists
if (isset(self::$_tag_objects[$tag])) { if (isset(self::$_tag_objects[$tag])) {
// compile this tag // compile this tag
@@ -433,10 +477,10 @@ abstract class Smarty_Internal_TemplateCompilerBase {
if ($this->smarty->loadPlugin($class_name)) { if ($this->smarty->loadPlugin($class_name)) {
// check if tag allowed by security // check if tag allowed by security
if (!isset($this->smarty->security_policy) || $this->smarty->security_policy->isTrustedTag($tag, $this)) { if (!isset($this->smarty->security_policy) || $this->smarty->security_policy->isTrustedTag($tag, $this)) {
// use plugin if found // use plugin if found
self::$_tag_objects[$tag] = new $class_name; self::$_tag_objects[$tag] = new $class_name;
// compile this tag // compile this tag
return self::$_tag_objects[$tag]->compile($args, $this, $param1, $param2, $param3); return self::$_tag_objects[$tag]->compile($args, $this, $param1, $param2, $param3);
} }
} }
// no internal compile plugin for this tag // no internal compile plugin for this tag
@@ -450,8 +494,7 @@ abstract class Smarty_Internal_TemplateCompilerBase {
* @param string $plugin_type type of plugin * @param string $plugin_type type of plugin
* @return string call name of function * @return string call name of function
*/ */
public function getPlugin($plugin_name, $plugin_type) public function getPlugin($plugin_name, $plugin_type) {
{
$function = null; $function = null;
if ($this->template->caching && ($this->nocache || $this->tag_nocache)) { if ($this->template->caching && ($this->nocache || $this->tag_nocache)) {
if (isset($this->template->required_plugins['nocache'][$plugin_name][$plugin_type])) { if (isset($this->template->required_plugins['nocache'][$plugin_name][$plugin_type])) {
@@ -505,14 +548,12 @@ abstract class Smarty_Internal_TemplateCompilerBase {
* @param string $plugin_type type of plugin * @param string $plugin_type type of plugin
* @return boolean true if found * @return boolean true if found
*/ */
public function getPluginFromDefaultHandler($tag, $plugin_type) public function getPluginFromDefaultHandler($tag, $plugin_type) {
{
$callback = null; $callback = null;
$script = null; $script = null;
$cacheable = true; $cacheable = true;
$result = call_user_func_array( $result = call_user_func_array(
$this->smarty->default_plugin_handler_func, $this->smarty->default_plugin_handler_func, array($tag, $plugin_type, $this->template, &$callback, &$script, &$cacheable)
array($tag, $plugin_type, $this->template, &$callback, &$script, &$cacheable)
); );
if ($result) { if ($result) {
$this->tag_nocache = $this->tag_nocache || !$cacheable; $this->tag_nocache = $this->tag_nocache || !$cacheable;
@@ -526,7 +567,7 @@ abstract class Smarty_Internal_TemplateCompilerBase {
$this->template->required_plugins['compiled'][$tag][$plugin_type]['function'] = $callback; $this->template->required_plugins['compiled'][$tag][$plugin_type]['function'] = $callback;
} }
include_once $script; include_once $script;
} else { } else {
$this->trigger_template_error("Default plugin handler: Returned script file \"{$script}\" for \"{$tag}\" not found"); $this->trigger_template_error("Default plugin handler: Returned script file \"{$script}\" for \"{$tag}\" not found");
} }
} }
@@ -554,16 +595,14 @@ abstract class Smarty_Internal_TemplateCompilerBase {
* @param boolean $is_code true if content is compiled code * @param boolean $is_code true if content is compiled code
* @return string content * @return string content
*/ */
public function processNocacheCode($content, $is_code) public function processNocacheCode($content, $is_code) {
{
// If the template is not evaluated and we have a nocache section and or a nocache tag // If the template is not evaluated and we have a nocache section and or a nocache tag
if ($is_code && !empty($content)) { if ($is_code && !empty($content)) {
// generate replacement code // generate replacement code
if ((!($this->template->source->recompiled) || $this->forceNocache) && $this->template->caching && !$this->suppressNocacheProcessing && if ((!($this->template->source->recompiled) || $this->forceNocache) && $this->template->caching && !$this->suppressNocacheProcessing &&
($this->nocache || $this->tag_nocache || $this->forceNocache == 2)) { ($this->nocache || $this->tag_nocache || $this->forceNocache == 2)) {
$this->template->has_nocache_code = true; $this->template->has_nocache_code = true;
$_output = str_replace("'", "\'", $content); $_output = addcslashes($content,'\'\\');
$_output = str_replace('\\\\', '\\\\\\', $_output);
$_output = str_replace("^#^", "'", $_output); $_output = str_replace("^#^", "'", $_output);
$_output = "<?php echo '/*%%SmartyNocache:{$this->nocache_hash}%%*/" . $_output . "/*/%%SmartyNocache:{$this->nocache_hash}%%*/';?>\n"; $_output = "<?php echo '/*%%SmartyNocache:{$this->nocache_hash}%%*/" . $_output . "/*/%%SmartyNocache:{$this->nocache_hash}%%*/';?>\n";
// make sure we include modifer plugins for nocache code // make sure we include modifer plugins for nocache code
@@ -596,21 +635,20 @@ abstract class Smarty_Internal_TemplateCompilerBase {
* @param string $line line-number * @param string $line line-number
* @throws SmartyCompilerException when an unexpected token is found * @throws SmartyCompilerException when an unexpected token is found
*/ */
public function trigger_template_error($args = null, $line = null) public function trigger_template_error($args = null, $line = null) {
{
// get template source line which has error // get template source line which has error
if (!isset($line)) { if (!isset($line)) {
$line = $this->lex->line; $line = $this->lex->line;
} }
$match = preg_split("/\n/", $this->lex->data); $match = preg_split("/\n/", $this->lex->data);
$error_text = 'Syntax Error in template "' . $this->template->source->filepath . '" on line ' . $line . ' "' . htmlspecialchars(trim(preg_replace('![\t\r\n]+!',' ',$match[$line-1]))) . '" '; $error_text = 'Syntax Error in template "' . $this->template->source->filepath . '" on line ' . $line . ' "' . htmlspecialchars(trim(preg_replace('![\t\r\n]+!', ' ', $match[$line - 1]))) . '" ';
if (isset($args)) { if (isset($args)) {
// individual error message // individual error message
$error_text .= $args; $error_text .= $args;
} else { } else {
// expected token from parser // expected token from parser
$error_text .= ' - Unexpected "' . $this->lex->value.'"'; $error_text .= ' - Unexpected "' . $this->lex->value . '"';
if (count($this->parser->yy_get_expected_tokens($this->parser->yymajor)) <= 4 ) { if (count($this->parser->yy_get_expected_tokens($this->parser->yymajor)) <= 4) {
foreach ($this->parser->yy_get_expected_tokens($this->parser->yymajor) as $token) { foreach ($this->parser->yy_get_expected_tokens($this->parser->yymajor) as $token) {
$exp_token = $this->parser->yyTokenName[$token]; $exp_token = $this->parser->yyTokenName[$token];
if (isset($this->lex->smarty_token_names[$exp_token])) { if (isset($this->lex->smarty_token_names[$exp_token])) {
@@ -85,6 +85,7 @@ class Smarty_Internal_Templatelexer
$this->ldel = preg_quote($this->smarty->left_delimiter,'/'); $this->ldel = preg_quote($this->smarty->left_delimiter,'/');
$this->ldel_length = strlen($this->smarty->left_delimiter); $this->ldel_length = strlen($this->smarty->left_delimiter);
$this->rdel = preg_quote($this->smarty->right_delimiter,'/'); $this->rdel = preg_quote($this->smarty->right_delimiter,'/');
$this->rdel_length = strlen($this->smarty->right_delimiter);
$this->smarty_token_names['LDEL'] = $this->smarty->left_delimiter; $this->smarty_token_names['LDEL'] = $this->smarty->left_delimiter;
$this->smarty_token_names['RDEL'] = $this->smarty->right_delimiter; $this->smarty_token_names['RDEL'] = $this->smarty->right_delimiter;
$this->mbstring_overload = ini_get('mbstring.func_overload') & 2; $this->mbstring_overload = ini_get('mbstring.func_overload') & 2;
@@ -141,11 +142,12 @@ class Smarty_Internal_Templatelexer
21 => 0, 21 => 0,
22 => 0, 22 => 0,
23 => 0, 23 => 0,
24 => 0,
); );
if ($this->counter >= ($this->mbstring_overload ? mb_strlen($this->data,'latin1'): strlen($this->data))) { if ($this->counter >= ($this->mbstring_overload ? mb_strlen($this->data,'latin1'): strlen($this->data))) {
return false; // end of input return false; // end of input
} }
$yy_global_pattern = "/\G(".$this->ldel."[$]smarty\\.block\\.child".$this->rdel.")|\G(\\{\\})|\G(".$this->ldel."\\*([\S\s]*?)\\*".$this->rdel.")|\G(".$this->ldel."strip".$this->rdel.")|\G(".$this->ldel."\\s{1,}strip\\s{1,}".$this->rdel.")|\G(".$this->ldel."\/strip".$this->rdel.")|\G(".$this->ldel."\\s{1,}\/strip\\s{1,}".$this->rdel.")|\G(".$this->ldel."\\s*literal\\s*".$this->rdel.")|\G(".$this->ldel."\\s{1,}\/)|\G(".$this->ldel."\\s*(if|elseif|else if|while)\\s+)|\G(".$this->ldel."\\s*for\\s+)|\G(".$this->ldel."\\s*foreach(?![^\s]))|\G(".$this->ldel."\\s*setfilter\\s+)|\G(".$this->ldel."\\s{1,})|\G(".$this->ldel."\/)|\G(".$this->ldel.")|\G(<\\?(?:php\\w+|=|[a-zA-Z]+)?)|\G(\\?>)|\G(<%)|\G(%>)|\G([\S\s])/iS"; $yy_global_pattern = "/\G(".$this->ldel."[$]smarty\\.block\\.child".$this->rdel.")|\G(\\{\\})|\G(".$this->ldel."\\*([\S\s]*?)\\*".$this->rdel.")|\G(".$this->ldel."strip".$this->rdel.")|\G(".$this->ldel."\\s{1,}strip\\s{1,}".$this->rdel.")|\G(".$this->ldel."\/strip".$this->rdel.")|\G(".$this->ldel."\\s{1,}\/strip\\s{1,}".$this->rdel.")|\G(".$this->ldel."\\s*literal\\s*".$this->rdel.")|\G(".$this->ldel."\\s{1,}\/)|\G(".$this->ldel."\\s*(if|elseif|else if|while)\\s+)|\G(".$this->ldel."\\s*for\\s+)|\G(".$this->ldel."\\s*foreach(?![^\s]))|\G(".$this->ldel."\\s*setfilter\\s+)|\G(".$this->ldel."\\s{1,})|\G(".$this->ldel."\/)|\G(".$this->ldel.")|\G(<\\?(?:php\\w+|=|[a-zA-Z]+)?)|\G(\\?>)|\G(".$this->rdel.")|\G(<%)|\G(%>)|\G([\S\s])/iS";
do { do {
if ($this->mbstring_overload ? preg_match($yy_global_pattern, mb_substr($this->data, $this->counter,2000000000,'latin1'), $yymatches) : preg_match($yy_global_pattern,$this->data, $yymatches, null, $this->counter)) { if ($this->mbstring_overload ? preg_match($yy_global_pattern, mb_substr($this->data, $this->counter,2000000000,'latin1'), $yymatches) : preg_match($yy_global_pattern,$this->data, $yymatches, null, $this->counter)) {
@@ -344,16 +346,21 @@ class Smarty_Internal_Templatelexer
function yy_r1_21($yy_subpatterns) function yy_r1_21($yy_subpatterns)
{ {
$this->token = Smarty_Internal_Templateparser::TP_ASPSTARTTAG; $this->token = Smarty_Internal_Templateparser::TP_TEXT;
} }
function yy_r1_22($yy_subpatterns) function yy_r1_22($yy_subpatterns)
{ {
$this->token = Smarty_Internal_Templateparser::TP_ASPENDTAG; $this->token = Smarty_Internal_Templateparser::TP_ASPSTARTTAG;
} }
function yy_r1_23($yy_subpatterns) function yy_r1_23($yy_subpatterns)
{ {
$this->token = Smarty_Internal_Templateparser::TP_ASPENDTAG;
}
function yy_r1_24($yy_subpatterns)
{
if ($this->mbstring_overload) { if ($this->mbstring_overload) {
$to = mb_strlen($this->data,'latin1'); $to = mb_strlen($this->data,'latin1');
} else { } else {
@@ -442,11 +449,12 @@ class Smarty_Internal_Templatelexer
74 => 0, 74 => 0,
75 => 0, 75 => 0,
76 => 0, 76 => 0,
77 => 0,
); );
if ($this->counter >= ($this->mbstring_overload ? mb_strlen($this->data,'latin1'): strlen($this->data))) { if ($this->counter >= ($this->mbstring_overload ? mb_strlen($this->data,'latin1'): strlen($this->data))) {
return false; // end of input return false; // end of input
} }
$yy_global_pattern = "/\G('[^'\\\\]*(?:\\\\.[^'\\\\]*)*')|\G(".$this->ldel."\\s{1,}\/)|\G(".$this->ldel."\\s*(if|elseif|else if|while)\\s+)|\G(".$this->ldel."\\s*for\\s+)|\G(".$this->ldel."\\s*foreach(?![^\s]))|\G(".$this->ldel."\\s{1,})|\G(\\s{1,}".$this->rdel.")|\G(".$this->ldel."\/)|\G(".$this->ldel.")|\G(".$this->rdel.")|\G(\\s+is\\s+in\\s+)|\G(\\s+as\\s+)|\G(\\s+to\\s+)|\G(\\s+step\\s+)|\G(\\s+instanceof\\s+)|\G(\\s*===\\s*)|\G(\\s*!==\\s*)|\G(\\s*==\\s*|\\s+eq\\s+)|\G(\\s*!=\\s*|\\s*<>\\s*|\\s+(ne|neq)\\s+)|\G(\\s*>=\\s*|\\s+(ge|gte)\\s+)|\G(\\s*<=\\s*|\\s+(le|lte)\\s+)|\G(\\s*>\\s*|\\s+gt\\s+)|\G(\\s*<\\s*|\\s+lt\\s+)|\G(\\s+mod\\s+)|\G(!\\s*|not\\s+)|\G(\\s*&&\\s*|\\s*and\\s+)|\G(\\s*\\|\\|\\s*|\\s*or\\s+)|\G(\\s*xor\\s+)|\G(\\s+is\\s+odd\\s+by\\s+)|\G(\\s+is\\s+not\\s+odd\\s+by\\s+)|\G(\\s+is\\s+odd)|\G(\\s+is\\s+not\\s+odd)|\G(\\s+is\\s+even\\s+by\\s+)|\G(\\s+is\\s+not\\s+even\\s+by\\s+)|\G(\\s+is\\s+even)|\G(\\s+is\\s+not\\s+even)|\G(\\s+is\\s+div\\s+by\\s+)|\G(\\s+is\\s+not\\s+div\\s+by\\s+)|\G(\\((int(eger)?|bool(ean)?|float|double|real|string|binary|array|object)\\)\\s*)|\G(\\s*\\(\\s*)|\G(\\s*\\))|\G(\\[\\s*)|\G(\\s*\\])|\G(\\s*->\\s*)|\G(\\s*=>\\s*)|\G(\\s*=\\s*)|\G(\\+\\+|--)|\G(\\s*(\\+|-)\\s*)|\G(\\s*(\\*|\/|%)\\s*)|\G(\\$)|\G(\\s*;)|\G(::)|\G(\\s*:\\s*)|\G(@)|\G(#)|\G(\")|\G(`)|\G(\\|)|\G(\\.)|\G(\\s*,\\s*)|\G(\\s*&\\s*)|\G(\\s*\\?\\s*)|\G(0[xX][0-9a-fA-F]+)|\G([0-9]*[a-zA-Z_]\\w*)|\G(\\d+)|\G(\\s+)|\G([\S\s])/iS"; $yy_global_pattern = "/\G('[^'\\\\]*(?:\\\\.[^'\\\\]*)*')|\G(".$this->ldel."\\s{1,}\/)|\G(".$this->ldel."\\s*(if|elseif|else if|while)\\s+)|\G(".$this->ldel."\\s*for\\s+)|\G(".$this->ldel."\\s*foreach(?![^\s]))|\G(".$this->ldel."\\s{1,})|\G(\\s{1,}".$this->rdel.")|\G(".$this->ldel."\/)|\G(".$this->ldel.")|\G(".$this->rdel.")|\G(\\s+is\\s+in\\s+)|\G(\\s+as\\s+)|\G(\\s+to\\s+)|\G(\\s+step\\s+)|\G(\\s+instanceof\\s+)|\G(\\s*===\\s*)|\G(\\s*!==\\s*)|\G(\\s*==\\s*|\\s+eq\\s+)|\G(\\s*!=\\s*|\\s*<>\\s*|\\s+(ne|neq)\\s+)|\G(\\s*>=\\s*|\\s+(ge|gte)\\s+)|\G(\\s*<=\\s*|\\s+(le|lte)\\s+)|\G(\\s*>\\s*|\\s+gt\\s+)|\G(\\s*<\\s*|\\s+lt\\s+)|\G(\\s+mod\\s+)|\G(!\\s*|not\\s+)|\G(\\s*&&\\s*|\\s*and\\s+)|\G(\\s*\\|\\|\\s*|\\s*or\\s+)|\G(\\s*xor\\s+)|\G(\\s+is\\s+odd\\s+by\\s+)|\G(\\s+is\\s+not\\s+odd\\s+by\\s+)|\G(\\s+is\\s+odd)|\G(\\s+is\\s+not\\s+odd)|\G(\\s+is\\s+even\\s+by\\s+)|\G(\\s+is\\s+not\\s+even\\s+by\\s+)|\G(\\s+is\\s+even)|\G(\\s+is\\s+not\\s+even)|\G(\\s+is\\s+div\\s+by\\s+)|\G(\\s+is\\s+not\\s+div\\s+by\\s+)|\G(\\((int(eger)?|bool(ean)?|float|double|real|string|binary|array|object)\\)\\s*)|\G(\\s*\\(\\s*)|\G(\\s*\\))|\G(\\[\\s*)|\G(\\s*\\])|\G(\\s*->\\s*)|\G(\\s*=>\\s*)|\G(\\s*=\\s*)|\G(\\+\\+|--)|\G(\\s*(\\+|-)\\s*)|\G(\\s*(\\*|\/|%)\\s*)|\G(\\$)|\G(\\s*;)|\G(::)|\G(\\s*:\\s*)|\G(@)|\G(#)|\G(\")|\G(`)|\G(\\|)|\G(\\.)|\G(\\s*,\\s*)|\G(\\s*&\\s*)|\G(\\s*\\?\\s*)|\G(0[xX][0-9a-fA-F]+)|\G(\\s+[0-9]*[a-zA-Z_][a-zA-Z0-9_\-:]*\\s*=\\s*)|\G([0-9]*[a-zA-Z_]\\w*)|\G(\\d+)|\G(\\s+)|\G([\S\s])/iS";
do { do {
if ($this->mbstring_overload ? preg_match($yy_global_pattern, mb_substr($this->data, $this->counter,2000000000,'latin1'), $yymatches) : preg_match($yy_global_pattern,$this->data, $yymatches, null, $this->counter)) { if ($this->mbstring_overload ? preg_match($yy_global_pattern, mb_substr($this->data, $this->counter,2000000000,'latin1'), $yymatches) : preg_match($yy_global_pattern,$this->data, $yymatches, null, $this->counter)) {
@@ -852,21 +860,33 @@ class Smarty_Internal_Templatelexer
function yy_r2_73($yy_subpatterns) function yy_r2_73($yy_subpatterns)
{ {
$this->token = Smarty_Internal_Templateparser::TP_ID; // resolve conflicts with shorttag and right_delimiter starting with '='
if (substr($this->data, $this->counter + strlen($this->value) - 1, $this->rdel_length) == $this->smarty->right_delimiter) {
preg_match("/\s+/",$this->value,$match);
$this->value = $match[0];
$this->token = Smarty_Internal_Templateparser::TP_SPACE;
} else {
$this->token = Smarty_Internal_Templateparser::TP_ATTR;
}
} }
function yy_r2_74($yy_subpatterns) function yy_r2_74($yy_subpatterns)
{ {
$this->token = Smarty_Internal_Templateparser::TP_INTEGER; $this->token = Smarty_Internal_Templateparser::TP_ID;
} }
function yy_r2_75($yy_subpatterns) function yy_r2_75($yy_subpatterns)
{ {
$this->token = Smarty_Internal_Templateparser::TP_SPACE; $this->token = Smarty_Internal_Templateparser::TP_INTEGER;
} }
function yy_r2_76($yy_subpatterns) function yy_r2_76($yy_subpatterns)
{ {
$this->token = Smarty_Internal_Templateparser::TP_SPACE;
}
function yy_r2_77($yy_subpatterns)
{
$this->token = Smarty_Internal_Templateparser::TP_TEXT; $this->token = Smarty_Internal_Templateparser::TP_TEXT;
} }
@@ -1181,4 +1201,3 @@ class Smarty_Internal_Templatelexer
} }
} }
?>
File diff suppressed because it is too large. Load diff
@@ -72,8 +72,8 @@ class Smarty_Internal_Utility {
$_compileDirs = new RecursiveDirectoryIterator($_dir); $_compileDirs = new RecursiveDirectoryIterator($_dir);
$_compile = new RecursiveIteratorIterator($_compileDirs); $_compile = new RecursiveIteratorIterator($_compileDirs);
foreach ($_compile as $_fileinfo) { foreach ($_compile as $_fileinfo) {
if (substr($_fileinfo->getBasename(),0,1) == '.' || strpos($_fileinfo, '.svn') !== false) continue;
$_file = $_fileinfo->getFilename(); $_file = $_fileinfo->getFilename();
if (substr(basename($_fileinfo->getPathname()),0,1) == '.' || strpos($_file, '.svn') !== false) continue;
if (!substr_compare($_file, $extention, - strlen($extention)) == 0) continue; if (!substr_compare($_file, $extention, - strlen($extention)) == 0) continue;
if ($_fileinfo->getPath() == substr($_dir, 0, -1)) { if ($_fileinfo->getPath() == substr($_dir, 0, -1)) {
$_template_file = $_file; $_template_file = $_file;
@@ -87,6 +87,7 @@ class Smarty_Internal_Utility {
$_tpl = $smarty->createTemplate($_template_file,null,null,null,false); $_tpl = $smarty->createTemplate($_template_file,null,null,null,false);
if ($_tpl->mustCompile()) { if ($_tpl->mustCompile()) {
$_tpl->compileTemplateSource(); $_tpl->compileTemplateSource();
$_count++;
echo ' compiled in ', microtime(true) - $_start_time, ' seconds'; echo ' compiled in ', microtime(true) - $_start_time, ' seconds';
flush(); flush();
} else { } else {
@@ -135,8 +136,8 @@ class Smarty_Internal_Utility {
$_compileDirs = new RecursiveDirectoryIterator($_dir); $_compileDirs = new RecursiveDirectoryIterator($_dir);
$_compile = new RecursiveIteratorIterator($_compileDirs); $_compile = new RecursiveIteratorIterator($_compileDirs);
foreach ($_compile as $_fileinfo) { foreach ($_compile as $_fileinfo) {
if (substr($_fileinfo->getBasename(),0,1) == '.' || strpos($_fileinfo, '.svn') !== false) continue;
$_file = $_fileinfo->getFilename(); $_file = $_fileinfo->getFilename();
if (substr(basename($_fileinfo->getPathname()),0,1) == '.' || strpos($_file, '.svn') !== false) continue;
if (!substr_compare($_file, $extention, - strlen($extention)) == 0) continue; if (!substr_compare($_file, $extention, - strlen($extention)) == 0) continue;
if ($_fileinfo->getPath() == substr($_dir, 0, -1)) { if ($_fileinfo->getPath() == substr($_dir, 0, -1)) {
$_config_file = $_file; $_config_file = $_file;
@@ -150,6 +151,7 @@ class Smarty_Internal_Utility {
$_config = new Smarty_Internal_Config($_config_file, $smarty); $_config = new Smarty_Internal_Config($_config_file, $smarty);
if ($_config->mustCompile()) { if ($_config->mustCompile()) {
$_config->compileConfigSource(); $_config->compileConfigSource();
$_count++;
echo ' compiled in ', microtime(true) - $_start_time, ' seconds'; echo ' compiled in ', microtime(true) - $_start_time, ' seconds';
flush(); flush();
} else { } else {
@@ -229,7 +231,7 @@ class Smarty_Internal_Utility {
} }
$_compile = new RecursiveIteratorIterator($_compileDirs, RecursiveIteratorIterator::CHILD_FIRST); $_compile = new RecursiveIteratorIterator($_compileDirs, RecursiveIteratorIterator::CHILD_FIRST);
foreach ($_compile as $_file) { foreach ($_compile as $_file) {
if (substr($_file->getBasename(), 0, 1) == '.' || strpos($_file, '.svn') !== false) if (substr(basename($_file->getPathname()), 0, 1) == '.' || strpos($_file, '.svn') !== false)
continue; continue;
$_filepath = (string) $_file; $_filepath = (string) $_file;
@@ -299,7 +301,7 @@ class Smarty_Internal_Utility {
echo "Smarty Installation test...\n"; echo "Smarty Installation test...\n";
echo "Testing template directory...\n"; echo "Testing template directory...\n";
} }
$_stream_resolve_include_path = function_exists('stream_resolve_include_path'); $_stream_resolve_include_path = function_exists('stream_resolve_include_path');
// test if all registered template_dir are accessible // test if all registered template_dir are accessible
@@ -315,7 +317,7 @@ class Smarty_Internal_Utility {
} else { } else {
$template_dir = Smarty_Internal_Get_Include_Path::getIncludePath($_template_dir); $template_dir = Smarty_Internal_Get_Include_Path::getIncludePath($_template_dir);
} }
if ($template_dir !== false) { if ($template_dir !== false) {
if ($errors === null) { if ($errors === null) {
echo "$template_dir is OK.\n"; echo "$template_dir is OK.\n";
@@ -436,7 +438,7 @@ class Smarty_Internal_Utility {
} else { } else {
$plugin_dir = Smarty_Internal_Get_Include_Path::getIncludePath($_plugin_dir); $plugin_dir = Smarty_Internal_Get_Include_Path::getIncludePath($_plugin_dir);
} }
if ($plugin_dir !== false) { if ($plugin_dir !== false) {
if ($errors === null) { if ($errors === null) {
echo "$plugin_dir is OK.\n"; echo "$plugin_dir is OK.\n";
@@ -568,7 +570,7 @@ class Smarty_Internal_Utility {
} else { } else {
$config_dir = Smarty_Internal_Get_Include_Path::getIncludePath($_config_dir); $config_dir = Smarty_Internal_Get_Include_Path::getIncludePath($_config_dir);
} }
if ($config_dir !== false) { if ($config_dir !== false) {
if ($errors === null) { if ($errors === null) {
echo "$config_dir is OK.\n"; echo "$config_dir is OK.\n";
@@ -44,12 +44,30 @@ class Smarty_Internal_Write_File {
throw new SmartyException("unable to write file {$_tmp_file}"); throw new SmartyException("unable to write file {$_tmp_file}");
return false; return false;
} }
/*
* Windows' rename() fails if the destination exists,
* Linux' rename() properly handles the overwrite.
* Simply unlink()ing a file might cause other processes
* currently reading that file to fail, but linux' rename()
* seems to be smart enough to handle that for us.
*/
if (Smarty::$_IS_WINDOWS) {
// remove original file
@unlink($_filepath);
// rename tmp file
$success = @rename($_tmp_file, $_filepath);
} else {
// rename tmp file
$success = @rename($_tmp_file, $_filepath);
if (!$success) {
// remove original file
@unlink($_filepath);
// rename tmp file
$success = @rename($_tmp_file, $_filepath);
}
}
// remove original file
@unlink($_filepath);
// rename tmp file
$success = rename($_tmp_file, $_filepath);
if (!$success) { if (!$success) {
error_reporting($_error_reporting); error_reporting($_error_reporting);
throw new SmartyException("unable to write file {$_filepath}"); throw new SmartyException("unable to write file {$_filepath}");
+60 -33
View File
@@ -144,7 +144,52 @@ abstract class Smarty_Resource {
$compiled->filepath = $_compile_dir . $_filepath . '.' . $compiled->source->type . $_basename . $_cache . '.php'; $compiled->filepath = $_compile_dir . $_filepath . '.' . $compiled->source->type . $_basename . $_cache . '.php';
} }
/**
* Normalize Paths "foo/../bar" to "bar"
*
* @param string $_path path to normalize
* @param boolean $ds respect windows directory separator
* @return string normalized path
*/
protected function normalizePath($_path, $ds=true)
{
if ($ds) {
// don't we all just love windows?
$_path = str_replace('\\', '/', $_path);
}
$offset = 0;
// resolve simples
$_path = preg_replace('#(/\./(\./)*)|/{2,}#', '/', $_path);
// resolve parents
while (true) {
$_parent = strpos($_path, '/../', $offset);
if (!$_parent) {
break;
} else if ($_path[$_parent - 1] === '.') {
$offset = $_parent + 3;
continue;
}
$_pos = strrpos($_path, '/', $_parent - strlen($_path) - 1);
if ($_pos === false) {
// don't we all just love windows?
$_pos = $_parent;
}
$_path = substr_replace($_path, '', $_pos, $_parent + 3 - $_pos);
}
if ($ds && DS != '/') {
// don't we all just love windows?
$_path = str_replace('/', '\\', $_path);
}
return $_path;
}
/** /**
* build template filepath by traversing the template_dir array * build template filepath by traversing the template_dir array
* *
@@ -181,43 +226,22 @@ abstract class Smarty_Resource {
// resolve relative path // resolve relative path
if (!preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $file)) { if (!preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $file)) {
$_was_relative_prefix = $file[0] == '.' ? substr($file, 0, strpos($file, '|')) : null; // don't we all just love windows?
$_path = DS . trim($file, '/\\'); $_path = str_replace('\\', '/', $file);
$_path = DS . trim($file, '/');
$_was_relative = true; $_was_relative = true;
} else { } else {
$_path = $file; // don't we all just love windows?
} $_path = str_replace('\\', '/', $file);
// don't we all just love windows?
$_path = str_replace('\\', '/', $_path);
// resolve simples
$_path = preg_replace('#(/\./(\./)*)|/{2,}#', '/', $_path);
// resolve parents
while (true) {
$_parent = strpos($_path, '/../');
if ($_parent === false) {
break;
} else if ($_parent === 0) {
$_path = substr($_path, 3);
break;
}
$_pos = strrpos($_path, '/', $_parent - strlen($_path) - 1);
if ($_pos === false) {
// don't we all just love windows?
$_pos = $_parent;
}
$_path = substr_replace($_path, '', $_pos, $_parent + 3 - $_pos);
} }
$_path = $this->normalizePath($_path, false);
if (DS != '/') { if (DS != '/') {
// don't we all just love windows? // don't we all just love windows?
$_path = str_replace('/', '\\', $_path); $_path = str_replace('/', '\\', $_path);
} }
// revert to relative // revert to relative
if (isset($_was_relative)) { if (isset($_was_relative)) {
if (isset($_was_relative_prefix)){ $_path = substr($_path, 1);
$_path = $_was_relative_prefix . $_path;
} else {
$_path = substr($_path, 1);
}
} }
// this is only required for directories // this is only required for directories
@@ -254,7 +278,7 @@ abstract class Smarty_Resource {
} }
} }
} }
$_stream_resolve_include_path = function_exists('stream_resolve_include_path'); $_stream_resolve_include_path = function_exists('stream_resolve_include_path');
// relative file name? // relative file name?
@@ -262,7 +286,7 @@ abstract class Smarty_Resource {
foreach ($_directories as $_directory) { foreach ($_directories as $_directory) {
$_filepath = $_directory . $file; $_filepath = $_directory . $file;
if ($this->fileExists($source, $_filepath)) { if ($this->fileExists($source, $_filepath)) {
return $_filepath; return $this->normalizePath($_filepath);
} }
if ($source->smarty->use_include_path && !preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $_directory)) { if ($source->smarty->use_include_path && !preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $_directory)) {
// try PHP include_path // try PHP include_path
@@ -271,10 +295,10 @@ abstract class Smarty_Resource {
} else { } else {
$_filepath = Smarty_Internal_Get_Include_Path::getIncludePath($_filepath); $_filepath = Smarty_Internal_Get_Include_Path::getIncludePath($_filepath);
} }
if ($_filepath !== false) { if ($_filepath !== false) {
if ($this->fileExists($source, $_filepath)) { if ($this->fileExists($source, $_filepath)) {
return $_filepath; return $this->normalizePath($_filepath);
} }
} }
} }
@@ -493,6 +517,9 @@ abstract class Smarty_Resource {
// check runtime cache // check runtime cache
$_cache_key = 'template|' . $unique_resource_name; $_cache_key = 'template|' . $unique_resource_name;
if ($smarty->compile_id) {
$_cache_key .= '|'.$smarty->compile_id;
}
if (isset(self::$sources[$_cache_key])) { if (isset(self::$sources[$_cache_key])) {
return self::$sources[$_cache_key]; return self::$sources[$_cache_key];
} }