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

This commit is contained in:
vAugagneur
2013-02-15 11:33:06 +01:00
61 changed files with 2397 additions and 1952 deletions
+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 {border: solid 1px #ccc; height: 115px}
#modules_list_container_tab ul li {margin:5px;height:140px}
/*MODULE POSITION*/
.blocLiveEdit { float:right; clear:right; background-color: #EBEDF4; border: 1px solid #C2C4D9;display: block; width:250px;}
@@ -35,7 +35,7 @@
if (this.value !== "")
location.href = base_url + '&id_category=' + parseInt(this.value);
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
@@ -47,7 +47,7 @@
else
{
$(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)
{
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)
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'])))
{
$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
$total_shipping = 0;
+1 -1
View File
@@ -1048,7 +1048,7 @@ class CategoryCore extends ObjectModel
$result = Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow('
SELECT ctg.`id_group`
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 {
$result = Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow('
+9 -3
View File
@@ -128,12 +128,18 @@ class MediaCore
public static function packJS($js_content)
{
if (strlen($js_content) > 0)
if (!empty($js_content))
{
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())
+4 -6
View File
@@ -2668,7 +2668,6 @@ class ProductCore extends ObjectModel
// Add Tax
if ($use_tax)
$price = $product_tax_calculator->addTaxes($price);
$price = Tools::ps_round($price, $decimals);
// Reduction
$reduc = 0;
@@ -2680,14 +2679,14 @@ class ProductCore extends ObjectModel
if (!$specific_price['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
$reduc = Tools::ps_round($price * $specific_price['reduction'], $decimals);
$reduc = $price * $specific_price['reduction'];
}
if ($only_reduc)
return $reduc;
return Tools::ps_round($reduc, $decimals);
if ($use_reduc)
$price -= $reduc;
@@ -2700,7 +2699,6 @@ class ProductCore extends ObjectModel
$price *= ((100 - Group::getReductionByIdGroup($id_group)) / 100);
}
$price = Tools::ps_round($price, $decimals);
// Eco Tax
if (($result['ecotax'] || isset($result['attribute_ecotax'])) && $with_ecotax)
{
@@ -4236,7 +4234,7 @@ class ProductCore extends ObjectModel
SELECT ctg.`id_group`
FROM `'._DB_PREFIX_.'category_product` cp
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
return (bool)Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue('
SELECT cg.`id_group`
+7 -9
View File
@@ -978,11 +978,11 @@ class ToolsCore
if ($allow_accented_chars === null)
$allow_accented_chars = Configuration::get('PS_ALLOW_ACCENTED_CHARS_URL');
$str = trim($str);
if (function_exists('mb_strtolower'))
$str = mb_strtolower($str, 'utf-8');
$str = trim($str);
if (!function_exists('mb_strtolower') || !$allow_accented_chars)
elseif (!$allow_accented_chars)
$str = Tools::replaceAccentedChars($str);
// Remove all non-whitelist chars.
@@ -990,7 +990,7 @@ class ToolsCore
$str = preg_replace('/[^a-zA-Z0-9\s\'\:\/\[\]-\pL]/u', '', $str);
else
$str = preg_replace('/[^a-zA-Z0-9\s\'\:\/\[\]-]/','', $str);
$str = preg_replace('/[\s\'\:\/\[\]-]+/', ' ', $str);
$str = str_replace(array(' ', '/'), '-', $str);
@@ -1691,11 +1691,9 @@ class ToolsCore
FileETag INode MTime Size
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE text/javascript
AddOutputFilterByType DEFLATE application/javascript
AddOutputFilterByType DEFLATE application/x-javascript
<IfModule mod_filter.c>
AddOutputFilterByType DEFLATE text/html text/css text/javascript application/javascript application/x-javascript
</IfModule>
</IfModule>\n\n";
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 */
protected $list_no_link = false;
protected $allow_export = false;
/** @var array $cache_lang cache for traduction */
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).');
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
@@ -1025,6 +1060,11 @@ class AdminControllerCore extends Controller
'href' => self::$currentIndex.'&amp;add'.$this->table.'&amp;token='.$this->token,
'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();
}
@@ -1929,6 +1969,11 @@ class AdminControllerCore extends Controller
else
$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 */
elseif (isset($_POST['submitReset'.$this->table]))
$this->action = 'reset_filters';
+6 -1
View File
@@ -68,7 +68,12 @@ class MySQLCore extends Db
*/
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
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', 'secureReferrer', array('Tools', 'secureReferrer'));
+5
View File
@@ -27,6 +27,11 @@
global $smarty;
$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)
{
global $_LANG;
+10 -13
View File
@@ -44,6 +44,8 @@ class AdminAddressesControllerCore extends AdminController
$this->addRowAction('delete');
$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'))
$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'));
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()
{
parent::initToolbar();
@@ -71,18 +80,6 @@ class AdminAddressesControllerCore extends AdminController
'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()
{
@@ -35,6 +35,7 @@ class AdminCartsControllerCore extends AdminController
$this->addRowAction('view');
$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->_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->deleted = false;
$this->explicitSelect = true;
$this->allow_export = true;
$this->context = Context::getContext();
@@ -42,6 +42,8 @@ class AdminCustomersControllerCore extends AdminController
$this->deleted = true;
$this->explicitSelect = true;
$this->allow_export = true;
$this->addRowAction('edit');
$this->addRowAction('view');
$this->addRowAction('delete');
@@ -35,6 +35,7 @@ class AdminManufacturersControllerCore extends AdminController
$this->className = 'Manufacturer';
$this->lang = 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?')));
@@ -64,6 +64,13 @@ class AdminMetaControllerCore extends AdminController
'type' => 'rewriting_settings',
'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(
'title' => $this->l('Automatically redirect to the canonical URL.'),
'desc' => $this->l('Recommended, but your theme must be compliant.'),
+7 -1
View File
@@ -1072,6 +1072,12 @@ class AdminModulesControllerCore extends AdminController
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
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_activated'] = $this->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['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->addRowAction('view');
$this->explicitSelect = true;
$this->allow_export = true;
$this->deleted = false;
$this->context = Context::getContext();
+25 -9
View File
@@ -53,6 +53,8 @@ class AdminProductsControllerCore extends AdminController
protected $position_identifier = 'id_product';
protected $submitted_tabs;
protected $id_current_category;
public function __construct()
{
@@ -71,6 +73,7 @@ class AdminProductsControllerCore extends AdminController
$this->_defaultOrderBy = 'position';
$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->allow_export = true;
// @since 1.5 : translations for tabs
$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']);
}
if (Tools::getValue('reset_filter_category'))
$this->context->cookie->id_category_products_filter = false;
/* Join categories table */
if ($id_category = (int)Tools::getValue('productFilter_cl!name'))
{
$this->_category = new Category((int)$id_category);
$_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
$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;
if (Validate::isLoadedObject($this->_category) && empty($this->_filter))
@@ -241,7 +255,8 @@ class AdminProductsControllerCore extends AdminController
'type' => 'bool',
'orderby' => false
);
if ((int)Tools::getValue('id_category'))
if ((int)$this->id_current_category)
$this->fields_list['position'] = array(
'title' => $this->l('Position'),
'width' => 70,
@@ -2126,8 +2141,8 @@ class AdminProductsControllerCore extends AdminController
}
else
{
if ($id_category = (int)Tools::getValue('id_category'))
self::$currentIndex .= '&id_category='.(int)$id_category;
if ($id_category = (int)$this->id_current_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 (!$id_category)
@@ -2139,8 +2154,9 @@ class AdminProductsControllerCore extends AdminController
unset($this->context->cookie->{$this->table.'Orderway'});
}
}
$id_category = (int)Tools::getValue('id_category', 1);
$this->tpl_list_vars['is_category_filter'] = Tools::getValue('id_category') ? true : false;
if (!$id_category)
$id_category = 1;
$this->tpl_list_vars['is_category_filter'] = (bool)$this->id_current_category;
// Generate category selection tree
$helper = new Helper();
@@ -34,6 +34,8 @@ class AdminSuppliersControllerCore extends AdminController
$this->addRowAction('view');
$this->addRowAction('edit');
$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->_select = 'COUNT(DISTINCT ps.`id_product`) AS products';
+2 -11
View File
@@ -340,19 +340,10 @@ class OrderControllerCore extends ParentOrderController
parent::_assignCarrier();
// Assign wrapping and TOS
$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(
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)
));
}
+1 -10
View File
@@ -480,15 +480,6 @@ class OrderOpcControllerCore extends ParentOrderController
else
$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();
$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();
$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),
'recyclablePackAllowed' => (int)(Configuration::get('PS_RECYCLABLE_PACK')),
'giftAllowed' => (int)(Configuration::get('PS_GIFT_WRAPPING')),
@@ -37,6 +37,16 @@ class PageNotFoundControllerCore extends FrontController
{
header('HTTP/1.1 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();
$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('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
{
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);
$this->canonicalRedirection();
/*
* If the product is associated to the shop
* 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 (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.
$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'])));
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')))
$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();
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();
foreach ($texts as $text_field)
$text_fields['textFields_'.$this->product->id.'_'.$text_field['index']] = str_replace('<br />', "\n", $text_field['value']);
if ($this->product->customizable)
{
$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(
'pictures' => $pictures,
'textFields' => $text_fields));
+1 -1
View File
@@ -2,5 +2,5 @@
<entity_gender>
<gender id="Mr" name="M."/>
<gender id="Ms" name="Mme"/>
<gender id="Miss" name="Melle"/>
<gender id="Miss" name="Mlle"/>
</entity_gender>
+4 -4
View File
@@ -101,11 +101,11 @@
</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; ?> />
<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>
<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"><label for="set_license"><strong><?php echo $this->l('I agree to the above terms and conditions.') ?></strong></label></div>
<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; ?> />
<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>
<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"><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>
<?php $this->displayTemplate('footer') ?>
@@ -41,7 +41,7 @@ function add_default_restrictions_modules_groups()
FROM `'._DB_PREFIX_.'shop`');
foreach ($groups as $group)
{
if (!is_array($modules))
if (!is_array($modules) || !is_array($shops))
return false;
else
{
@@ -49,10 +49,10 @@ function add_default_restrictions_modules_groups()
foreach ($modules as $mod)
foreach ($shops as $s)
$sql .= '("'.(int)$mod['id_module'].'", "'.(int)$s.'", "'.(int)$group['id_group'].'"),';
// removing last comma to avoid SQL error
$sql = substr($sql, 0, strlen($sql) - 1);
$res &= Db::getInstance()->execute($sql);
// removing last comma to avoid SQL error
$sql = substr($sql, 0, strlen($sql) - 1);
$res &= Db::getInstance()->execute($sql);
}
}
return $res;
}
}
@@ -54,29 +54,35 @@ function generate_root_category_for_multishop()
');
$data = array();
foreach ($langs as $lang)
foreach ($shops as $shop)
$data[] = array(
'id_lang' => $lang['id_lang'],
'id_shop' => $shop['id_shop'],
'id_category' => $id,
'name' => 'Root',
'link_rewrite' => '',
);
Db::getInstance()->insert('category_lang', $data);
if(is_array($shops) && is_array($langs))
{
foreach ($langs as $lang)
foreach ($shops as $shop)
$data[] = array(
'id_lang' => $lang['id_lang'],
'id_shop' => $shop['id_shop'],
'id_category' => $id,
'name' => 'Root',
'link_rewrite' => '',
);
Db::getInstance()->insert('category_lang', $data);
}
$categories = Db::getInstance()->executeS('
SELECT `id_category`
FROM `'._DB_PREFIX_.'category`
');
$data = array();
foreach ($categories as $category)
foreach ($shops as $shop)
$data[] = array(
'id_category' => $category['id_category'],
'id_shop' => $shop['id_shop']
);
Db::getInstance()->insert('category_shop', $data);
if(is_array($shops) && is_array($categories))
{
foreach ($categories as $category)
foreach ($shops as $shop)
$data[] = array(
'id_category' => $category['id_category'],
'id_shop' => $shop['id_shop']
);
Db::getInstance()->insert('category_shop', $data);
}
Db::getInstance()->execute('
UPDATE `'._DB_PREFIX_.'category`
@@ -90,4 +96,4 @@ function generate_root_category_for_multishop()
');
generate_ntree();
}
}
@@ -160,22 +160,24 @@ function p15012_add_missing_columns()
if (empty($table))
continue;
$list_fields = $db->executeS('SHOW FIELDS FROM `'._DB_PREFIX_.$table.'`');
foreach($list_fields as $k => $field)
$list_fields[$k] = $field['Field'];
foreach ($cols as $col => $q)
{
// do only if column exists
if (in_array($col, $list_fields))
$do = 'mod';
else
$do = 'add';
if (!empty($q[$do]))
if (is_array($list_fields))
foreach($list_fields as $k => $field)
$list_fields[$k] = $field['Field'];
if (is_array($cols))
foreach ($cols as $col => $q)
{
if (!$db->execute($q[$do]))
$errors[] = '<subquery><query>'.$q[$do].'</query><error>'.$db->getMsgError().'</error></subquery>';
// do only if column exists
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)
@@ -185,5 +187,4 @@ function p15012_add_missing_columns()
}
else
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, 5, 'Sig.ra'),
(3, 1, 'Miss'),
(3, 2, 'Melle'),
(3, 2, 'Mlle'),
(3, 3, 'Miss'),
(3, 4, 'Miss'),
(3, 5, 'Miss');
+2 -2
View File
@@ -31,9 +31,9 @@
{include file="$tpl_dir./errors.tpl"}
{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}
<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}
<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">
+1 -1
View File
@@ -387,7 +387,7 @@ abstract class Controller extends ControllerCore
uasort($queries, 'prestashop_querytime_sort');
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']))
{
$explain = Db::getInstance()->executeS('explain '.$data['query']);
+32 -14
View File
@@ -2,7 +2,7 @@
/**
* Project: Smarty: the PHP compiling template engine
* 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
* modify it under the terms of the GNU Lesser General Public
@@ -28,7 +28,7 @@
* @author Uwe Tews
* @author Rodney Rehm
* @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);
}
if (!defined('SMARTY_MBSTRING')) {
define('SMARTY_MBSTRING', function_exists('mb_strlen'));
define('SMARTY_MBSTRING', function_exists('mb_split'));
}
if (!defined('SMARTY_RESOURCE_CHAR_SET')) {
// UTF-8 can only be done properly when mbstring is available!
@@ -113,7 +113,7 @@ class Smarty extends Smarty_Internal_TemplateBase {
/**
* smarty version
*/
const SMARTY_VERSION = 'Smarty-3.1.8';
const SMARTY_VERSION = 'Smarty-3.1.13';
/**
* define variable scopes
@@ -189,8 +189,12 @@ class Smarty extends Smarty_Internal_TemplateBase {
* Flag denoting if PCRE should run in UTF-8 mode
*/
public static $_UTF8_MODIFIER = 'u';
/**
* Flag denoting if operating system is windows
*/
public static $_IS_WINDOWS = false;
/**#@+
* variables
*/
@@ -1277,7 +1281,7 @@ class Smarty extends Smarty_Internal_TemplateBase {
}
// plugin filename is expected to be: [type].[name].php
$_plugin_filename = "{$_name_parts[1]}.{$_name_parts[2]}.php";
$_stream_resolve_include_path = function_exists('stream_resolve_include_path');
// loop through plugin dirs and find the plugin
@@ -1298,7 +1302,7 @@ class Smarty extends Smarty_Internal_TemplateBase {
} else {
$file = Smarty_Internal_Get_Include_Path::getIncludePath($file);
}
if ($file !== false) {
require_once($file);
return $file;
@@ -1388,10 +1392,12 @@ class Smarty extends Smarty_Internal_TemplateBase {
// add the SMARTY_DIR to the list of muted directories
if (!isset(Smarty::$_muted_directories[SMARTY_DIR])) {
$smarty_dir = realpath(SMARTY_DIR);
Smarty::$_muted_directories[SMARTY_DIR] = array(
'file' => $smarty_dir,
'length' => strlen($smarty_dir),
);
if ($smarty_dir !== false) {
Smarty::$_muted_directories[SMARTY_DIR] = array(
'file' => $smarty_dir,
'length' => strlen($smarty_dir),
);
}
}
// walk the muted directories and test against $errfile
@@ -1399,6 +1405,11 @@ class Smarty extends Smarty_Internal_TemplateBase {
if (!$dir) {
// resolve directory and length for speedy comparisons
$file = realpath($key);
if ($file === false) {
// this directory does not exist, remove and skip it
unset(Smarty::$_muted_directories[$key]);
continue;
}
$dir = array(
'file' => $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
if (Smarty::$_CHARSET !== 'UTF-8') {
Smarty::$_UTF8_MODIFIER = '';
@@ -1474,6 +1488,10 @@ if (Smarty::$_CHARSET !== 'UTF-8') {
* @package Smarty
*/
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,
);
if (preg_match('/^[0-9a-z_-]+$/i', $_class) && !strncmp($_class, 'smarty_internal_', 16) || isset($_classes[$_class])) {
include SMARTY_SYSPLUGINS_DIR . $_class . '.php';
if (!strncmp($_class, 'smarty_internal_', 16) || isset($_classes[$_class])) {
include SMARTY_SYSPLUGINS_DIR . $_class . '.php';
}
}
@@ -116,6 +116,23 @@ function smarty_function_html_checkboxes($params, $template)
case 'assign':
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:
if(!is_array($_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);
}
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:
if (!is_array($_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);
return '';
}
} else {
$value = smarty_function_escape_special_chars((string) $value);
}
$_html_result .= $_html_class . $_html_id . '>' . $value . '</option>' . "\n";
$idx++;
@@ -102,6 +102,23 @@ function smarty_function_html_radios($params, $template)
case 'assign':
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:
if (!is_array($_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
*/
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);
} elseif ($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()
* @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) {
$char_set = Smarty::$_CHARSET;
}
switch ($esc_type) {
case 'html':
/* PrestaShop
return htmlspecialchars($string, ENT_QUOTES, $char_set, $double_encode);
*/
return htmlspecialchars($string, ENT_QUOTES, $char_set);
/* END */
if ($_double_encode) {
// php >=5.3.2 - go native
return htmlspecialchars($string, ENT_QUOTES, $char_set, $double_encode);
} else {
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':
if (Smarty::$_MBSTRING) {
// mb_convert_encoding ignores htmlspecialchars()
/* PrestaShop
return htmlspecialchars($string, ENT_QUOTES, $char_set, $double_encode);
*/
return htmlspecialchars($string, ENT_QUOTES, $char_set);
/* END */
if ($_double_encode) {
// php >=5.3.2 - go native
$string = htmlspecialchars($string, ENT_QUOTES, $char_set, $double_encode);
} else {
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
return mb_convert_encoding($string, 'HTML-ENTITIES', $char_set);
}
// no MBString fallback
/* PrestaShop
return htmlentities($string, ENT_QUOTES, $char_set, $double_encode);
*/
return htmlentities($string, ENT_QUOTES, $char_set);
/* END */
if ($_double_encode) {
return htmlentities($string, ENT_QUOTES, $char_set, $double_encode);
} else {
if ($double_encode) {
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':
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)
{
static $_double_encode = null;
if ($_double_encode === null) {
$_double_encode = version_compare(PHP_VERSION, '5.2.3', '>=');
}
try {
$esc_type = smarty_literal_compiler_param($params, 1, 'html');
$char_set = smarty_literal_compiler_param($params, 2, Smarty::$_CHARSET);
@@ -36,48 +41,56 @@ function smarty_modifiercompiler_escape($params, $compiler)
switch ($esc_type) {
case 'html':
/* PrestaShop
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('
if ($_double_encode) {
return 'htmlspecialchars('
. $params[0] .', ENT_QUOTES, '
. var_export($char_set, true) . ', '
. var_export($double_encode, true)
. '), "HTML-ENTITIES", '
. var_export($char_set, true) . ')';
}
*/
if (Smarty::$_MBSTRING) {
return 'mb_convert_encoding(htmlspecialchars('
. var_export($double_encode, true) . ')';
} else if ($double_encode) {
return 'htmlspecialchars('
. $params[0] .', ENT_QUOTES, '
. var_export($char_set, true)
. '), "HTML-ENTITIES", '
. 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
/* PrestaShop
return 'htmlentities('
. $params[0] .', ENT_QUOTES, '
. var_export($char_set, true) . ', '
. var_export($double_encode, true) . ')';
*/
return 'htmlentities('
. $params[0] .', ENT_QUOTES, '
. var_export($char_set, true) . ')';
/* END */
if ($_double_encode) {
// php >=5.2.3 - go native
return 'htmlentities('
. $params[0] .', ENT_QUOTES, '
. var_export($char_set, true) . ', '
. var_export($double_encode, true) . ')';
} else if ($double_encode) {
// php <5.2.3 - only handle double encoding
return 'htmlentities('
. $params[0] .', ENT_QUOTES, '
. var_export($char_set, true) . ')';
} else {
// fall back to modifier.escape.php
}
case 'url':
return 'rawurlencode(' . $params[0] . ')';
@@ -40,6 +40,7 @@ function smarty_outputfilter_trimwhitespace($source, Smarty_Internal_Template $s
}
// Strip all HTML-Comments
// yes, even the ones in <script> - see http://stackoverflow.com/a/808850/515124
$source = preg_replace( '#<!--.*?-->#ms', '', $source );
// 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)
{
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;
return true;
if ($_template->cached->exists) {
return true;
}
}
return false;
}
@@ -181,7 +183,7 @@ class Smarty_Internal_CacheResource_File extends Smarty_CacheResource {
if (preg_match('/^(\.|\.\.|\.svn|index\.php)$/', $_file->getFilename()))
continue;
/* End */
// directory ?
if ($_file->isDir()) {
if (!$_cache->isDot()) {
@@ -39,7 +39,11 @@ class Smarty_Internal_Compile_Assign extends Smarty_Internal_CompileBase {
if ($compiler->tag_nocache || $compiler->nocache) {
$_nocache = 'true';
// 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
if (isset($_attr['scope'])) {
@@ -58,7 +62,14 @@ class Smarty_Internal_Compile_Assign extends Smarty_Internal_CompileBase {
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];";
} 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) {
$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
/**
* Smarty Internal Plugin Compile Block
*
* Compiles the {block}{/block} tags
*
* @package Smarty
* @subpackage Compiler
* @author Uwe Tews
*/
/**
* Smarty Internal Plugin Compile Block Class
*
* @package Smarty
* @subpackage Compiler
*/
* Smarty Internal Plugin Compile Block
*
* Compiles the {block}{/block} tags
*
* @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 {
/**
* Attribute definition: Overwrites base class.
*
* @var array
* @see Smarty_Internal_CompileBase
*/
* Attribute definition: Overwrites base class.
*
* @var array
* @see Smarty_Internal_CompileBase
*/
public $required_attributes = array('name');
/**
* Attribute definition: Overwrites base class.
*
* @var array
* @see Smarty_Internal_CompileBase
*/
* Attribute definition: Overwrites base class.
*
* @var array
* @see Smarty_Internal_CompileBase
*/
public $shorttag_order = array('name', 'hide');
/**
* Attribute definition: Overwrites base class.
*
* @var array
* @see Smarty_Internal_CompileBase
*/
* Attribute definition: Overwrites base class.
*
* @var array
* @see Smarty_Internal_CompileBase
*/
public $optional_attributes = array('hide');
/**
* Compiles code for the {block} tag
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @return boolean true
*/
public function compile($args, $compiler)
{
* Compiles code for the {block} tag
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @return boolean true
*/
public function compile($args, $compiler) {
// check and get attributes
$_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);
@@ -66,18 +68,17 @@ class Smarty_Internal_Compile_Block extends Smarty_Internal_CompileBase {
}
/**
* Save or replace child block source by block name during parsing
*
* @param string $block_content block source content
* @param string $block_tag opening block tag
* @param object $template template object
* @param string $filepath filepath of template source
*/
public static function saveBlockData($block_content, $block_tag, $template, $filepath)
{
* Save or replace child block source by block name during parsing
*
* @param string $block_content block source content
* @param string $block_tag opening block tag
* @param object $template template object
* @param string $filepath filepath of template source
*/
public static function saveBlockData($block_content, $block_tag, $template, $filepath) {
$_rdl = preg_quote($template->smarty->right_delimiter);
$_ldl = preg_quote($template->smarty->left_delimiter);
if ($template->smarty->auto_literal) {
if (!$template->smarty->auto_literal) {
$al = '\s*';
} else {
$al = '';
@@ -88,24 +89,34 @@ class Smarty_Internal_Compile_Block extends Smarty_Internal_CompileBase {
} else {
$_name = trim($_match[3], '\'"');
if ($_match[8] != 'hide' || isset($template->block_data[$_name])) { // replace {$smarty.block.child}
// do we have {$smart.block.child} in 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)) {
foreach($_match2[3] as $name) {
// get nested block tags
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 $key => $name) {
// get it's replacement
$_name2 = trim($name, '\'"');
if (isset($template->block_data[$_name2])) {
$replacement = $template->block_data[$_name2]['source'];
if ($_match2[5][$key] != 'hide' || isset($template->block_data[$_name2])) {
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 {
$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}
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
if (isset($template->block_data[$_name])) {
$replacement = $template->block_data[$_name]['source'];
@@ -113,12 +124,12 @@ class Smarty_Internal_Compile_Block extends Smarty_Internal_CompileBase {
} else {
$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 (strpos($template->block_data[$_name]['source'], '%%%%SMARTY_PARENT%%%%') !== false) {
$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') {
$template->block_data[$_name]['source'] .= $block_content;
} 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
*
* @param object $compiler compiler object
* @param string $_name optional name of child block
* @return string compiled code of schild block
*/
public static function compileChildBlock($compiler, $_name = null)
{
* Compile saved child block source
*
* @param object $compiler compiler object
* @param string $_name optional name of child block
* @return string compiled code of schild block
*/
public static function compileChildBlock($compiler, $_name = null) {
$_output = '';
// if called by {$smarty.block.child} we must search the name of enclosing {block}
if ($_name == null) {
$stack_count = count($compiler->_tag_stack);
while (--$stack_count >= 0) {
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;
}
}
@@ -168,8 +178,8 @@ class Smarty_Internal_Compile_Block extends Smarty_Internal_CompileBase {
if (!isset($compiler->template->block_data[$_name]['source'])) {
return '';
}
$_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);
$_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);
$_tpl->variable_filters = $compiler->template->variable_filters;
$_tpl->properties['nocache_hash'] = $compiler->template->properties['nocache_hash'];
$_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) {
$compiler->template->has_nocache_code = true;
}
foreach($_tpl->required_plugins as $key => $tmp1) {
if ($compiler->nocache) {
foreach ($_tpl->required_plugins as $key => $tmp1) {
if ($compiler->nocache && $compiler->template->caching) {
$code = 'nocache';
} else {
$code = $key;
}
foreach($tmp1 as $name => $tmp) {
foreach($tmp as $type => $data) {
foreach ($tmp1 as $name => $tmp) {
foreach ($tmp as $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
*
* @package Smarty
* @subpackage Compiler
*/
* Smarty Internal Plugin Compile BlockClose Class
*
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_Blockclose extends Smarty_Internal_CompileBase {
/**
* Compiles code for the {/block} tag
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @return string compiled code
*/
public function compile($args, $compiler)
{
* Compiles code for the {/block} tag
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @return string compiled code
*/
public function compile($args, $compiler) {
$compiler->has_code = true;
// check and get attributes
$_attr = $this->getAttributes($compiler, $args);
@@ -255,12 +264,12 @@ class Smarty_Internal_Compile_Blockclose extends Smarty_Internal_CompileBase {
} else {
$_output = $compiler->parser->current_buffer->to_smarty_php();
}
unset ($compiler->template->block_data[$_name]['compiled']);
unset($compiler->template->block_data[$_name]['compiled']);
}
// reset flags
$compiler->parser->current_buffer = $saved_data[1];
$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
$compiler->inheritance = false;
// $_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);
$this->_rdl = preg_quote($compiler->smarty->right_delimiter);
$this->_ldl = preg_quote($compiler->smarty->left_delimiter);
if (!$compiler->smarty->auto_literal) {
$al = '\s*';
} else {
$al = '';
}
$filepath = $compiler->template->source->filepath;
$this->mbstring_overload = ini_get('mbstring.func_overload') & 2;
// 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->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));
if (preg_match_all("!({$this->_ldl}block\s(.+?){$this->_rdl})!", $_content, $s) !=
preg_match_all("!({$this->_ldl}/block{$this->_rdl})!", $_content, $c)) {
$_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}{$al}block\s(.+?)\s*{$this->_rdl})!", $_content, $s) !=
preg_match_all("!({$this->_ldl}{$al}/block\s*{$this->_rdl})!", $_content, $c)) {
$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]);
$_start = 0;
while ($_start+1 < $_result_count) {
@@ -149,7 +149,8 @@ class Smarty_Internal_Compile_Functionclose extends Smarty_Internal_CompileBase
$compiler->has_code = false;
$output = true;
} 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
$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
* @return string compiled code
*/
public function compile($args, $compiler, $parameter)
{
public function compile($args, $compiler, $parameter) {
// check and get attributes
$_attr = $this->getAttributes($compiler, $args);
$output = $parameter['value'];
@@ -36,40 +35,100 @@ class Smarty_Internal_Compile_Private_Modifier extends Smarty_Internal_CompileBa
$modifier = $single_modifier[0];
$single_modifier[0] = $output;
$params = implode(',', $single_modifier);
// check for 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 . ')';
}
}
} 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})";
}
// check if we know already the type of modifier
if (isset($compiler->known_modifier_type[$modifier])) {
$modifier_types = array($compiler->known_modifier_type[$modifier]);
} 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);
}
}
@@ -77,10 +77,14 @@ class Smarty_Internal_Compile_Private_Special_Variable extends Smarty_Internal_C
$compiler->trigger_template_error("(secure mode) constants not permitted");
break;
}
return '@' . trim($_index[1], "'");
return "@constant({$_index[1]})";
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':
$_ldelim = $compiler->smarty->left_delimiter;
return "'$_ldelim'";
@@ -240,9 +240,8 @@ class Smarty_Internal_Config {
}
// scan sections
if (!empty($sections)) {
$sections = array_flip((array) $sections);
foreach ($_config_vars['sections'] as $this_section => $dummy) {
if (isset($sections[$this_section])) {
foreach ((array) $sections as $this_section) {
if (isset($_config_vars['sections'][$this_section])) {
foreach ($_config_vars['sections'][$this_section]['vars'] as $variable => $value) {
if ($this->smarty->config_overwrite || !isset($scope_ptr->config_vars[$variable])) {
$scope_ptr->config_vars[$variable] = $value;
@@ -80,6 +80,11 @@ class Smarty_Internal_Data {
{
if ($varname != '') {
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;
@@ -89,6 +89,11 @@ class Smarty_Internal_Resource_Extends extends Smarty_Resource {
$this->mbstring_overload = ini_get('mbstring.func_overload') & 2;
$_rdl = preg_quote($source->smarty->right_delimiter);
$_ldl = preg_quote($source->smarty->left_delimiter);
if (!$source->smarty->auto_literal) {
$al = '\s*';
} else {
$al = '';
}
$_components = array_reverse($source->components);
$_first = reset($_components);
$_last = end($_components);
@@ -105,11 +110,11 @@ class Smarty_Internal_Resource_Extends extends Smarty_Resource {
// extend sources
if ($_component != $_last) {
if (preg_match_all("!({$_ldl}block\s(.+?){$_rdl})!", $_content, $_open) !=
preg_match_all("!({$_ldl}/block{$_rdl})!", $_content, $_close)) {
if (preg_match_all("!({$_ldl}{$al}block\s(.+?)\s*{$_rdl})!", $_content, $_open) !=
preg_match_all("!({$_ldl}{$al}/block\s*{$_rdl})!", $_content, $_close)) {
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]);
$_start = 0;
while ($_start+1 < $_result_count) {
@@ -1,36 +1,40 @@
<?php
/**
* Smarty Internal Plugin Resource Stream
*
* Implements the streams as resource for Smarty template
*
* @package Smarty
* @subpackage TemplateResources
* @author Uwe Tews
* @author Rodney Rehm
*/
* Smarty Internal Plugin Resource Stream
*
* Implements the streams as resource for Smarty template
*
* @package Smarty
* @subpackage TemplateResources
* @author Uwe Tews
* @author Rodney Rehm
*/
/**
* Smarty Internal Plugin Resource Stream
*
* Implements the streams as resource for Smarty template
*
* @link http://php.net/streams
* @package Smarty
* @subpackage TemplateResources
*/
* Smarty Internal Plugin Resource Stream
*
* Implements the streams as resource for Smarty template
*
* @link http://php.net/streams
* @package Smarty
* @subpackage TemplateResources
*/
class Smarty_Internal_Resource_Stream extends Smarty_Resource_Recompiled {
/**
* populate Source Object with meta data from Resource
*
* @param Smarty_Template_Source $source source object
* @param Smarty_Internal_Template $_template template object
* @return void
*/
* populate Source Object with meta data from Resource
*
* @param Smarty_Template_Source $source source object
* @param Smarty_Internal_Template $_template template object
* @return void
*/
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->content = $this->getContent($source);
$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
*
* @param Smarty_Template_Source $source source object
* @return string template source
* @throws SmartyException if source cannot be loaded
*/
* Load template's source from stream into current template object
*
* @param Smarty_Template_Source $source source object
* @return string template source
* @throws SmartyException if source cannot be loaded
*/
public function getContent(Smarty_Template_Source $source)
{
$t = '';
@@ -59,18 +63,16 @@ class Smarty_Internal_Resource_Stream extends Smarty_Resource_Recompiled {
return false;
}
}
/**
* modify resource_name according to resource handlers specifications
*
* @param Smarty $smarty Smarty instance
* @param string $resource_name resource_name to make unique
* @return string unique resource name
*/
* modify resource_name according to resource handlers specifications
*
* @param Smarty $smarty Smarty instance
* @param string $resource_name resource_name to make unique
* @return string unique resource name
*/
protected function buildUniqueResourceName(Smarty $smarty, $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
if ($parent_scope == Smarty::SCOPE_LOCAL) {
$tpl->tpl_vars = $this->tpl_vars;
$tpl->tpl_vars['smarty'] = clone $this->tpl_vars['smarty'];
} elseif ($parent_scope == Smarty::SCOPE_PARENT) {
$tpl->tpl_vars = &$this->tpl_vars;
} elseif ($parent_scope == Smarty::SCOPE_GLOBAL) {
@@ -305,6 +306,7 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase {
// get variables from calling scope
if ($parent_scope == Smarty::SCOPE_LOCAL ) {
$tpl->tpl_vars = $this->tpl_vars;
$tpl->tpl_vars['smarty'] = clone $this->tpl_vars['smarty'];
} elseif ($parent_scope == Smarty::SCOPE_PARENT) {
$tpl->tpl_vars = &$this->tpl_vars;
} 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 ($tmp as $data) {
$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 .= '?>';
@@ -353,7 +359,11 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase {
foreach ($this->required_plugins['nocache'] as $tmp) {
foreach ($tmp as $data) {
$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";
@@ -442,7 +452,7 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase {
$mtime = $this->source->timestamp;
} else {
// 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') {
continue;
@@ -450,7 +460,7 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase {
$source = Smarty_Resource::source(null, $this->smarty, $_file_to_check[0]);
$mtime = $source->timestamp;
}
if ($mtime > $_file_to_check[1]) {
if (!$mtime || $mtime > $_file_to_check[1]) {
$is_valid = false;
break;
}
@@ -319,7 +319,7 @@ abstract class Smarty_Internal_TemplateBase extends Smarty_Internal_Data {
break;
default:
header('HTTP/1.1 304 Not Modified');
header($_SERVER['SERVER_PROTOCOL'].' 304 Not Modified');
break;
}
} else {
@@ -1,4 +1,5 @@
<?php
/**
* Smarty Internal Plugin Smarty Template Compiler Base
*
@@ -23,101 +24,130 @@ abstract class Smarty_Internal_TemplateCompilerBase {
* @var mixed
*/
private $nocache_hash = null;
/**
* suppress generation of nocache code
*
* @var bool
*/
public $suppressNocacheProcessing = false;
/**
* suppress generation of merged template code
*
* @var bool
*/
public $suppressMergedTemplates = false;
/**
* compile tag objects
*
* @var array
*/
public static $_tag_objects = array();
/**
* tag stack
*
* @var array
*/
public $_tag_stack = array();
/**
* current template
*
* @var Smarty_Internal_Template
*/
public $template = null;
/**
* merged templates
*
* @var array
*/
public $merged_templates = array();
/**
* flag when compiling {block}
*
* @var bool
*/
public $inheritance = false;
/**
* plugins loaded by default plugin handler
*
* @var array
*/
public $default_handler_plugins = array();
/**
* saved preprocessed modifier list
*
* @var mixed
*/
public $default_modifier_list = null;
/**
* force compilation of complete template as nocache
* @var boolean
*/
public $forceNocache = false;
/**
* suppress Smarty header code in compiled template
* @var bool
*/
public $suppressHeader = false;
/**
* suppress template property header code in compiled template
* @var bool
*/
public $suppressTemplatePropertyHeader = false;
/**
* flag if compiled template file shall we written
* @var bool
*/
public $write_compiled_code = true;
/**
* flag if currently a template function is compiled
* @var bool
*/
public $compiles_template_function = false;
/**
* called subfuntions from template function
* @var array
*/
public $called_functions = array();
/**
* flags for used modifier plugins
* @var 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
*/
public function __construct()
{
public function __construct() {
$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
* @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'])) {
$template->properties['nocache_hash'] = $this->nocache_hash;
} else {
@@ -156,7 +185,7 @@ abstract class Smarty_Internal_TemplateCompilerBase {
$_content = $template->source->content;
// run prefilter if required
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
if ($_content == '') {
@@ -194,6 +223,8 @@ abstract class Smarty_Internal_TemplateCompilerBase {
} else {
$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;
}
@@ -208,8 +239,7 @@ abstract class Smarty_Internal_TemplateCompilerBase {
* @param array $parameter array with compilation parameter
* @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
// assume that tag does compile into code, but creates no HTML output
$this->has_code = true;
@@ -219,8 +249,8 @@ abstract class Smarty_Internal_TemplateCompilerBase {
$this->template->used_tags[] = array($tag, $args);
}
// check nocache option flag
if (in_array("'nocache'",$args) || in_array(array('nocache'=>'true'),$args)
|| in_array(array('nocache'=>'"true"'),$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)) {
$this->tag_nocache = true;
}
// 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'])) {
$methode = $parameter['object_methode'];
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);
} elseif (in_array($methode, $this->smarty->registered_objects[$tag][3])) {
return $this->callTagCompiler('private_object_block_function', $args, $parameter, $tag, $methode);
} 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
@@ -275,10 +305,10 @@ abstract class Smarty_Internal_TemplateCompilerBase {
if ($plugin_type == Smarty::PLUGIN_COMPILER) {
$new_args = array();
foreach ($args as $key => $mixed) {
if (is_array($mixed)) {
$new_args = array_merge($new_args, $mixed);
if (is_array($mixed)) {
$new_args = array_merge($new_args, $mixed);
} else {
$new_args[$key] = $mixed;
$new_args[$key] = $mixed;
}
}
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) {
return $this->callTagCompiler('private_registered_' . $plugin_type, $args, $parameter, $tag);
}
}
}
// check plugins from plugins folder
@@ -308,10 +337,10 @@ abstract class Smarty_Internal_TemplateCompilerBase {
// convert arguments format for old compiler plugins
$new_args = array();
foreach ($args as $key => $mixed) {
if (is_array($mixed)) {
$new_args = array_merge($new_args, $mixed);
if (is_array($mixed)) {
$new_args = array_merge($new_args, $mixed);
} else {
$new_args[$key] = $mixed;
$new_args[$key] = $mixed;
}
}
return $plugin($new_args, $this->smarty);
@@ -325,7 +354,7 @@ abstract class Smarty_Internal_TemplateCompilerBase {
throw new SmartyException("Plugin \"{$tag}\" not callable");
} else {
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);
}
}
@@ -378,7 +407,7 @@ abstract class Smarty_Internal_TemplateCompilerBase {
if (in_array($methode, $this->smarty->registered_objects[$base_tag][3])) {
return $this->callTagCompiler('private_object_block_function', $args, $parameter, $tag, $methode);
} 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 ?
@@ -389,6 +418,22 @@ abstract class Smarty_Internal_TemplateCompilerBase {
if ($function = $this->getPlugin($base_tag, Smarty::PLUGIN_BLOCK)) {
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)) {
$plugin = 'smarty_compiler_' . $tag;
if (is_callable($plugin)) {
@@ -403,7 +448,7 @@ abstract class Smarty_Internal_TemplateCompilerBase {
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
* @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
if (isset(self::$_tag_objects[$tag])) {
// compile this tag
@@ -433,10 +477,10 @@ abstract class Smarty_Internal_TemplateCompilerBase {
if ($this->smarty->loadPlugin($class_name)) {
// check if tag allowed by security
if (!isset($this->smarty->security_policy) || $this->smarty->security_policy->isTrustedTag($tag, $this)) {
// use plugin if found
self::$_tag_objects[$tag] = new $class_name;
// compile this tag
return self::$_tag_objects[$tag]->compile($args, $this, $param1, $param2, $param3);
// use plugin if found
self::$_tag_objects[$tag] = new $class_name;
// compile this tag
return self::$_tag_objects[$tag]->compile($args, $this, $param1, $param2, $param3);
}
}
// no internal compile plugin for this tag
@@ -450,8 +494,7 @@ abstract class Smarty_Internal_TemplateCompilerBase {
* @param string $plugin_type type of plugin
* @return string call name of function
*/
public function getPlugin($plugin_name, $plugin_type)
{
public function getPlugin($plugin_name, $plugin_type) {
$function = null;
if ($this->template->caching && ($this->nocache || $this->tag_nocache)) {
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
* @return boolean true if found
*/
public function getPluginFromDefaultHandler($tag, $plugin_type)
{
public function getPluginFromDefaultHandler($tag, $plugin_type) {
$callback = null;
$script = null;
$cacheable = true;
$result = call_user_func_array(
$this->smarty->default_plugin_handler_func,
array($tag, $plugin_type, $this->template, &$callback, &$script, &$cacheable)
$this->smarty->default_plugin_handler_func, array($tag, $plugin_type, $this->template, &$callback, &$script, &$cacheable)
);
if ($result) {
$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;
}
include_once $script;
} else {
} else {
$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
* @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 ($is_code && !empty($content)) {
// generate replacement code
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;
$_output = str_replace("'", "\'", $content);
$_output = str_replace('\\\\', '\\\\\\', $_output);
$_output = addcslashes($content,'\'\\');
$_output = str_replace("^#^", "'", $_output);
$_output = "<?php echo '/*%%SmartyNocache:{$this->nocache_hash}%%*/" . $_output . "/*/%%SmartyNocache:{$this->nocache_hash}%%*/';?>\n";
// make sure we include modifer plugins for nocache code
@@ -596,21 +635,20 @@ abstract class Smarty_Internal_TemplateCompilerBase {
* @param string $line line-number
* @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
if (!isset($line)) {
$line = $this->lex->line;
}
$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)) {
// individual error message
$error_text .= $args;
} else {
// expected token from parser
$error_text .= ' - Unexpected "' . $this->lex->value.'"';
if (count($this->parser->yy_get_expected_tokens($this->parser->yymajor)) <= 4 ) {
$error_text .= ' - Unexpected "' . $this->lex->value . '"';
if (count($this->parser->yy_get_expected_tokens($this->parser->yymajor)) <= 4) {
foreach ($this->parser->yy_get_expected_tokens($this->parser->yymajor) as $token) {
$exp_token = $this->parser->yyTokenName[$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_length = strlen($this->smarty->left_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['RDEL'] = $this->smarty->right_delimiter;
$this->mbstring_overload = ini_get('mbstring.func_overload') & 2;
@@ -141,11 +142,12 @@ class Smarty_Internal_Templatelexer
21 => 0,
22 => 0,
23 => 0,
24 => 0,
);
if ($this->counter >= ($this->mbstring_overload ? mb_strlen($this->data,'latin1'): strlen($this->data))) {
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 {
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)
{
$this->token = Smarty_Internal_Templateparser::TP_ASPSTARTTAG;
$this->token = Smarty_Internal_Templateparser::TP_TEXT;
}
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)
{
$this->token = Smarty_Internal_Templateparser::TP_ASPENDTAG;
}
function yy_r1_24($yy_subpatterns)
{
if ($this->mbstring_overload) {
$to = mb_strlen($this->data,'latin1');
} else {
@@ -442,11 +449,12 @@ class Smarty_Internal_Templatelexer
74 => 0,
75 => 0,
76 => 0,
77 => 0,
);
if ($this->counter >= ($this->mbstring_overload ? mb_strlen($this->data,'latin1'): strlen($this->data))) {
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 {
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)
{
$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)
{
$this->token = Smarty_Internal_Templateparser::TP_INTEGER;
$this->token = Smarty_Internal_Templateparser::TP_ID;
}
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)
{
$this->token = Smarty_Internal_Templateparser::TP_SPACE;
}
function yy_r2_77($yy_subpatterns)
{
$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);
$_compile = new RecursiveIteratorIterator($_compileDirs);
foreach ($_compile as $_fileinfo) {
if (substr($_fileinfo->getBasename(),0,1) == '.' || strpos($_fileinfo, '.svn') !== false) continue;
$_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 ($_fileinfo->getPath() == substr($_dir, 0, -1)) {
$_template_file = $_file;
@@ -87,6 +87,7 @@ class Smarty_Internal_Utility {
$_tpl = $smarty->createTemplate($_template_file,null,null,null,false);
if ($_tpl->mustCompile()) {
$_tpl->compileTemplateSource();
$_count++;
echo ' compiled in ', microtime(true) - $_start_time, ' seconds';
flush();
} else {
@@ -135,8 +136,8 @@ class Smarty_Internal_Utility {
$_compileDirs = new RecursiveDirectoryIterator($_dir);
$_compile = new RecursiveIteratorIterator($_compileDirs);
foreach ($_compile as $_fileinfo) {
if (substr($_fileinfo->getBasename(),0,1) == '.' || strpos($_fileinfo, '.svn') !== false) continue;
$_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 ($_fileinfo->getPath() == substr($_dir, 0, -1)) {
$_config_file = $_file;
@@ -150,6 +151,7 @@ class Smarty_Internal_Utility {
$_config = new Smarty_Internal_Config($_config_file, $smarty);
if ($_config->mustCompile()) {
$_config->compileConfigSource();
$_count++;
echo ' compiled in ', microtime(true) - $_start_time, ' seconds';
flush();
} else {
@@ -229,7 +231,7 @@ class Smarty_Internal_Utility {
}
$_compile = new RecursiveIteratorIterator($_compileDirs, RecursiveIteratorIterator::CHILD_FIRST);
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;
$_filepath = (string) $_file;
@@ -299,7 +301,7 @@ class Smarty_Internal_Utility {
echo "Smarty Installation test...\n";
echo "Testing template directory...\n";
}
$_stream_resolve_include_path = function_exists('stream_resolve_include_path');
// test if all registered template_dir are accessible
@@ -315,7 +317,7 @@ class Smarty_Internal_Utility {
} else {
$template_dir = Smarty_Internal_Get_Include_Path::getIncludePath($_template_dir);
}
if ($template_dir !== false) {
if ($errors === null) {
echo "$template_dir is OK.\n";
@@ -436,7 +438,7 @@ class Smarty_Internal_Utility {
} else {
$plugin_dir = Smarty_Internal_Get_Include_Path::getIncludePath($_plugin_dir);
}
if ($plugin_dir !== false) {
if ($errors === null) {
echo "$plugin_dir is OK.\n";
@@ -568,7 +570,7 @@ class Smarty_Internal_Utility {
} else {
$config_dir = Smarty_Internal_Get_Include_Path::getIncludePath($_config_dir);
}
if ($config_dir !== false) {
if ($errors === null) {
echo "$config_dir is OK.\n";
@@ -44,12 +44,30 @@ class Smarty_Internal_Write_File {
throw new SmartyException("unable to write file {$_tmp_file}");
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) {
error_reporting($_error_reporting);
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';
}
/**
* 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
*
@@ -181,43 +226,22 @@ abstract class Smarty_Resource {
// resolve relative path
if (!preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $file)) {
$_was_relative_prefix = $file[0] == '.' ? substr($file, 0, strpos($file, '|')) : null;
$_path = DS . trim($file, '/\\');
// don't we all just love windows?
$_path = str_replace('\\', '/', $file);
$_path = DS . trim($file, '/');
$_was_relative = true;
} else {
$_path = $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);
// don't we all just love windows?
$_path = str_replace('\\', '/', $file);
}
$_path = $this->normalizePath($_path, false);
if (DS != '/') {
// don't we all just love windows?
$_path = str_replace('/', '\\', $_path);
}
// revert to relative
if (isset($_was_relative)) {
if (isset($_was_relative_prefix)){
$_path = $_was_relative_prefix . $_path;
} else {
$_path = substr($_path, 1);
}
$_path = substr($_path, 1);
}
// this is only required for directories
@@ -254,7 +278,7 @@ abstract class Smarty_Resource {
}
}
}
$_stream_resolve_include_path = function_exists('stream_resolve_include_path');
// relative file name?
@@ -262,7 +286,7 @@ abstract class Smarty_Resource {
foreach ($_directories as $_directory) {
$_filepath = $_directory . $file;
if ($this->fileExists($source, $_filepath)) {
return $_filepath;
return $this->normalizePath($_filepath);
}
if ($source->smarty->use_include_path && !preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $_directory)) {
// try PHP include_path
@@ -271,10 +295,10 @@ abstract class Smarty_Resource {
} else {
$_filepath = Smarty_Internal_Get_Include_Path::getIncludePath($_filepath);
}
if ($_filepath !== false) {
if ($this->fileExists($source, $_filepath)) {
return $_filepath;
return $this->normalizePath($_filepath);
}
}
}
@@ -493,6 +517,9 @@ abstract class Smarty_Resource {
// check runtime cache
$_cache_key = 'template|' . $unique_resource_name;
if ($smarty->compile_id) {
$_cache_key .= '|'.$smarty->compile_id;
}
if (isset(self::$sources[$_cache_key])) {
return self::$sources[$_cache_key];
}