#!/bin/bash # Patch apllying tool template # v0.1.2 # (c) Copyright 2013. Magento Inc. # # DO NOT CHANGE ANY LINE IN THIS FILE. # 1. Check required system tools _check_installed_tools() { local missed="" until [ -z "$1" ]; do type -t $1 >/dev/null 2>/dev/null if (( $? != 0 )); then missed="$missed $1" fi shift done echo $missed } REQUIRED_UTILS='sed patch' MISSED_REQUIRED_TOOLS=`_check_installed_tools $REQUIRED_UTILS` if (( `echo $MISSED_REQUIRED_TOOLS | wc -w` > 0 )); then echo -e "Error! Some required system tools, that are utilized in this sh script, are not installed:\nTool(s) \"$MISSED_REQUIRED_TOOLS\" is(are) missed, please install it(them)." exit 1 fi # 2. Determine bin path for system tools CAT_BIN=`which cat` PATCH_BIN=`which patch` SED_BIN=`which sed` PWD_BIN=`which pwd` BASENAME_BIN=`which basename` BASE_NAME=`$BASENAME_BIN "$0"` # 3. Help menu if [ "$1" = "-?" -o "$1" = "-h" -o "$1" = "--help" ] then $CAT_BIN << EOFH Usage: sh $BASE_NAME [--help] [-R|--revert] [--list] Apply embedded patch. -R, --revert Revert previously applied embedded patch --list Show list of applied patches --help Show this help message EOFH exit 0 fi # 4. Get "revert" flag and "list applied patches" flag REVERT_FLAG= SHOW_APPLIED_LIST=0 if [ "$1" = "-R" -o "$1" = "--revert" ] then REVERT_FLAG=-R fi if [ "$1" = "--list" ] then SHOW_APPLIED_LIST=1 fi # 5. File pathes CURRENT_DIR=`$PWD_BIN`/ APP_ETC_DIR=`echo "$CURRENT_DIR""app/etc/"` APPLIED_PATCHES_LIST_FILE=`echo "$APP_ETC_DIR""applied.patches.list"` # 6. Show applied patches list if requested if [ "$SHOW_APPLIED_LIST" -eq 1 ] ; then echo -e "Applied/reverted patches list:" if [ -e "$APPLIED_PATCHES_LIST_FILE" ] then if [ ! -r "$APPLIED_PATCHES_LIST_FILE" ] then echo "ERROR: \"$APPLIED_PATCHES_LIST_FILE\" must be readable so applied patches list can be shown." exit 1 else $SED_BIN -n "/SUP-\|SUPEE-/p" $APPLIED_PATCHES_LIST_FILE fi else echo "" fi exit 0 fi # 7. Check applied patches track file and its directory _check_files() { if [ ! -e "$APP_ETC_DIR" ] then echo "ERROR: \"$APP_ETC_DIR\" must exist for proper tool work." exit 1 fi if [ ! -w "$APP_ETC_DIR" ] then echo "ERROR: \"$APP_ETC_DIR\" must be writeable for proper tool work." exit 1 fi if [ -e "$APPLIED_PATCHES_LIST_FILE" ] then if [ ! -w "$APPLIED_PATCHES_LIST_FILE" ] then echo "ERROR: \"$APPLIED_PATCHES_LIST_FILE\" must be writeable for proper tool work." exit 1 fi fi } _check_files # 8. Apply/revert patch # Note: there is no need to check files permissions for files to be patched. # "patch" tool will not modify any file if there is not enough permissions for all files to be modified. # Get start points for additional information and patch data SKIP_LINES=$((`$SED_BIN -n "/^__PATCHFILE_FOLLOWS__$/=" "$CURRENT_DIR""$BASE_NAME"` + 1)) ADDITIONAL_INFO_LINE=$(($SKIP_LINES - 3))p _apply_revert_patch() { DRY_RUN_FLAG= if [ "$1" = "dry-run" ] then DRY_RUN_FLAG=" --dry-run" echo "Checking if patch can be applied/reverted successfully..." fi PATCH_APPLY_REVERT_RESULT=`$SED_BIN -e '1,/^__PATCHFILE_FOLLOWS__$/d' "$CURRENT_DIR""$BASE_NAME" | $PATCH_BIN $DRY_RUN_FLAG $REVERT_FLAG -p0` PATCH_APPLY_REVERT_STATUS=$? if [ $PATCH_APPLY_REVERT_STATUS -eq 1 ] ; then echo -e "ERROR: Patch can't be applied/reverted successfully.\n\n$PATCH_APPLY_REVERT_RESULT" exit 1 fi if [ $PATCH_APPLY_REVERT_STATUS -eq 2 ] ; then echo -e "ERROR: Patch can't be applied/reverted successfully." exit 2 fi } REVERTED_PATCH_MARK= if [ -n "$REVERT_FLAG" ] then REVERTED_PATCH_MARK=" | REVERTED" fi _apply_revert_patch dry-run _apply_revert_patch # 9. Track patch applying result echo "Patch was applied/reverted successfully." ADDITIONAL_INFO=`$SED_BIN -n ""$ADDITIONAL_INFO_LINE"" "$CURRENT_DIR""$BASE_NAME"` APPLIED_REVERTED_ON_DATE=`date -u +"%F %T UTC"` APPLIED_REVERTED_PATCH_INFO=`echo -n "$APPLIED_REVERTED_ON_DATE"" | ""$ADDITIONAL_INFO""$REVERTED_PATCH_MARK"` echo -e "$APPLIED_REVERTED_PATCH_INFO\n$PATCH_APPLY_REVERT_RESULT\n\n" >> "$APPLIED_PATCHES_LIST_FILE" exit 0 SUPEE-11219_CE_1936 | CE_1.9.3.6 | v1 | 8c6eafd72fd3dc9255332f0f6ccb483fa3a94bc2 | Fri Oct 4 21:26:43 2019 +0000 | 3ef303818fe6e7ce784f376b6ef22d636db93a8b..HEAD __PATCHFILE_FOLLOWS__ diff --git app/code/core/Mage/Admin/Model/User.php app/code/core/Mage/Admin/Model/User.php index dc60a65245e..9a6b8c39f78 100644 --- app/code/core/Mage/Admin/Model/User.php +++ app/code/core/Mage/Admin/Model/User.php @@ -74,14 +74,25 @@ class Mage_Admin_Model_User extends Mage_Core_Model_Abstract /** * Minimum length of admin password + * @deprecated Use getMinAdminPasswordLength() method instead */ - const MIN_PASSWORD_LENGTH = 7; + const MIN_PASSWORD_LENGTH = 14; + + /** + * Configuration path for minimum length of admin password + */ + const XML_PATH_MIN_ADMIN_PASSWORD_LENGTH = 'admin/security/min_admin_password_length'; /** * Length of salt */ const HASH_SALT_LENGTH = 32; + /** + * Empty hash salt + */ + const HASH_SALT_EMPTY = null; + /** * Model event prefix * @@ -459,7 +470,7 @@ class Mage_Admin_Model_User extends Mage_Core_Model_Abstract */ protected function _getEncodedPassword($password) { - return $this->_getHelper('core')->getHash($password, self::HASH_SALT_LENGTH); + return $this->_getHelper('core')->getHashPassword($password, self::HASH_SALT_LENGTH); } /** @@ -569,17 +580,23 @@ class Mage_Admin_Model_User extends Mage_Core_Model_Abstract } if ($this->hasNewPassword()) { - if (Mage::helper('core/string')->strlen($this->getNewPassword()) < self::MIN_PASSWORD_LENGTH) { - $errors[] = Mage::helper('adminhtml')->__('Password must be at least of %d characters.', self::MIN_PASSWORD_LENGTH); + $password = $this->getNewPassword(); + } elseif ($this->hasPassword()) { + $password = $this->getPassword(); + } + if (isset($password)) { + $minAdminPasswordLength = $this->getMinAdminPasswordLength(); + if (Mage::helper('core/string')->strlen($password) < $minAdminPasswordLength) { + $errors[] = Mage::helper('adminhtml') + ->__('Password must be at least of %d characters.', $minAdminPasswordLength); } - if (!preg_match('/[a-z]/iu', $this->getNewPassword()) - || !preg_match('/[0-9]/u', $this->getNewPassword()) - ) { - $errors[] = Mage::helper('adminhtml')->__('Password must include both numeric and alphabetic characters.'); + if (!preg_match('/[a-z]/iu', $password) || !preg_match('/[0-9]/u', $password)) { + $errors[] = Mage::helper('adminhtml') + ->__('Password must include both numeric and alphabetic characters.'); } - if ($this->hasPasswordConfirmation() && $this->getNewPassword() != $this->getPasswordConfirmation()) { + if ($this->hasPasswordConfirmation() && $password != $this->getPasswordConfirmation()) { $errors[] = Mage::helper('adminhtml')->__('Password confirmation must be same as password.'); } @@ -745,4 +762,16 @@ class Mage_Admin_Model_User extends Mage_Core_Model_Abstract $emails = str_replace(' ', '', Mage::getStoreConfig(self::XML_PATH_ADDITIONAL_EMAILS)); return explode(',', $emails); } + + /** + * Retrieve minimum length of admin password + * + * @return int + */ + public function getMinAdminPasswordLength() + { + $minLength = (int)Mage::getStoreConfig(self::XML_PATH_MIN_ADMIN_PASSWORD_LENGTH); + $absoluteMinLength = Mage_Core_Model_App::ABSOLUTE_MIN_PASSWORD_LENGTH; + return ($minLength < $absoluteMinLength) ? $absoluteMinLength : $minLength; + } } diff --git app/code/core/Mage/Admin/etc/config.xml app/code/core/Mage/Admin/etc/config.xml index 7681dc21ed6..a98a0f7dec7 100644 --- app/code/core/Mage/Admin/etc/config.xml +++ app/code/core/Mage/Admin/etc/config.xml @@ -28,7 +28,7 @@ - 1.6.1.2 + 1.6.1.3 diff --git app/code/core/Mage/Admin/sql/admin_setup/upgrade-1.6.1.2-1.6.1.3.php app/code/core/Mage/Admin/sql/admin_setup/upgrade-1.6.1.2-1.6.1.3.php new file mode 100644 index 00000000000..ca30d4aead3 --- /dev/null +++ app/code/core/Mage/Admin/sql/admin_setup/upgrade-1.6.1.2-1.6.1.3.php @@ -0,0 +1,43 @@ +startSetup(); + +//Increase password field length +$installer->getConnection()->changeColumn( + $installer->getTable('admin/user'), + 'password', + 'password', + array( + 'type' => Varien_Db_Ddl_Table::TYPE_TEXT, + 'length' => 255, + 'comment' => 'User Password', + ) +); + +$installer->endSetup(); diff --git app/code/core/Mage/Adminhtml/Block/Api/User/Edit/Tab/Main.php app/code/core/Mage/Adminhtml/Block/Api/User/Edit/Tab/Main.php index 01ffdab2f9b..0d53e05610e 100644 --- app/code/core/Mage/Adminhtml/Block/Api/User/Edit/Tab/Main.php +++ app/code/core/Mage/Adminhtml/Block/Api/User/Edit/Tab/Main.php @@ -96,13 +96,16 @@ class Mage_Adminhtml_Block_Api_User_Edit_Tab_Main extends Mage_Adminhtml_Block_W ) ); + $minPasswordLength = Mage::getModel('customer/customer')->getMinPasswordLength(); if ($model->getUserId()) { $fieldset->addField('password', 'password', array( 'name' => 'new_api_key', 'label' => Mage::helper('adminhtml')->__('New API Key'), 'id' => 'new_pass', 'title' => Mage::helper('adminhtml')->__('New API Key'), - 'class' => 'input-text validate-password', + 'class' => 'input-text validate-password min-pass-length-' . $minPasswordLength, + 'note' => Mage::helper('adminhtml') + ->__('API Key must be at least of %d characters.', $minPasswordLength), )); $fieldset->addField('confirmation', 'password', array( @@ -113,15 +116,17 @@ class Mage_Adminhtml_Block_Api_User_Edit_Tab_Main extends Mage_Adminhtml_Block_W )); } else { - $fieldset->addField('password', 'password', array( + $fieldset->addField('password', 'password', array( 'name' => 'api_key', 'label' => Mage::helper('adminhtml')->__('API Key'), 'id' => 'customer_pass', 'title' => Mage::helper('adminhtml')->__('API Key'), - 'class' => 'input-text required-entry validate-password', + 'class' => 'input-text required-entry validate-password min-pass-length-' . $minPasswordLength, 'required' => true, + 'note' => Mage::helper('adminhtml') + ->__('API Key must be at least of %d characters.', $minPasswordLength), )); - $fieldset->addField('confirmation', 'password', array( + $fieldset->addField('confirmation', 'password', array( 'name' => 'api_key_confirmation', 'label' => Mage::helper('adminhtml')->__('API Key Confirmation'), 'id' => 'confirmation', diff --git app/code/core/Mage/Adminhtml/Block/Catalog/Product/Attribute/Set/Main.php app/code/core/Mage/Adminhtml/Block/Catalog/Product/Attribute/Set/Main.php index b890a44d932..7718803ec9a 100644 --- app/code/core/Mage/Adminhtml/Block/Catalog/Product/Attribute/Set/Main.php +++ app/code/core/Mage/Adminhtml/Block/Catalog/Product/Attribute/Set/Main.php @@ -93,10 +93,13 @@ class Mage_Adminhtml_Block_Catalog_Product_Attribute_Set_Main extends Mage_Admin 'class' => 'save' ))); + $deleteConfirmMessage = $this->jsQuoteEscape(Mage::helper('catalog') + ->__('All products of this set will be deleted! Are you sure you want to delete this attribute set?')); + $deleteUrl = $this->getUrlSecure('*/*/delete', array('id' => $setId)); $this->setChild('delete_button', $this->getLayout()->createBlock('adminhtml/widget_button')->setData(array( 'label' => Mage::helper('catalog')->__('Delete Attribute Set'), - 'onclick' => 'deleteConfirm(\''. $this->jsQuoteEscape(Mage::helper('catalog')->__('All products of this set will be deleted! Are you sure you want to delete this attribute set?')) . '\', \'' . $this->getUrl('*/*/delete', array('id' => $setId)) . '\')', + 'onclick' => 'deleteConfirm(\'' . $deleteConfirmMessage . '\', \'' . $deleteUrl . '\')', 'class' => 'delete' ))); diff --git app/code/core/Mage/Adminhtml/Block/Customer/Edit/Renderer/Newpass.php app/code/core/Mage/Adminhtml/Block/Customer/Edit/Renderer/Newpass.php index 992a11965f8..c5f54d5d979 100644 --- app/code/core/Mage/Adminhtml/Block/Customer/Edit/Renderer/Newpass.php +++ app/code/core/Mage/Adminhtml/Block/Customer/Edit/Renderer/Newpass.php @@ -45,7 +45,11 @@ class Mage_Adminhtml_Block_Customer_Edit_Renderer_Newpass { $html = ''; $html .= '' . $element->getLabelHtml() . ''; - $html .= '' . $element->getElementHtml() . ''; + $html .= '' . $element->getElementHtml(); + if ($element->getNote()) { + $html .= '

' . $element->getNote() . '

'; + } + $html .= ''; $html .= '' . "\n"; $html .= ''; $html .= ''; diff --git app/code/core/Mage/Adminhtml/Block/Customer/Edit/Tab/Account.php app/code/core/Mage/Adminhtml/Block/Customer/Edit/Tab/Account.php index 9b937afe8a7..cb9d56f5d7a 100644 --- app/code/core/Mage/Adminhtml/Block/Customer/Edit/Tab/Account.php +++ app/code/core/Mage/Adminhtml/Block/Customer/Edit/Tab/Account.php @@ -163,6 +163,7 @@ class Mage_Adminhtml_Block_Customer_Edit_Tab_Account extends Mage_Adminhtml_Bloc } } + $minPasswordLength = Mage::getModel('customer/customer')->getMinPasswordLength(); if ($customer->getId()) { if (!$customer->isReadonly()) { // Add password management fieldset @@ -175,7 +176,9 @@ class Mage_Adminhtml_Block_Customer_Edit_Tab_Account extends Mage_Adminhtml_Bloc array( 'label' => Mage::helper('customer')->__('New Password'), 'name' => 'new_password', - 'class' => 'validate-new-password' + 'class' => 'validate-new-password min-pass-length-' . $minPasswordLength, + 'note' => Mage::helper('adminhtml') + ->__('Password must be at least of %d characters.', $minPasswordLength), ) ); $field->setRenderer($this->getLayout()->createBlock('adminhtml/customer_edit_renderer_newpass')); @@ -224,9 +227,11 @@ class Mage_Adminhtml_Block_Customer_Edit_Tab_Account extends Mage_Adminhtml_Bloc $field = $newFieldset->addField('password', 'text', array( 'label' => Mage::helper('customer')->__('Password'), - 'class' => 'input-text required-entry validate-password', + 'class' => 'input-text required-entry validate-password min-pass-length-' . $minPasswordLength, 'name' => 'password', - 'required' => true + 'required' => true, + 'note' => Mage::helper('adminhtml') + ->__('Password must be at least of %d characters.', $minPasswordLength), ) ); $field->setRenderer($this->getLayout()->createBlock('adminhtml/customer_edit_renderer_newpass')); diff --git app/code/core/Mage/Adminhtml/Block/Newsletter/Queue/Preview.php app/code/core/Mage/Adminhtml/Block/Newsletter/Queue/Preview.php index 897640a604e..9e3181a8a2a 100644 --- app/code/core/Mage/Adminhtml/Block/Newsletter/Queue/Preview.php +++ app/code/core/Mage/Adminhtml/Block/Newsletter/Queue/Preview.php @@ -75,6 +75,9 @@ class Mage_Adminhtml_Block_Newsletter_Queue_Preview extends Mage_Adminhtml_Block $templateProcessed = "
" . htmlspecialchars($templateProcessed) . "
"; } + $templateProcessed = Mage::getSingleton('core/input_filter_maliciousCode') + ->linkFilter($templateProcessed); + Varien_Profiler::stop("newsletter_queue_proccessing"); return $templateProcessed; diff --git app/code/core/Mage/Adminhtml/Block/Newsletter/Template/Edit.php app/code/core/Mage/Adminhtml/Block/Newsletter/Template/Edit.php index 841d0e2bb3f..16bddd65f40 100644 --- app/code/core/Mage/Adminhtml/Block/Newsletter/Template/Edit.php +++ app/code/core/Mage/Adminhtml/Block/Newsletter/Template/Edit.php @@ -315,7 +315,7 @@ class Mage_Adminhtml_Block_Newsletter_Template_Edit extends Mage_Adminhtml_Block */ public function getDeleteUrl() { - return $this->getUrl('*/*/delete', array('id' => $this->getRequest()->getParam('id'))); + return $this->getUrlSecure('*/*/delete', array('id' => $this->getRequest()->getParam('id'))); } /** diff --git app/code/core/Mage/Adminhtml/Block/Newsletter/Template/Preview.php app/code/core/Mage/Adminhtml/Block/Newsletter/Template/Preview.php index 9b5b591da89..170a5dfe78c 100644 --- app/code/core/Mage/Adminhtml/Block/Newsletter/Template/Preview.php +++ app/code/core/Mage/Adminhtml/Block/Newsletter/Template/Preview.php @@ -74,6 +74,9 @@ class Mage_Adminhtml_Block_Newsletter_Template_Preview extends Mage_Adminhtml_Bl $templateProcessed = "
" . htmlspecialchars($templateProcessed) . "
"; } + $templateProcessed = Mage::getSingleton('core/input_filter_maliciousCode') + ->linkFilter($templateProcessed); + Varien_Profiler::stop("newsletter_template_proccessing"); return $templateProcessed; diff --git app/code/core/Mage/Adminhtml/Block/Permissions/Tab/Useredit.php app/code/core/Mage/Adminhtml/Block/Permissions/Tab/Useredit.php index cf94dcd7ecd..28247fe481a 100644 --- app/code/core/Mage/Adminhtml/Block/Permissions/Tab/Useredit.php +++ app/code/core/Mage/Adminhtml/Block/Permissions/Tab/Useredit.php @@ -85,6 +85,7 @@ class Mage_Adminhtml_Block_Permissions_Tab_Useredit extends Mage_Adminhtml_Block ) ); + $minPasswordLength = Mage::getModel('customer/customer')->getMinPasswordLength(); if ($user->getUserId()) { $fieldset->addField('password', 'password', array( @@ -92,7 +93,9 @@ class Mage_Adminhtml_Block_Permissions_Tab_Useredit extends Mage_Adminhtml_Block 'label' => Mage::helper('adminhtml')->__('New Password'), 'id' => 'new_pass', 'title' => Mage::helper('adminhtml')->__('New Password'), - 'class' => 'input-text validate-password', + 'class' => 'input-text validate-password min-pass-length-' . $minPasswordLength, + 'note' => Mage::helper('adminhtml') + ->__('Password must be at least of %d characters.', $minPasswordLength), ) ); @@ -112,8 +115,10 @@ class Mage_Adminhtml_Block_Permissions_Tab_Useredit extends Mage_Adminhtml_Block 'label' => Mage::helper('adminhtml')->__('Password'), 'id' => 'customer_pass', 'title' => Mage::helper('adminhtml')->__('Password'), - 'class' => 'input-text required-entry validate-password', + 'class' => 'input-text required-entry validate-password min-pass-length-' . $minPasswordLength, 'required' => true, + 'note' => Mage::helper('adminhtml') + ->__('Password must be at least of %d characters.', $minPasswordLength), ) ); $fieldset->addField('confirmation', 'password', diff --git app/code/core/Mage/Adminhtml/Block/Permissions/User/Edit/Tab/Main.php app/code/core/Mage/Adminhtml/Block/Permissions/User/Edit/Tab/Main.php index 2f80c3047ee..a1633da7fb3 100644 --- app/code/core/Mage/Adminhtml/Block/Permissions/User/Edit/Tab/Main.php +++ app/code/core/Mage/Adminhtml/Block/Permissions/User/Edit/Tab/Main.php @@ -97,13 +97,16 @@ class Mage_Adminhtml_Block_Permissions_User_Edit_Tab_Main extends Mage_Adminhtml 'required' => true, )); + $minAdminPasswordLength = Mage::getModel('admin/user')->getMinAdminPasswordLength(); if ($model->getUserId()) { $fieldset->addField('password', 'password', array( 'name' => 'new_password', 'label' => Mage::helper('adminhtml')->__('New Password'), 'id' => 'new_pass', 'title' => Mage::helper('adminhtml')->__('New Password'), - 'class' => 'input-text validate-admin-password', + 'class' => 'input-text validate-admin-password min-admin-pass-length-' . $minAdminPasswordLength, + 'note' => Mage::helper('adminhtml') + ->__('Password must be at least of %d characters.', $minAdminPasswordLength), )); $fieldset->addField('confirmation', 'password', array( @@ -114,15 +117,18 @@ class Mage_Adminhtml_Block_Permissions_User_Edit_Tab_Main extends Mage_Adminhtml )); } else { - $fieldset->addField('password', 'password', array( + $fieldset->addField('password', 'password', array( 'name' => 'password', 'label' => Mage::helper('adminhtml')->__('Password'), 'id' => 'customer_pass', 'title' => Mage::helper('adminhtml')->__('Password'), - 'class' => 'input-text required-entry validate-admin-password', + 'class' => 'input-text required-entry validate-admin-password min-admin-pass-length-' + . $minAdminPasswordLength, 'required' => true, + 'note' => Mage::helper('adminhtml') + ->__('Password must be at least of %d characters.', $minAdminPasswordLength), )); - $fieldset->addField('confirmation', 'password', array( + $fieldset->addField('confirmation', 'password', array( 'name' => 'password_confirmation', 'label' => Mage::helper('adminhtml')->__('Password Confirmation'), 'id' => 'confirmation', diff --git app/code/core/Mage/Adminhtml/Block/Sales/Order/View.php app/code/core/Mage/Adminhtml/Block/Sales/Order/View.php index 85e97923758..288c46542c7 100644 --- app/code/core/Mage/Adminhtml/Block/Sales/Order/View.php +++ app/code/core/Mage/Adminhtml/Block/Sales/Order/View.php @@ -246,7 +246,7 @@ class Mage_Adminhtml_Block_Sales_Order_View extends Mage_Adminhtml_Block_Widget_ public function getCancelUrl() { - return $this->getUrl('*/*/cancel'); + return $this->getUrlSecure('*/*/cancel'); } public function getInvoiceUrl() diff --git app/code/core/Mage/Adminhtml/Block/System/Account/Edit/Form.php app/code/core/Mage/Adminhtml/Block/System/Account/Edit/Form.php index 36866a08dfa..6380d6e87f3 100644 --- app/code/core/Mage/Adminhtml/Block/System/Account/Edit/Form.php +++ app/code/core/Mage/Adminhtml/Block/System/Account/Edit/Form.php @@ -90,11 +90,14 @@ class Mage_Adminhtml_Block_System_Account_Edit_Form extends Mage_Adminhtml_Block ) ); + $minAdminPasswordLength = Mage::getModel('admin/user')->getMinAdminPasswordLength(); $fieldset->addField('password', 'password', array( 'name' => 'new_password', 'label' => Mage::helper('adminhtml')->__('New Password'), 'title' => Mage::helper('adminhtml')->__('New Password'), - 'class' => 'input-text validate-admin-password', + 'class' => 'input-text validate-admin-password min-admin-pass-length-' . $minAdminPasswordLength, + 'note' => Mage::helper('adminhtml') + ->__('Password must be at least of %d characters.', $minAdminPasswordLength), ) ); diff --git app/code/core/Mage/Adminhtml/Block/System/Email/Template/Edit.php app/code/core/Mage/Adminhtml/Block/System/Email/Template/Edit.php index 34fc4302529..fc878d35aad 100644 --- app/code/core/Mage/Adminhtml/Block/System/Email/Template/Edit.php +++ app/code/core/Mage/Adminhtml/Block/System/Email/Template/Edit.php @@ -267,7 +267,7 @@ class Mage_Adminhtml_Block_System_Email_Template_Edit extends Mage_Adminhtml_Blo */ public function getDeleteUrl() { - return $this->getUrl('*/*/delete', array('_current' => true)); + return $this->getUrlSecure('*/*/delete', array('_current' => true)); } /** diff --git app/code/core/Mage/Adminhtml/Block/Widget/Grid.php app/code/core/Mage/Adminhtml/Block/Widget/Grid.php index 09c35fd0ecc..0ed1bc0bd68 100644 --- app/code/core/Mage/Adminhtml/Block/Widget/Grid.php +++ app/code/core/Mage/Adminhtml/Block/Widget/Grid.php @@ -464,7 +464,7 @@ class Mage_Adminhtml_Block_Widget_Grid extends Mage_Adminhtml_Block_Widget { if ($this->getCollection()) { $field = ( $column->getFilterIndex() ) ? $column->getFilterIndex() : $column->getIndex(); - if ($column->getFilterConditionCallback()) { + if ($column->getFilterConditionCallback() && $column->getFilterConditionCallback()[0] instanceof self) { call_user_func($column->getFilterConditionCallback(), $this->getCollection(), $column); } else { $cond = $column->getFilter()->getCondition(); diff --git app/code/core/Mage/Adminhtml/Model/Config/Data.php app/code/core/Mage/Adminhtml/Model/Config/Data.php index dbbe27a17a7..191447f3d5c 100644 --- app/code/core/Mage/Adminhtml/Model/Config/Data.php +++ app/code/core/Mage/Adminhtml/Model/Config/Data.php @@ -34,6 +34,10 @@ class Mage_Adminhtml_Model_Config_Data extends Varien_Object { + const SCOPE_DEFAULT = 'default'; + const SCOPE_WEBSITES = 'websites'; + const SCOPE_STORES = 'stores'; + /** * Config data for sections * @@ -268,15 +272,15 @@ class Mage_Adminhtml_Model_Config_Data extends Varien_Object protected function _getScope() { if ($this->getStore()) { - $scope = 'stores'; + $scope = self::SCOPE_STORES; $scopeId = (int)Mage::getConfig()->getNode('stores/' . $this->getStore() . '/system/store/id'); $scopeCode = $this->getStore(); } elseif ($this->getWebsite()) { - $scope = 'websites'; + $scope = self::SCOPE_WEBSITES; $scopeId = (int)Mage::getConfig()->getNode('websites/' . $this->getWebsite() . '/system/website/id'); $scopeCode = $this->getWebsite(); } else { - $scope = 'default'; + $scope = self::SCOPE_DEFAULT; $scopeId = 0; $scopeCode = ''; } @@ -363,4 +367,100 @@ class Mage_Adminhtml_Model_Config_Data extends Varien_Object } return $this->_configRoot; } + + /** + * Secure set groups + * + * @param array $groups + * @return Mage_Adminhtml_Model_Config_Data + * @throws Mage_Core_Exception + */ + public function setGroupsSecure($groups) + { + $this->_validate(); + $this->_getScope(); + + $groupsSecure = array(); + $section = $this->getSection(); + $sections = Mage::getModel('adminhtml/config')->getSections(); + + foreach ($groups as $group => $groupData) { + $groupConfig = $sections->descend($section . '/groups/' . $group); + foreach ($groupData['fields'] as $field => $fieldData) { + $fieldName = $field; + if ($groupConfig && $groupConfig->clone_fields) { + if ($groupConfig->clone_model) { + $cloneModel = Mage::getModel((string)$groupConfig->clone_model); + } else { + Mage::throwException( + $this->__('Config form fieldset clone model required to be able to clone fields') + ); + } + foreach ($cloneModel->getPrefixes() as $prefix) { + if (strpos($field, $prefix['field']) === 0) { + $field = substr($field, strlen($prefix['field'])); + } + } + } + $fieldConfig = $sections->descend($section . '/groups/' . $group . '/fields/' . $field); + if (!$fieldConfig) { + $node = $sections->xpath($section . '//' . $group . '[@type="group"]/fields/' . $field); + if ($node) { + $fieldConfig = $node[0]; + } + } + if (($groupConfig ? !$groupConfig->dynamic_group : true) && !$this->_isValidField($fieldConfig)) { + Mage::throwException(Mage::helper('adminhtml')->__('Wrong field specified.')); + } + $groupsSecure[$group]['fields'][$fieldName] = $fieldData; + } + } + + $this->setGroups($groupsSecure); + + return $this; + } + + /** + * Check field visibility by scope + * + * @param Mage_Core_Model_Config_Element $field + * @return bool + */ + protected function _isValidField($field) + { + if (!$field) { + return false; + } + + switch ($this->getScope()) { + case self::SCOPE_DEFAULT: + return (bool)(int)$field->show_in_default; + break; + case self::SCOPE_WEBSITES: + return (bool)(int)$field->show_in_website; + break; + case self::SCOPE_STORES: + return (bool)(int)$field->show_in_store; + break; + } + + return true; + } + + /** + * Select group setter is secure or not based on the configuration + * + * @param array $groups + * @return Mage_Adminhtml_Model_Config_Data + * @throws Mage_Core_Exception + */ + public function setGroupsSelector($groups) + { + if (Mage::getStoreConfigFlag('admin/security/secure_system_configuration_save_disabled')) { + return $this->setGroups($groups); + } + + return $this->setGroupsSecure($groups); + } } diff --git app/code/core/Mage/Adminhtml/Model/LayoutUpdate/Validator.php app/code/core/Mage/Adminhtml/Model/LayoutUpdate/Validator.php index 77d3c41765d..7daed0148c2 100644 --- app/code/core/Mage/Adminhtml/Model/LayoutUpdate/Validator.php +++ app/code/core/Mage/Adminhtml/Model/LayoutUpdate/Validator.php @@ -53,33 +53,26 @@ class Mage_Adminhtml_Model_LayoutUpdate_Validator extends Zend_Validate_Abstract * * @var array */ - protected $_disallowedXPathExpressions = array( - '*//template', - '*//@template', - '//*[@method=\'setTemplate\']', - '//*[@method=\'setDataUsingMethod\']//*[contains(translate(text(), - \'ABCDEFGHIJKLMNOPQRSTUVWXYZ\', \'abcdefghijklmnopqrstuvwxyz\'), \'template\')]/../*', - ); + protected $_disallowedXPathExpressions = array(); /** * Disallowed template name * * @var array */ - protected $_disallowedBlock = array( - 'Mage_Install_Block_End', - 'Mage_Rss_Block_Order_New', - 'Mage_Core_Block_Template_Zend', - ); + protected $_disallowedBlock = array(); + + /** + * @var Mage_Core_Model_Layout_Validator + */ + protected $_validator; /** * Protected expressions * * @var array */ - protected $_protectedExpressions = array( - self::PROTECTED_ATTR_HELPER_IN_TAG_ACTION_VAR => '//action/*[@helper]', - ); + protected $_protectedExpressions = array(); /** * Construct @@ -87,27 +80,17 @@ class Mage_Adminhtml_Model_LayoutUpdate_Validator extends Zend_Validate_Abstract public function __construct() { $this->_initMessageTemplates(); + $this->_initValidator(); } /** - * Initialize messages templates with translating + * Returns array of validation failure messages * - * @return Mage_Adminhtml_Model_LayoutUpdate_Validator + * @return array */ - protected function _initMessageTemplates() + public function getMessages() { - if (!$this->_messageTemplates) { - $this->_messageTemplates = array( - self::PROTECTED_ATTR_HELPER_IN_TAG_ACTION_VAR => - Mage::helper('adminhtml')->__('Helper attributes should not be used in custom layout updates.'), - self::XML_INVALID => Mage::helper('adminhtml')->__('XML data is invalid.'), - self::INVALID_TEMPLATE_PATH => Mage::helper('adminhtml')->__( - 'Invalid template path used in layout update.' - ), - self::INVALID_BLOCK_NAME => Mage::helper('adminhtml')->__('Disallowed block name for frontend.'), - ); - } - return $this; + return $this->_validator->getMessages(); } /** @@ -124,43 +107,42 @@ class Mage_Adminhtml_Model_LayoutUpdate_Validator extends Zend_Validate_Abstract */ public function isValid($value) { - if (is_string($value)) { - $value = trim($value); - try { - //wrap XML value in the "config" tag because config cannot - //contain multiple root tags - $value = new Varien_Simplexml_Element('' . $value . ''); - } catch (Exception $e) { - $this->_error(self::XML_INVALID); - return false; - } - } elseif (!($value instanceof Varien_Simplexml_Element)) { - throw new Exception( - Mage::helper('adminhtml')->__('XML object is not instance of "Varien_Simplexml_Element".')); - } + return $this->_validator->isValid($value); + } - if ($value->xpath($this->_getXpathBlockValidationExpression())) { - $this->_error(self::INVALID_BLOCK_NAME); - return false; - } - // if layout update declare custom templates then validate their paths - if ($templatePaths = $value->xpath($this->_getXpathValidationExpression())) { - try { - $this->_validateTemplatePath($templatePaths); - } catch (Exception $e) { - $this->_error(self::INVALID_TEMPLATE_PATH); - return false; - } - } - $this->_setValue($value); + /** + * Initialize the validator instance with populated template messages + */ + protected function _initValidator() + { + $this->_validator = Mage::getModel('core/layout_validator'); + $this->_disallowedBlock = $this->_validator->getDisallowedBlocks(); + $this->_protectedExpressions = $this->_validator->getProtectedExpressions(); + $this->_disallowedXPathExpressions = $this->_validator->getDisallowedXpathValidationExpression(); + $this->_validator->setMessages($this->_messageTemplates); + } - foreach ($this->_protectedExpressions as $key => $xpr) { - if ($this->_value->xpath($xpr)) { - $this->_error($key); - return false; - } + /** + * Initialize messages templates with translating + * + * @return Mage_Adminhtml_Model_LayoutUpdate_Validator + */ + protected function _initMessageTemplates() + { + if (!$this->_messageTemplates) { + $this->_messageTemplates = array( + self::PROTECTED_ATTR_HELPER_IN_TAG_ACTION_VAR => + Mage::helper('adminhtml')->__('Helper attributes should not be used in custom layout updates.'), + self::XML_INVALID => Mage::helper('adminhtml')->__('XML data is invalid.'), + self::INVALID_TEMPLATE_PATH => Mage::helper('adminhtml')->__( + 'Invalid template path used in layout update.' + ), + self::INVALID_BLOCK_NAME => Mage::helper('adminhtml')->__('Disallowed block name for frontend.'), + Mage_Core_Model_Layout_Validator::INVALID_XML_OBJECT_EXCEPTION => + Mage::helper('adminhtml')->__('XML object is not instance of "Varien_Simplexml_Element".'), + ); } - return true; + return $this; } /** @@ -168,8 +150,9 @@ class Mage_Adminhtml_Model_LayoutUpdate_Validator extends Zend_Validate_Abstract * * @return string xPath for validate incorrect path to template */ - protected function _getXpathValidationExpression() { - return implode(" | ", $this->_disallowedXPathExpressions); + protected function _getXpathValidationExpression() + { + return $this->_validator->getXpathValidationExpression(); } /** @@ -177,16 +160,9 @@ class Mage_Adminhtml_Model_LayoutUpdate_Validator extends Zend_Validate_Abstract * * @return string xPath for validate incorrect block name */ - protected function _getXpathBlockValidationExpression() { - $xpath = ""; - if (count($this->_disallowedBlock)) { - foreach ($this->_disallowedBlock as $key => $value) { - $xpath .= $key > 0 ? " | " : ''; - $xpath .= "//block[translate(@type, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz') = "; - $xpath .= "translate('$value', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')]"; - } - } - return $xpath; + protected function _getXpathBlockValidationExpression() + { + return $this->_validator->getXpathBlockValidationExpression(); } /** @@ -197,14 +173,6 @@ class Mage_Adminhtml_Model_LayoutUpdate_Validator extends Zend_Validate_Abstract */ protected function _validateTemplatePath(array $templatePaths) { - /**@var $path Varien_Simplexml_Element */ - foreach ($templatePaths as $path) { - if ($path->hasChildren()) { - $path = stripcslashes(trim((string) $path->children(), '"')); - } - if (strpos($path, '..' . DS) !== false) { - throw new Exception(); - } - } + $this->_validator->validateTemplatePath($templatePaths); } } diff --git app/code/core/Mage/Adminhtml/Model/System/Config/Backend/Locale.php app/code/core/Mage/Adminhtml/Model/System/Config/Backend/Locale.php index 0fa4771c562..b19becc2767 100644 --- app/code/core/Mage/Adminhtml/Model/System/Config/Backend/Locale.php +++ app/code/core/Mage/Adminhtml/Model/System/Config/Backend/Locale.php @@ -45,6 +45,39 @@ class Mage_Adminhtml_Model_System_Config_Backend_Locale extends Mage_Core_Model_ $allCurrenciesOptions = Mage::getSingleton('adminhtml/system_config_source_locale_currency_all') ->toOptionArray(true); + if (!function_exists('array_column')) { + function array_column(array $allCurrenciesOptions, $columnKey, $indexKey = null) + { + $array = array(); + foreach ($allCurrenciesOptions as $allCurrenciesOption) { + if (!array_key_exists($columnKey, $allCurrenciesOption)) { + Mage::getSingleton('adminhtml/session')->addError( + Mage::helper('adminhtml')->__("Key %s does not exist in array", $columnKey) + ); + return false; + } + if (is_null($indexKey)) { + $array[] = $allCurrenciesOption[$columnKey]; + } else { + if (!array_key_exists($indexKey, $allCurrenciesOption)) { + Mage::getSingleton('adminhtml/session')->addError( + Mage::helper('adminhtml')->__("Key %s does not exist in array", $indexKey) + ); + return false; + } + if (!is_scalar($allCurrenciesOption[$indexKey])) { + Mage::getSingleton('adminhtml/session')->addError( + Mage::helper('adminhtml')->__("Key %s does not contain scalar value", $indexKey) + ); + return false; + } + $array[$allCurrenciesOption[$indexKey]] = $allCurrenciesOption[$columnKey]; + } + } + return $array; + } + } + $allCurrenciesValues = array_column($allCurrenciesOptions, 'value'); foreach ($this->getValue() as $currency) { diff --git app/code/core/Mage/Adminhtml/Model/System/Config/Backend/Passwordlength.php app/code/core/Mage/Adminhtml/Model/System/Config/Backend/Passwordlength.php new file mode 100644 index 00000000000..9a723b9d252 --- /dev/null +++ app/code/core/Mage/Adminhtml/Model/System/Config/Backend/Passwordlength.php @@ -0,0 +1,50 @@ + + */ +class Mage_Adminhtml_Model_System_Config_Backend_Passwordlength extends Mage_Core_Model_Config_Data +{ + /** + * Before save processing + * + * @throws Mage_Core_Exception + * @return Mage_Adminhtml_Model_System_Config_Backend_Passwordlength + */ + protected function _beforeSave() + { + if ((int)$this->getValue() < Mage_Core_Model_App::ABSOLUTE_MIN_PASSWORD_LENGTH) { + Mage::throwException(Mage::helper('adminhtml') + ->__('Password must be at least of %d characters.', Mage_Core_Model_App::ABSOLUTE_MIN_PASSWORD_LENGTH)); + } + return $this; + } +} diff --git app/code/core/Mage/Adminhtml/controllers/Api/UserController.php app/code/core/Mage/Adminhtml/controllers/Api/UserController.php index 962b8ff67c9..7cf2cbce69a 100644 --- app/code/core/Mage/Adminhtml/controllers/Api/UserController.php +++ app/code/core/Mage/Adminhtml/controllers/Api/UserController.php @@ -123,6 +123,19 @@ class Mage_Adminhtml_Api_UserController extends Mage_Adminhtml_Controller_Action $this->getRequest()->setParam('current_password', null); unset($data['current_password']); $result = $this->_validateCurrentPassword($currentPassword); + $model->setData($data); + + if ($model->hasNewApiKey() && $model->getNewApiKey() === '') { + $model->unsNewApiKey(); + } + + if ($model->hasApiKeyConfirmation() && $model->getApiKeyConfirmation() === '') { + $model->unsApiKeyConfirmation(); + } + + if (!is_array($result)) { + $result = $model->validate(); + } if (is_array($result)) { foreach ($result as $error) { @@ -138,7 +151,6 @@ class Mage_Adminhtml_Api_UserController extends Mage_Adminhtml_Controller_Action return; } - $model->setData($data); try { $model->save(); if ( $uRoles = $this->getRequest()->getParam('roles', false) ) { diff --git app/code/core/Mage/Adminhtml/controllers/Catalog/CategoryController.php app/code/core/Mage/Adminhtml/controllers/Catalog/CategoryController.php index 77a4e9bc440..15d63e389ee 100644 --- app/code/core/Mage/Adminhtml/controllers/Catalog/CategoryController.php +++ app/code/core/Mage/Adminhtml/controllers/Catalog/CategoryController.php @@ -509,4 +509,15 @@ class Mage_Adminhtml_Catalog_CategoryController extends Mage_Adminhtml_Controlle { return Mage::getSingleton('admin/session')->isAllowed('catalog/categories'); } + + /** + * Controller predispatch method + * + * @return Mage_Adminhtml_Controller_Action + */ + public function preDispatch() + { + $this->_setForcedFormKeyActions('delete'); + return parent::preDispatch(); + } } diff --git app/code/core/Mage/Adminhtml/controllers/Catalog/Product/AttributeController.php app/code/core/Mage/Adminhtml/controllers/Catalog/Product/AttributeController.php index ccbf26cd08e..0e51c947964 100644 --- app/code/core/Mage/Adminhtml/controllers/Catalog/Product/AttributeController.php +++ app/code/core/Mage/Adminhtml/controllers/Catalog/Product/AttributeController.php @@ -253,6 +253,7 @@ class Mage_Adminhtml_Catalog_Product_AttributeController extends Mage_Adminhtml_ return; } + $data['backend_model'] = $model->getBackendModel(); $data['attribute_code'] = $model->getAttributeCode(); $data['is_user_defined'] = $model->getIsUserDefined(); $data['frontend_input'] = $model->getFrontendInput(); @@ -342,7 +343,7 @@ class Mage_Adminhtml_Catalog_Product_AttributeController extends Mage_Adminhtml_ // entity type check $model->load($id); - if ($model->getEntityTypeId() != $this->_entityTypeId) { + if ($model->getEntityTypeId() != $this->_entityTypeId || !$model->getIsUserDefined()) { Mage::getSingleton('adminhtml/session')->addError( Mage::helper('catalog')->__('This attribute cannot be deleted.')); $this->_redirect('*/*/'); diff --git app/code/core/Mage/Adminhtml/controllers/Catalog/Product/SetController.php app/code/core/Mage/Adminhtml/controllers/Catalog/Product/SetController.php index dc6735a63ff..9dd47944097 100644 --- app/code/core/Mage/Adminhtml/controllers/Catalog/Product/SetController.php +++ app/code/core/Mage/Adminhtml/controllers/Catalog/Product/SetController.php @@ -208,6 +208,17 @@ class Mage_Adminhtml_Catalog_Product_SetController extends Mage_Adminhtml_Contro } } + /** + * Controller predispatch method + * + * @return Mage_Adminhtml_Controller_Action + */ + public function preDispatch() + { + $this->_setForcedFormKeyActions('delete'); + return parent::preDispatch(); + } + /** * Define in register catalog_product entity type code as entityType * diff --git app/code/core/Mage/Adminhtml/controllers/Catalog/SearchController.php app/code/core/Mage/Adminhtml/controllers/Catalog/SearchController.php index 079adc71689..1ef4a1ff5ae 100644 --- app/code/core/Mage/Adminhtml/controllers/Catalog/SearchController.php +++ app/code/core/Mage/Adminhtml/controllers/Catalog/SearchController.php @@ -188,6 +188,17 @@ class Mage_Adminhtml_Catalog_SearchController extends Mage_Adminhtml_Controller_ $this->_redirect('*/*/index'); } + /** + * Controller predispatch method + * + * @return Mage_Adminhtml_Controller_Action + */ + public function preDispatch() + { + $this->_setForcedFormKeyActions('delete', 'massDelete'); + return parent::preDispatch(); + } + protected function _isAllowed() { return Mage::getSingleton('admin/session')->isAllowed('catalog/search'); diff --git app/code/core/Mage/Adminhtml/controllers/Cms/PageController.php app/code/core/Mage/Adminhtml/controllers/Cms/PageController.php index e3ae70abcdc..74e69348cb3 100644 --- app/code/core/Mage/Adminhtml/controllers/Cms/PageController.php +++ app/code/core/Mage/Adminhtml/controllers/Cms/PageController.php @@ -215,6 +215,17 @@ class Mage_Adminhtml_Cms_PageController extends Mage_Adminhtml_Controller_Action $this->_redirect('*/*/'); } + /** + * Controller predispatch method + * + * @return Mage_Adminhtml_Controller_Action + */ + public function preDispatch() + { + $this->_setForcedFormKeyActions('delete'); + return parent::preDispatch(); + } + /** * Check the permission to run it * diff --git app/code/core/Mage/Adminhtml/controllers/CustomerController.php app/code/core/Mage/Adminhtml/controllers/CustomerController.php index e1e6a5a0c35..15b7e9f9d7c 100644 --- app/code/core/Mage/Adminhtml/controllers/CustomerController.php +++ app/code/core/Mage/Adminhtml/controllers/CustomerController.php @@ -360,9 +360,15 @@ class Mage_Adminhtml_CustomerController extends Mage_Adminhtml_Controller_Action } if (!empty($data['account']['new_password'])) { - $newPassword = $data['account']['new_password']; + $newPassword = trim($data['account']['new_password']); if ($newPassword == 'auto') { $newPassword = $customer->generatePassword(); + } else { + $minPasswordLength = Mage::getModel('customer/customer')->getMinPasswordLength(); + if (Mage::helper('core/string')->strlen($newPassword) < $minPasswordLength) { + Mage::throwException(Mage::helper('customer') + ->__('The minimum password length is %s', $minPasswordLength)); + } } $customer->changePassword($newPassword); $customer->sendPasswordReminderEmail(); diff --git app/code/core/Mage/Adminhtml/controllers/IndexController.php app/code/core/Mage/Adminhtml/controllers/IndexController.php index 841c59c367e..5af88e482b8 100644 --- app/code/core/Mage/Adminhtml/controllers/IndexController.php +++ app/code/core/Mage/Adminhtml/controllers/IndexController.php @@ -287,7 +287,8 @@ class Mage_Adminhtml_IndexController extends Mage_Adminhtml_Controller_Action $this->_validateResetPasswordLinkToken($userId, $resetPasswordLinkToken); $data = array( 'userId' => $userId, - 'resetPasswordLinkToken' => $resetPasswordLinkToken + 'resetPasswordLinkToken' => $resetPasswordLinkToken, + 'minAdminPasswordLength' => $this->_getModel('admin/user')->getMinAdminPasswordLength() ); $this->_outTemplate('resetforgottenpassword', $data); } catch (Exception $exception) { @@ -342,7 +343,8 @@ class Mage_Adminhtml_IndexController extends Mage_Adminhtml_Controller_Action } $data = array( 'userId' => $userId, - 'resetPasswordLinkToken' => $resetPasswordLinkToken + 'resetPasswordLinkToken' => $resetPasswordLinkToken, + 'minAdminPasswordLength' => $this->_getModel('admin/user')->getMinAdminPasswordLength() ); $this->_outTemplate('resetforgottenpassword', $data); return; @@ -359,7 +361,8 @@ class Mage_Adminhtml_IndexController extends Mage_Adminhtml_Controller_Action $this->_getSession()->addError($exception->getMessage()); $data = array( 'userId' => $userId, - 'resetPasswordLinkToken' => $resetPasswordLinkToken + 'resetPasswordLinkToken' => $resetPasswordLinkToken, + 'minAdminPasswordLength' => $this->_getModel('admin/user')->getMinAdminPasswordLength() ); $this->_outTemplate('resetforgottenpassword', $data); return; diff --git app/code/core/Mage/Adminhtml/controllers/Newsletter/TemplateController.php app/code/core/Mage/Adminhtml/controllers/Newsletter/TemplateController.php index 7b99586ad98..2d759da55c9 100644 --- app/code/core/Mage/Adminhtml/controllers/Newsletter/TemplateController.php +++ app/code/core/Mage/Adminhtml/controllers/Newsletter/TemplateController.php @@ -249,4 +249,15 @@ class Mage_Adminhtml_Newsletter_TemplateController extends Mage_Adminhtml_Contro $this->getLayout()->getBlock('preview_form')->setFormData($data); $this->renderLayout(); } + + /** + * Controller predispatch method + * + * @return Mage_Adminhtml_Controller_Action + */ + public function preDispatch() + { + $this->_setForcedFormKeyActions('delete'); + return parent::preDispatch(); + } } diff --git app/code/core/Mage/Adminhtml/controllers/Permissions/BlockController.php app/code/core/Mage/Adminhtml/controllers/Permissions/BlockController.php index 86a8b39f48c..21d8d530a38 100644 --- app/code/core/Mage/Adminhtml/controllers/Permissions/BlockController.php +++ app/code/core/Mage/Adminhtml/controllers/Permissions/BlockController.php @@ -204,6 +204,17 @@ class Mage_Adminhtml_Permissions_BlockController extends Mage_Adminhtml_Controll ); } + /** + * Controller predispatch method + * + * @return Mage_Adminhtml_Controller_Action + */ + public function preDispatch() + { + $this->_setForcedFormKeyActions('delete'); + return parent::preDispatch(); + } + /** * Check permissions before allow edit list of blocks * diff --git app/code/core/Mage/Adminhtml/controllers/Sales/OrderController.php app/code/core/Mage/Adminhtml/controllers/Sales/OrderController.php index 6a5e4263db1..51939bdb175 100644 --- app/code/core/Mage/Adminhtml/controllers/Sales/OrderController.php +++ app/code/core/Mage/Adminhtml/controllers/Sales/OrderController.php @@ -778,4 +778,15 @@ class Mage_Adminhtml_Sales_OrderController extends Mage_Adminhtml_Controller_Act $this->_redirect('*/*/'); } } + + /** + * Controller predispatch method + * + * @return Mage_Adminhtml_Controller_Action + */ + public function preDispatch() + { + $this->_setForcedFormKeyActions('cancel', 'massCancel'); + return parent::preDispatch(); + } } diff --git app/code/core/Mage/Adminhtml/controllers/System/ConfigController.php app/code/core/Mage/Adminhtml/controllers/System/ConfigController.php index 096eff2c480..5da036ab8ab 100644 --- app/code/core/Mage/Adminhtml/controllers/System/ConfigController.php +++ app/code/core/Mage/Adminhtml/controllers/System/ConfigController.php @@ -161,7 +161,7 @@ class Mage_Adminhtml_System_ConfigController extends Mage_Adminhtml_Controller_A ->setSection($section) ->setWebsite($website) ->setStore($store) - ->setGroups($groups) + ->setGroupsSelector($groups) ->save(); // reinit configuration diff --git app/code/core/Mage/Adminhtml/controllers/System/Email/TemplateController.php app/code/core/Mage/Adminhtml/controllers/System/Email/TemplateController.php index 1c51cc5c2c9..ba5cd4d9109 100644 --- app/code/core/Mage/Adminhtml/controllers/System/Email/TemplateController.php +++ app/code/core/Mage/Adminhtml/controllers/System/Email/TemplateController.php @@ -129,7 +129,7 @@ class Mage_Adminhtml_System_Email_TemplateController extends Mage_Adminhtml_Cont } try { - $allowedHtmlTags = ['template_text', 'styles']; + $allowedHtmlTags = ['template_text', 'styles', 'variables']; if (Mage::helper('adminhtml')->hasTags($request->getParams(), $allowedHtmlTags)) { Mage::throwException(Mage::helper('adminhtml')->__('Invalid template data.')); } @@ -229,6 +229,17 @@ class Mage_Adminhtml_System_Email_TemplateController extends Mage_Adminhtml_Cont $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($template->getData())); } + /** + * Controller predispatch method + * + * @return Mage_Adminhtml_Controller_Action + */ + public function preDispatch() + { + $this->_setForcedFormKeyActions('delete'); + return parent::preDispatch(); + } + /** * Load email template from request * diff --git app/code/core/Mage/Adminhtml/controllers/Tax/RuleController.php app/code/core/Mage/Adminhtml/controllers/Tax/RuleController.php index 692a279d50e..23718ba9622 100644 --- app/code/core/Mage/Adminhtml/controllers/Tax/RuleController.php +++ app/code/core/Mage/Adminhtml/controllers/Tax/RuleController.php @@ -250,4 +250,15 @@ class Mage_Adminhtml_Tax_RuleController extends Mage_Adminhtml_Controller_Action { return Mage::helper($className); } + + /** + * Controller predispatch method + * + * @return Mage_Adminhtml_Controller_Action + */ + public function preDispatch() + { + $this->_setForcedFormKeyActions('delete'); + return parent::preDispatch(); + } } diff --git app/code/core/Mage/Api/Model/User.php app/code/core/Mage/Api/Model/User.php index 20c5a8c4b85..2540191a544 100644 --- app/code/core/Mage/Api/Model/User.php +++ app/code/core/Mage/Api/Model/User.php @@ -342,7 +342,7 @@ class Mage_Api_Model_User extends Mage_Core_Model_Abstract */ protected function _getEncodedApiKey($apiKey) { - return $this->_getHelper('core')->getHash($apiKey, Mage_Admin_Model_User::HASH_SALT_LENGTH); + return $this->_getHelper('core')->getHashPassword($apiKey, Mage_Admin_Model_User::HASH_SALT_LENGTH); } /** @@ -355,4 +355,75 @@ class Mage_Api_Model_User extends Mage_Core_Model_Abstract { return Mage::helper($helperName); } + + /** + * Validate user attribute values. + * + * @return array|bool + * @throws Zend_Validate_Exception + */ + public function validate() + { + $errors = new ArrayObject(); + + if (!Zend_Validate::is($this->getUsername(), 'NotEmpty')) { + $errors[] = $this->_getHelper('api')->__('User Name is required field.'); + } + + if (!Zend_Validate::is($this->getFirstname(), 'NotEmpty')) { + $errors[] = $this->_getHelper('api')->__('First Name is required field.'); + } + + if (!Zend_Validate::is($this->getLastname(), 'NotEmpty')) { + $errors[] = $this->_getHelper('api')->__('Last Name is required field.'); + } + + if (!Zend_Validate::is($this->getEmail(), 'EmailAddress')) { + $errors[] = $this->_getHelper('api')->__('Please enter a valid email.'); + } + + if ($this->hasNewApiKey()) { + $apiKey = $this->getNewApiKey(); + } elseif ($this->hasApiKey()) { + $apiKey = $this->getApiKey(); + } + + if (isset($apiKey)) { + $minCustomerPasswordLength = $this->_getMinCustomerPasswordLength(); + if (strlen($apiKey) < $minCustomerPasswordLength) { + $errors[] = $this->_getHelper('api') + ->__('Api Key must be at least of %d characters.', $minCustomerPasswordLength); + } + + if (!preg_match('/[a-z]/iu', $apiKey) || !preg_match('/[0-9]/u', $apiKey)) { + $errors[] = $this->_getHelper('api') + ->__('Api Key must include both numeric and alphabetic characters.'); + } + + if ($this->hasApiKeyConfirmation() && $apiKey != $this->getApiKeyConfirmation()) { + $errors[] = $this->_getHelper('api')->__('Api Key confirmation must be same as Api Key.'); + } + } + + if ($this->userExists()) { + $errors[] = $this->_getHelper('api') + ->__('A user with the same user name or email already exists.'); + } + + if (count($errors) === 0) { + return true; + } + + return (array) $errors; + } + + /** + * Get min customer password length + * + * @return int + */ + protected function _getMinCustomerPasswordLength() + { + return Mage::getSingleton('customer/customer')->getMinPasswordLength(); + } } diff --git app/code/core/Mage/Api/etc/config.xml app/code/core/Mage/Api/etc/config.xml index 97055fac77b..5303ea61943 100644 --- app/code/core/Mage/Api/etc/config.xml +++ app/code/core/Mage/Api/etc/config.xml @@ -28,7 +28,7 @@ - 1.6.0.1 + 1.6.0.2 diff --git app/code/core/Mage/Api/sql/api_setup/mysql4-upgrade-1.6.0.1-1.6.0.2.php app/code/core/Mage/Api/sql/api_setup/mysql4-upgrade-1.6.0.1-1.6.0.2.php new file mode 100644 index 00000000000..4c338e20ad5 --- /dev/null +++ app/code/core/Mage/Api/sql/api_setup/mysql4-upgrade-1.6.0.1-1.6.0.2.php @@ -0,0 +1,41 @@ +startSetup(); + +$this->getConnection()->changeColumn( + $this->getTable('api/user'), + 'api_key', + 'api_key', + array( + 'type' => Varien_Db_Ddl_Table::TYPE_TEXT, + 'length' => 255, + 'comment' => 'Api key' + ) +); + +$this->endSetup(); diff --git app/code/core/Mage/Catalog/Block/Product/Abstract.php app/code/core/Mage/Catalog/Block/Product/Abstract.php index 6a51f57da05..ff721d967ee 100644 --- app/code/core/Mage/Catalog/Block/Product/Abstract.php +++ app/code/core/Mage/Catalog/Block/Product/Abstract.php @@ -124,21 +124,7 @@ abstract class Mage_Catalog_Block_Product_Abstract extends Mage_Core_Block_Templ */ public function getAddToCartUrl($product, $additional = array()) { - if (!$product->getTypeInstance(true)->hasRequiredOptions($product)) { - return $this->helper('checkout/cart')->getAddUrl($product, $additional); - } - $additional = array_merge( - $additional, - array(Mage_Core_Model_Url::FORM_KEY => $this->_getSingletonModel('core/session')->getFormKey()) - ); - if (!isset($additional['_escape'])) { - $additional['_escape'] = true; - } - if (!isset($additional['_query'])) { - $additional['_query'] = array(); - } - $additional['_query']['options'] = 'cart'; - return $this->getProductUrl($product, $additional); + return $this->getAddToCartUrlCustom($product, $additional); } /** @@ -164,15 +150,7 @@ abstract class Mage_Catalog_Block_Product_Abstract extends Mage_Core_Block_Templ */ public function getSubmitUrl($product, $additional = array()) { - $submitRouteData = $this->getData('submit_route_data'); - if ($submitRouteData) { - $route = $submitRouteData['route']; - $params = isset($submitRouteData['params']) ? $submitRouteData['params'] : array(); - $submitUrl = $this->getUrl($route, array_merge($params, $additional)); - } else { - $submitUrl = $this->getAddToCartUrl($product, $additional); - } - return $submitUrl; + return $this->getSubmitUrlCustom($product, $additional); } /** @@ -183,7 +161,7 @@ abstract class Mage_Catalog_Block_Product_Abstract extends Mage_Core_Block_Templ */ public function getAddToWishlistUrl($product) { - return $this->helper('wishlist')->getAddUrl($product); + return $this->getAddToWishlistUrlCustom($product); } /** @@ -194,7 +172,7 @@ abstract class Mage_Catalog_Block_Product_Abstract extends Mage_Core_Block_Templ */ public function getAddToCompareUrl($product) { - return $this->helper('catalog/product_compare')->getAddUrl($product); + return $this->getAddToCompareUrlCustom($product); } /** @@ -650,6 +628,36 @@ abstract class Mage_Catalog_Block_Product_Abstract extends Mage_Core_Block_Templ return (boolean)$statusInfo->getDisplayStatus(); } + /** + * Return link to Add to Wishlist with or without Form Key + * + * @param Mage_Catalog_Model_Product $product + * @param bool $addFormKey + * @return string + */ + public function getAddToWishlistUrlCustom($product, $addFormKey = true) + { + if (!$addFormKey) { + return $this->helper('wishlist')->getAddUrlWithCustomParams($product, array(), false); + } + return $this->helper('wishlist')->getAddUrl($product); + } + + /** + * Retrieve Add Product to Compare Products List URL with or without Form Key + * + * @param Mage_Catalog_Model_Product $product + * @param bool $addFormKey + * @return string + */ + public function getAddToCompareUrlCustom($product, $addFormKey = true) + { + if (!$addFormKey) { + return $this->helper('catalog/product_compare')->getAddUrlCustom($product, false); + } + return $this->helper('catalog/product_compare')->getAddUrl($product); + } + /** * If exists price template block, retrieve price blocks from it * @@ -669,4 +677,64 @@ abstract class Mage_Catalog_Block_Product_Abstract extends Mage_Core_Block_Templ return $this; } + + /** + * Retrieve url for add product to cart with or without Form Key + * Will return product view page URL if product has required options + * + * @param Mage_Catalog_Model_Product $product + * @param array $additional + * @param bool $addFormKey + * @return string + */ + public function getAddToCartUrlCustom($product, $additional = array(), $addFormKey = true) + { + if (!$product->getTypeInstance(true)->hasRequiredOptions($product)) { + if (!$addFormKey) { + return $this->helper('checkout/cart')->getAddUrlCustom($product, $additional, false); + } + return $this->helper('checkout/cart')->getAddUrl($product, $additional); + } + if ($addFormKey) { + $additional = array_merge( + $additional, + array(Mage_Core_Model_Url::FORM_KEY => $this->_getSingletonModel('core/session')->getFormKey()) + ); + } + if (!isset($additional['_escape'])) { + $additional['_escape'] = true; + } + if (!isset($additional['_query'])) { + $additional['_query'] = array(); + } + $additional['_query']['options'] = 'cart'; + return $this->getProductUrl($product, $additional); + } + + /** + * Retrieves url for form submitting: + * some objects can use setSubmitRouteData() to set route and params for form submitting, + * otherwise default url will be used with or without Form Key + * + * @param Mage_Catalog_Model_Product $product + * @param array $additional + * @param bool $addFormKey + * @return string + */ + public function getSubmitUrlCustom($product, $additional = array(), $addFormKey = true) + { + $submitRouteData = $this->getData('submit_route_data'); + if ($submitRouteData) { + $route = $submitRouteData['route']; + $params = isset($submitRouteData['params']) ? $submitRouteData['params'] : array(); + $submitUrl = $this->getUrl($route, array_merge($params, $additional)); + } else { + if ($addFormKey) { + $submitUrl = $this->getAddToCartUrl($product, $additional); + } else { + $submitUrl = $this->getAddToCartUrlCustom($product, $additional, false); + } + } + return $submitUrl; + } } diff --git app/code/core/Mage/Catalog/Block/Product/Compare/List.php app/code/core/Mage/Catalog/Block/Product/Compare/List.php index b7ca53f5a7c..dbb7a1ca1e3 100644 --- app/code/core/Mage/Catalog/Block/Product/Compare/List.php +++ app/code/core/Mage/Catalog/Block/Product/Compare/List.php @@ -77,14 +77,7 @@ class Mage_Catalog_Block_Product_Compare_List extends Mage_Catalog_Block_Product */ public function getAddToWishlistUrl($product) { - $continueUrl = Mage::helper('core')->urlEncode($this->getUrl('customer/account')); - $urlParamName = Mage_Core_Controller_Front_Action::PARAM_NAME_URL_ENCODED; - - $params = array( - $urlParamName => $continueUrl - ); - - return $this->helper('wishlist')->getAddUrlWithParams($product, $params); + return $this->getAddToWishlistUrlCustom($product); } /** @@ -195,4 +188,26 @@ class Mage_Catalog_Block_Product_Compare_List extends Mage_Catalog_Block_Product $this->_customerId = $id; return $this; } + + /** + * Retrieve url for adding product to wishlist with params with or without Form Key + * + * @param Mage_Catalog_Model_Product $product + * @param bool $addFormKey + * @return string + */ + public function getAddToWishlistUrlCustom($product, $addFormKey = true) + { + $continueUrl = Mage::helper('core')->urlEncode($this->getUrl('customer/account')); + $params = array( + Mage_Core_Controller_Front_Action::PARAM_NAME_URL_ENCODED => $continueUrl + ); + + if (!$addFormKey) { + return $this->helper('wishlist')->getAddUrlWithCustomParams($product, $params, false); + } + + return $this->helper('wishlist')->getAddUrlWithParams($product, $params); + } + } diff --git app/code/core/Mage/Catalog/Block/Product/Price.php app/code/core/Mage/Catalog/Block/Product/Price.php index c1f98fa3aba..3e88bd341b6 100644 --- app/code/core/Mage/Catalog/Block/Product/Price.php +++ app/code/core/Mage/Catalog/Block/Product/Price.php @@ -179,7 +179,7 @@ class Mage_Catalog_Block_Product_Price extends Mage_Catalog_Block_Product_Abstra */ public function getAddToCartUrl($product, $additional = array()) { - return $this->helper('checkout/cart')->getAddUrl($product, $additional); + return $this->getAddToCartUrlCustom($product, $additional); } /** @@ -229,4 +229,20 @@ class Mage_Catalog_Block_Product_Price extends Mage_Catalog_Block_Product_Abstra { return $this->getProduct()->getResource()->getAttribute($attribute); } + + /** + * Retrieve url for direct adding product to cart with or without Form Key + * + * @param Mage_Catalog_Model_Product $product + * @param array $additional + * @param bool $addFormKey + * @return string + */ + public function getAddToCartUrlCustom($product, $additional = array(), $addFormKey = true) + { + if (!$addFormKey) { + return $this->helper('checkout/cart')->getAddUrlCustom($product, $additional, false); + } + return $this->helper('checkout/cart')->getAddUrl($product, $additional); + } } diff --git app/code/core/Mage/Catalog/Block/Product/View.php app/code/core/Mage/Catalog/Block/Product/View.php index 81dd13a29f3..d3ebbe7cab1 100644 --- app/code/core/Mage/Catalog/Block/Product/View.php +++ app/code/core/Mage/Catalog/Block/Product/View.php @@ -113,19 +113,7 @@ class Mage_Catalog_Block_Product_View extends Mage_Catalog_Block_Product_Abstrac */ public function getAddToCartUrl($product, $additional = array()) { - if ($this->hasCustomAddToCartUrl()) { - return $this->getCustomAddToCartUrl(); - } - - if ($this->getRequest()->getParam('wishlist_next')) { - $additional['wishlist_next'] = 1; - } - - $addUrlKey = Mage_Core_Controller_Front_Action::PARAM_NAME_URL_ENCODED; - $addUrlValue = Mage::getUrl('*/*/*', array('_use_rewrite' => true, '_current' => true)); - $additional[$addUrlKey] = Mage::helper('core')->urlEncode($addUrlValue); - - return $this->helper('checkout/cart')->getAddUrl($product, $additional); + return $this->getAddToCartUrlCustom($product, $additional); } /** @@ -223,4 +211,34 @@ class Mage_Catalog_Block_Product_View extends Mage_Catalog_Block_Product_Abstrac { return array_merge(parent::getCacheTags(), $this->getProduct()->getCacheIdTags()); } + + /** + * Retrieve url for direct adding product to cart with or without Form Key + * + * @param Mage_Catalog_Model_Product $product + * @param array $additional + * @param bool $addFormKey + * @return string + */ + public function getAddToCartUrlCustom($product, $additional = array(), $addFormKey = true) + { + if (!$addFormKey && $this->hasCustomAddToCartPostUrl()) { + return $this->getCustomAddToCartPostUrl(); + } elseif ($this->hasCustomAddToCartUrl()) { + return $this->getCustomAddToCartUrl(); + } + + if ($this->getRequest()->getParam('wishlist_next')) { + $additional['wishlist_next'] = 1; + } + + $addUrlValue = Mage::getUrl('*/*/*', array('_use_rewrite' => true, '_current' => true)); + $additional[Mage_Core_Controller_Front_Action::PARAM_NAME_URL_ENCODED] = + Mage::helper('core')->urlEncode($addUrlValue); + + if (!$addFormKey) { + return $this->helper('checkout/cart')->getAddUrlCustom($product, $additional, false); + } + return $this->helper('checkout/cart')->getAddUrl($product, $additional); + } } diff --git app/code/core/Mage/Catalog/Helper/Product/Compare.php app/code/core/Mage/Catalog/Helper/Product/Compare.php index e374e9fc69d..fdaf04653e2 100644 --- app/code/core/Mage/Catalog/Helper/Product/Compare.php +++ app/code/core/Mage/Catalog/Helper/Product/Compare.php @@ -146,11 +146,7 @@ class Mage_Catalog_Helper_Product_Compare extends Mage_Core_Helper_Url */ protected function _getUrlParams($product) { - return array( - 'product' => $product->getId(), - Mage_Core_Controller_Front_Action::PARAM_NAME_URL_ENCODED => $this->getEncodedUrl(), - Mage_Core_Model_Url::FORM_KEY => $this->_coreSession->getFormKey() - ); + return $this->_getUrlCustomParams($product); } /** @@ -161,10 +157,7 @@ class Mage_Catalog_Helper_Product_Compare extends Mage_Core_Helper_Url */ public function getAddUrl($product) { - if ($this->_logCondition->isVisitorLogEnabled() || $this->_customerSession->isLoggedIn()) { - return $this->_getUrl('catalog/product_compare/add', $this->_getUrlParams($product)); - } - return ''; + return $this->getAddUrlCustom($product); } /** @@ -175,15 +168,7 @@ class Mage_Catalog_Helper_Product_Compare extends Mage_Core_Helper_Url */ public function getAddToWishlistUrl($product) { - $beforeCompareUrl = $this->_catalogSession->getBeforeCompareUrl(); - - $params = array( - 'product' => $product->getId(), - Mage_Core_Model_Url::FORM_KEY => $this->_coreSession->getFormKey(), - Mage_Core_Controller_Front_Action::PARAM_NAME_URL_ENCODED => $this->getEncodedUrl($beforeCompareUrl) - ); - - return $this->_getUrl('wishlist/index/add', $params); + return $this->getAddToWishlistUrlCustom($product); } /** @@ -194,14 +179,7 @@ class Mage_Catalog_Helper_Product_Compare extends Mage_Core_Helper_Url */ public function getAddToCartUrl($product) { - $beforeCompareUrl = $this->_catalogSession->getBeforeCompareUrl(); - $params = array( - 'product' => $product->getId(), - Mage_Core_Controller_Front_Action::PARAM_NAME_URL_ENCODED => $this->getEncodedUrl($beforeCompareUrl), - Mage_Core_Model_Url::FORM_KEY => $this->_coreSession->getFormKey() - ); - - return $this->_getUrl('checkout/cart/add', $params); + return $this->getAddToCartUrlCustom($product); } /** @@ -362,4 +340,74 @@ class Mage_Catalog_Helper_Product_Compare extends Mage_Core_Helper_Url $this->_customerId = $id; return $this; } + + /** + * Retrieve url for adding product to conpare list with or without Form Key + * + * @param Mage_Catalog_Model_Product $product + * @param bool $addFormKey + * @return string + */ + public function getAddUrlCustom($product, $addFormKey = true) + { + if ($this->_logCondition->isVisitorLogEnabled() || $this->_customerSession->isLoggedIn()) { + return $this->_getUrl('catalog/product_compare/add', $this->_getUrlCustomParams($product, $addFormKey)); + } + return ''; + } + + /** + * Retrive add to wishlist url with or without Form Key + * + * @param Mage_Catalog_Model_Product $product + * @param bool $addFormKey + * @return string + */ + public function getAddToWishlistUrlCustom($product, $addFormKey = true) + { + $beforeCompareUrl = $this->_catalogSession->getBeforeCompareUrl(); + $params = $this->_getUrlCustomParams($product, $addFormKey, $beforeCompareUrl); + + return $this->_getUrl('wishlist/index/add', $params); + } + + /** + * Retrive add to cart url with or without Form Key + * + * @param Mage_Catalog_Model_Product $product + * @param bool $addFormKey + * @return string + */ + public function getAddToCartUrlCustom($product, $addFormKey = true) + { + $beforeCompareUrl = $this->_catalogSession->getBeforeCompareUrl(); + $params = array( + 'product' => $product->getId(), + Mage_Core_Controller_Front_Action::PARAM_NAME_URL_ENCODED => $this->getEncodedUrl($beforeCompareUrl), + ); + if ($addFormKey) { + $params[Mage_Core_Model_Url::FORM_KEY] = $this->_coreSession->getFormKey(); + } + + return $this->_getUrl('checkout/cart/add', $params); + } + + /** + * Get parameters used for build add product to compare list urls with or without Form Key + * + * @param Mage_Catalog_Model_Product $product + * @param bool $addFormKey + * @return array + */ + protected function _getUrlCustomParams($product, $addFormKey = true, $url = null) + { + $params = array( + 'product' => $product->getId(), + Mage_Core_Controller_Front_Action::PARAM_NAME_URL_ENCODED => $this->getEncodedUrl($url), + ); + if ($addFormKey) { + $params[Mage_Core_Model_Url::FORM_KEY] = $this->_coreSession->getFormKey(); + } + return $params; + } } diff --git app/code/core/Mage/Catalog/Model/Design.php app/code/core/Mage/Catalog/Model/Design.php index 4be9791bbe7..8915e2d6488 100644 --- app/code/core/Mage/Catalog/Model/Design.php +++ app/code/core/Mage/Catalog/Model/Design.php @@ -375,9 +375,19 @@ class Mage_Catalog_Model_Design extends Mage_Core_Model_Abstract $date = $object->getCustomDesignDate(); if (array_key_exists('from', $date) && array_key_exists('to', $date) && Mage::app()->getLocale()->isStoreDateInInterval(null, $date['from'], $date['to'])) { - $settings->setCustomDesign($object->getCustomDesign()) - ->setPageLayout($object->getPageLayout()) - ->setLayoutUpdates((array)$object->getCustomLayoutUpdate()); + $customLayout = $object->getCustomLayoutUpdate(); + if ($customLayout) { + try { + if (!Mage::getModel('core/layout_validator')->isValid($customLayout)) { + $customLayout = ''; + } + } catch (Exception $e) { + $customLayout = ''; + } + } + $settings->setCustomDesign($object->getCustomDesign()) + ->setPageLayout($object->getPageLayout()) + ->setLayoutUpdates((array)$customLayout); } return $settings; } diff --git app/code/core/Mage/Catalog/etc/config.xml app/code/core/Mage/Catalog/etc/config.xml index 1effed20f3f..0cde4ed4c9f 100644 --- app/code/core/Mage/Catalog/etc/config.xml +++ app/code/core/Mage/Catalog/etc/config.xml @@ -28,7 +28,7 @@ - 1.6.0.0.19.1.5 + 1.6.0.0.19.1.6 diff --git app/code/core/Mage/Catalog/sql/catalog_setup/upgrade-1.6.0.0.19.1.5-1.6.0.0.19.1.6.php app/code/core/Mage/Catalog/sql/catalog_setup/upgrade-1.6.0.0.19.1.5-1.6.0.0.19.1.6.php new file mode 100644 index 00000000000..2443c66e9b5 --- /dev/null +++ app/code/core/Mage/Catalog/sql/catalog_setup/upgrade-1.6.0.0.19.1.5-1.6.0.0.19.1.6.php @@ -0,0 +1,44 @@ +getEntityTypeId('catalog_product'), + $installer->getEntityTypeId('catalog_category'), +]; +foreach ($entitiesToUpgrade as $entityTypeId) { + if ($this->getAttributeId($entityTypeId, $attributeId)) { + $installer->updateAttribute( + $entityTypeId, + $attributeId, + 'backend_model', + 'catalog/attribute_backend_customlayoutupdate' + ); + } +} diff --git app/code/core/Mage/Checkout/Block/Cart/Item/Renderer.php app/code/core/Mage/Checkout/Block/Cart/Item/Renderer.php index 068d33e1ed3..a613a8ee153 100644 --- app/code/core/Mage/Checkout/Block/Cart/Item/Renderer.php +++ app/code/core/Mage/Checkout/Block/Cart/Item/Renderer.php @@ -215,19 +215,31 @@ class Mage_Checkout_Block_Cart_Item_Renderer extends Mage_Core_Block_Template * @return string */ public function getDeleteUrl() + { + return $this->getDeleteUrlCustom(); + } + + /** + * Get item delete url with or without Form Key + * + * @param bool $addFormKey + * @return string + */ + public function getDeleteUrlCustom($addFormKey = true) { if ($this->hasDeleteUrl()) { return $this->getData('delete_url'); } - return $this->getUrl( - 'checkout/cart/delete', - array( - 'id'=>$this->getItem()->getId(), - 'form_key' => Mage::getSingleton('core/session')->getFormKey(), - Mage_Core_Controller_Front_Action::PARAM_NAME_URL_ENCODED => $this->helper('core/url')->getEncodedUrl() - ) + $params = array( + 'id' => $this->getItem()->getId(), + Mage_Core_Controller_Front_Action::PARAM_NAME_URL_ENCODED => $this->helper('core/url')->getEncodedUrl(), ); + if ($addFormKey) { + $params[Mage_Core_Model_Url::FORM_KEY] = Mage::getSingleton('core/session')->getFormKey(); + } + + return $this->getUrl('checkout/cart/delete', $params); } /** diff --git app/code/core/Mage/Checkout/Helper/Cart.php app/code/core/Mage/Checkout/Helper/Cart.php index fd2bf9662b8..95a01c1ced5 100644 --- app/code/core/Mage/Checkout/Helper/Cart.php +++ app/code/core/Mage/Checkout/Helper/Cart.php @@ -60,28 +60,7 @@ class Mage_Checkout_Helper_Cart extends Mage_Core_Helper_Url */ public function getAddUrl($product, $additional = array()) { - $routeParams = array( - Mage_Core_Controller_Front_Action::PARAM_NAME_URL_ENCODED => $this->_getHelperInstance('core') - ->urlEncode($this->getCurrentUrl()), - 'product' => $product->getEntityId(), - Mage_Core_Model_Url::FORM_KEY => $this->_getSingletonModel('core/session')->getFormKey() - ); - - if (!empty($additional)) { - $routeParams = array_merge($routeParams, $additional); - } - - if ($product->hasUrlDataObject()) { - $routeParams['_store'] = $product->getUrlDataObject()->getStoreId(); - $routeParams['_store_to_url'] = true; - } - - if ($this->_getRequest()->getRouteName() == 'checkout' - && $this->_getRequest()->getControllerName() == 'cart') { - $routeParams['in_cart'] = 1; - } - - return $this->_getUrl('checkout/cart/add', $routeParams); + return $this->getAddUrlCustom($product, $additional); } /** @@ -180,4 +159,39 @@ class Mage_Checkout_Helper_Cart extends Mage_Core_Helper_Url { return Mage::getStoreConfigFlag(self::XML_PATH_REDIRECT_TO_CART, $store); } + + /** + * Retrieve url for add product to cart with or without Form Key + * + * @param Mage_Catalog_Model_Product $product + * @param array $additional + * @param bool $addFormKey + * @return string + */ + public function getAddUrlCustom($product, $additional = array(), $addFormKey = true) + { + $routeParams = array( + Mage_Core_Controller_Front_Action::PARAM_NAME_URL_ENCODED => $this->_getHelperInstance('core') + ->urlEncode($this->getCurrentUrl()), + 'product' => $product->getEntityId(), + ); + if ($addFormKey) { + $routeParams[Mage_Core_Model_Url::FORM_KEY] = $this->_getSingletonModel('core/session')->getFormKey(); + } + if (!empty($additional)) { + $routeParams = array_merge($routeParams, $additional); + } + if ($product->hasUrlDataObject()) { + $routeParams['_store'] = $product->getUrlDataObject()->getStoreId(); + $routeParams['_store_to_url'] = true; + } + if ( + $this->_getRequest()->getRouteName() == 'checkout' + && $this->_getRequest()->getControllerName() == 'cart' + ) { + $routeParams['in_cart'] = 1; + } + + return $this->_getUrl('checkout/cart/add', $routeParams); + } } diff --git app/code/core/Mage/Checkout/Model/Session.php app/code/core/Mage/Checkout/Model/Session.php index b249bb65b0e..c929ebf4132 100644 --- app/code/core/Mage/Checkout/Model/Session.php +++ app/code/core/Mage/Checkout/Model/Session.php @@ -120,21 +120,13 @@ class Mage_Checkout_Model_Session extends Mage_Core_Model_Session_Abstract if ($this->_quote === null) { /** @var $quote Mage_Sales_Model_Quote */ $quote = Mage::getModel('sales/quote')->setStoreId(Mage::app()->getStore()->getId()); - $customerSession = Mage::getSingleton('customer/session'); - if ($this->getQuoteId()) { if ($this->_loadInactive) { $quote->load($this->getQuoteId()); } else { $quote->loadActive($this->getQuoteId()); } - if ( - $quote->getId() - && ( - ($customerSession->isLoggedIn() && $customerSession->getId() == $quote->getCustomerId()) - || (!$customerSession->isLoggedIn() && !$quote->getCustomerId()) - ) - ) { + if ($quote->getId()) { /** * If current currency code of quote is not equal current currency code of store, * need recalculate totals of quote. It is possible if customer use currency switcher or @@ -151,16 +143,16 @@ class Mage_Checkout_Model_Session extends Mage_Core_Model_Session_Abstract $quote->load($this->getQuoteId()); } } else { - $quote->unsetData(); $this->setQuoteId(null); } } + $customerSession = Mage::getSingleton('customer/session'); + if (!$this->getQuoteId()) { if ($customerSession->isLoggedIn() || $this->_customer) { $customer = ($this->_customer) ? $this->_customer : $customerSession->getCustomer(); $quote->loadByCustomer($customer); - $quote->setCustomer($customer); $this->setQuoteId($quote->getId()); } else { $quote->setIsCheckoutCart(true); diff --git app/code/core/Mage/Cms/Block/Widget/Block.php app/code/core/Mage/Cms/Block/Widget/Block.php index 359fc291f9a..d1abf253884 100644 --- app/code/core/Mage/Cms/Block/Widget/Block.php +++ app/code/core/Mage/Cms/Block/Widget/Block.php @@ -81,7 +81,13 @@ class Mage_Cms_Block_Widget_Block extends Mage_Core_Block_Template implements Ma /* @var $helper Mage_Cms_Helper_Data */ $helper = Mage::helper('cms'); $processor = $helper->getBlockTemplateProcessor(); - $this->setText($processor->filter($block->getContent())); + if ($this->isRequestFromAdminArea()) { + $this->setText($processor->filter( + Mage::getSingleton('core/input_filter_maliciousCode')->filter($block->getContent()) + )); + } else { + $this->setText($processor->filter($block->getContent())); + } $this->addModelTags($block); } } @@ -104,4 +110,14 @@ class Mage_Cms_Block_Widget_Block extends Mage_Core_Block_Template implements Ma } return $result; } + + /** + * Check is request goes from admin area + * + * @return bool + */ + public function isRequestFromAdminArea() + { + return $this->getRequest()->getRouteName() === Mage_Core_Model_App_Area::AREA_ADMINHTML; + } } diff --git app/code/core/Mage/Core/Block/Abstract.php app/code/core/Mage/Core/Block/Abstract.php index 54aa1b62f40..8f5b399c78f 100644 --- app/code/core/Mage/Core/Block/Abstract.php +++ app/code/core/Mage/Core/Block/Abstract.php @@ -1393,6 +1393,16 @@ abstract class Mage_Core_Block_Abstract extends Varien_Object return $this->getData('cache_lifetime'); } + /** + * Retrieve Session Form Key + * + * @return string + */ + public function getFormKey() + { + return Mage::getSingleton('core/session')->getFormKey(); + } + /** * Load block html from cache storage * diff --git app/code/core/Mage/Core/Helper/Data.php app/code/core/Mage/Core/Helper/Data.php index db971fd1a19..dc79c643fda 100644 --- app/code/core/Mage/Core/Helper/Data.php +++ app/code/core/Mage/Core/Helper/Data.php @@ -270,11 +270,41 @@ class Mage_Core_Helper_Data extends Mage_Core_Helper_Abstract return $this->getEncryptor()->getHash($password, $salt); } + /** + * Generate password hash for user + * + * @param string $password + * @param mixed $salt + * @return string + */ + public function getHashPassword($password, $salt = false) + { + $encryptionModel = $this->getEncryptor(); + $latestVersionHash = $this->getVersionHash($encryptionModel); + if ($latestVersionHash == $encryptionModel::HASH_VERSION_SHA512) { + return $this->getEncryptor()->getHashPassword($password, $salt); + } + return $this->getEncryptor()->getHashPassword($password, Mage_Admin_Model_User::HASH_SALT_EMPTY); + } + public function validateHash($password, $hash) { return $this->getEncryptor()->validateHash($password, $hash); } + /** + * Get encryption method depending on the presence of the function - password_hash. + * + * @param Mage_Core_Model_Encryption $encryptionModel + * @return int + */ + public function getVersionHash(Mage_Core_Model_Encryption $encryptionModel) + { + return function_exists('password_hash') + ? $encryptionModel::HASH_VERSION_LATEST + : $encryptionModel::HASH_VERSION_SHA512; + } + /** * Retrieve store identifier * diff --git app/code/core/Mage/Core/Helper/String.php app/code/core/Mage/Core/Helper/String.php index 2acdd1ea8cf..e23a8051c8c 100644 --- app/code/core/Mage/Core/Helper/String.php +++ app/code/core/Mage/Core/Helper/String.php @@ -536,4 +536,36 @@ class Mage_Core_Helper_String extends Mage_Core_Helper_Abstract $prevChar = $char; } } + + /** + * Detect serialization of data Array or Object + * + * @param mixed $data + * @return bool + */ + public function isSerializedArrayOrObject($data) + { + $pattern = + '/^a:\d+:\{(i:\d+;|s:\d+:\".+\";|N;|O:\d+:\"\w+\":\d+:\{\w:\d+:)+|^O:\d+:\"\w+\":\d+:\{(s:\d+:\"|i:\d+;)/'; + return is_string($data) && preg_match($pattern, $data); + } + + /** + * Validate is Serialized Data Object in string + * + * @param string $str + * @return bool + */ + public function validateSerializedObject($str) + { + if ($this->isSerializedArrayOrObject($str)) { + try { + $this->unserialize($str); + } catch (Exception $e) { + return false; + } + } + + return true; + } } diff --git app/code/core/Mage/Core/Model/App.php app/code/core/Mage/Core/Model/App.php index fa3d228ef99..c72acde862a 100644 --- app/code/core/Mage/Core/Model/App.php +++ app/code/core/Mage/Core/Model/App.php @@ -72,6 +72,22 @@ class Mage_Core_Model_App */ const ADMIN_STORE_ID = 0; + /** + * The absolute minimum of password length for all types of passwords + * + * With changing this value also need to change: + * 1. in `js/prototype/validation.js` declarations `var minLength = 7;` in two places; + * 2. in `app/code/core/Mage/Customer/etc/system.xml` + * comments for fields `min_password_length` and `min_admin_password_length` + * `Please enter a number 7 or greater in this field.`; + * 3. in `app/code/core/Mage/Customer/etc/config.xml` value `7` + * and, maybe, value `14` + * (if the absolute minimum of password length is higher then this value); + * 4. maybe, the value of deprecated `const MIN_PASSWORD_LENGTH` in `app/code/core/Mage/Admin/Model/User.php`, + * (if the absolute minimum of password length is higher then this value). + */ + const ABSOLUTE_MIN_PASSWORD_LENGTH = 7; + /** * Application loaded areas array * diff --git app/code/core/Mage/Core/Model/Encryption.php app/code/core/Mage/Core/Model/Encryption.php index e71d08525ae..5b443c30f5c 100644 --- app/code/core/Mage/Core/Model/Encryption.php +++ app/code/core/Mage/Core/Model/Encryption.php @@ -33,6 +33,14 @@ */ class Mage_Core_Model_Encryption { + const HASH_VERSION_MD5 = 0; + const HASH_VERSION_SHA512 = 2; + + /** + * Encryption method bcrypt + */ + const HASH_VERSION_LATEST = 3; + /** * @var Varien_Crypt_Mcrypt */ @@ -74,14 +82,37 @@ class Mage_Core_Model_Encryption return $salt === false ? $this->hash($password) : $this->hash($salt . $password) . ':' . $salt; } + /** + * Generate hash for customer password + * + * @param string $password + * @param mixed $salt + * @return string + */ + public function getHashPassword($password, $salt = null) + { + if (is_integer($salt)) { + $salt = $this->_helper->getRandomString($salt); + } + return (bool) $salt + ? $this->hash($salt . $password, $this->_helper->getVersionHash($this)) . ':' . $salt + : $this->hash($password, $this->_helper->getVersionHash($this)); + } + /** * Hash a string * * @param string $data - * @return string + * @param int $version + * @return bool|string */ - public function hash($data) + public function hash($data, $version = self::HASH_VERSION_MD5) { + if (self::HASH_VERSION_LATEST === $version && $version === $this->_helper->getVersionHash($this)) { + return password_hash($data, PASSWORD_DEFAULT); + } elseif (self::HASH_VERSION_SHA512 == $version) { + return hash('sha512', $data); + } return md5($data); } @@ -95,14 +126,31 @@ class Mage_Core_Model_Encryption */ public function validateHash($password, $hash) { - $hashArr = explode(':', $hash); - switch (count($hashArr)) { - case 1: - return hash_equals($this->hash($password), $hash); - case 2: - return hash_equals($this->hash($hashArr[1] . $password), $hashArr[0]); + return $this->validateHashByVersion($password, $hash, self::HASH_VERSION_LATEST) + || $this->validateHashByVersion($password, $hash, self::HASH_VERSION_SHA512) + || $this->validateHashByVersion($password, $hash, self::HASH_VERSION_MD5); + } + + /** + * Validate hash by specified version + * + * @param string $password + * @param string $hash + * @param int $version + * @return bool + */ + public function validateHashByVersion($password, $hash, $version = self::HASH_VERSION_MD5) + { + if ($version == self::HASH_VERSION_LATEST && $version == $this->_helper->getVersionHash($this)) { + return password_verify($password, $hash); + } + // look for salt + $hashArr = explode(':', $hash, 2); + if (1 === count($hashArr)) { + return hash_equals($this->hash($password, $version), $hash); } - Mage::throwException('Invalid hash.'); + list($hash, $salt) = $hashArr; + return hash_equals($this->hash($salt . $password, $version), $hash); } /** diff --git app/code/core/Mage/Core/Model/File/Uploader.php app/code/core/Mage/Core/Model/File/Uploader.php index ced1412a1ab..d74d851506c 100644 --- app/code/core/Mage/Core/Model/File/Uploader.php +++ app/code/core/Mage/Core/Model/File/Uploader.php @@ -41,6 +41,13 @@ class Mage_Core_Model_File_Uploader extends Varien_File_Uploader */ protected $_skipDbProcessing = false; + /** + * Max file name length + * + * @var int + */ + protected $_fileNameMaxLength = 200; + /** * Save file to storage * @@ -99,4 +106,25 @@ class Mage_Core_Model_File_Uploader extends Varien_File_Uploader return parent::checkAllowedExtension($extension); } + + /** + * Used to save uploaded file into destination folder with + * original or new file name (if specified). + * Added file name length validation. + * + * @param string $destinationFolder + * @param string|null $newFileName + * @return bool|void + * @throws Exception + */ + public function save($destinationFolder, $newFileName = null) + { + $fileName = isset($newFileName) ? $newFileName : $this->_file['name']; + if (strlen($fileName) > $this->_fileNameMaxLength) { + throw new Exception( + Mage::helper('core')->__("File name is too long. Maximum length is %s.", $this->_fileNameMaxLength) + ); + } + return parent::save($destinationFolder, $newFileName); + } } diff --git app/code/core/Mage/Core/Model/Input/Filter/MaliciousCode.php app/code/core/Mage/Core/Model/Input/Filter/MaliciousCode.php index e88beb2488e..6ac7ed9886d 100644 --- app/code/core/Mage/Core/Model/Input/Filter/MaliciousCode.php +++ app/code/core/Mage/Core/Model/Input/Filter/MaliciousCode.php @@ -50,11 +50,13 @@ class Mage_Core_Model_Input_Filter_MaliciousCode implements Zend_Filter_Interfac //js in the style attribute '/style=[^<]*((expression\s*?\([^<]*?\))|(behavior\s*:))[^<]*(?=\>)/Uis', //js attributes - '/(ondblclick|onclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|onload|onunload|onerror)\s*=[^>]*(?=\>)/Uis', + '/(ondblclick|onclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|onload|onunload|onerror|onanimationstart)\s*=[^>]*(?=\>)/Uis', //tags '/<\/?(script|meta|link|frame|iframe).*>/Uis', //base64 usage '/src\s*=[^<]*base64[^<]*(?=\>)/Uis', + //data attribute + '/(data(\\\\x3a|:|%3A)(.+?(?=")|.+?(?=\')))/is', ); /** @@ -99,4 +101,64 @@ class Mage_Core_Model_Input_Filter_MaliciousCode implements Zend_Filter_Interfac $this->_expressions = $expressions; return $this; } + + /** + * The filter adds safe attributes to the link + * + * @param string $html + * @param bool $removeWrapper flag for remove wrapper tags: Doctype, html, body + * @return string + * @throws Mage_Core_Exception + */ + public function linkFilter($html, $removeWrapper = true) + { + if (stristr($html, '_initDOMDocument(); + if (!$dom->loadHTML($html)) { + Mage::throwException(Mage::helper('core')->__('HTML filtration has failed.')); + } + + $relAttributeDefaultItems = array('noopener', 'noreferrer'); + /** @var DOMElement $linkItem */ + foreach ($dom->getElementsByTagName('a') as $linkItem) { + $relAttributeItems = array(); + $relAttributeCurrentValue = $linkItem->getAttribute('rel'); + if (!empty($relAttributeCurrentValue)) { + $relAttributeItems = explode(' ', $relAttributeCurrentValue); + } + $relAttributeItems = array_unique(array_merge($relAttributeItems, $relAttributeDefaultItems)); + $linkItem->setAttribute('rel', implode(' ', $relAttributeItems)); + $linkItem->setAttribute('target', '_blank'); + } + + if (!$html = $dom->saveHTML()) { + Mage::throwException(Mage::helper('core')->__('HTML filtration has failed.')); + } + + if ($removeWrapper) { + $html = preg_replace('/<(?:!DOCTYPE|\/?(?:html|body))[^>]*>\s*/i', '', $html); + } + + libxml_use_internal_errors($libXmlErrorsState); + + return $html; + } + + /** + * Initialize built-in DOM parser instance + * + * @return DOMDocument + */ + protected function _initDOMDocument() + { + $dom = new DOMDocument(); + $dom->strictErrorChecking = false; + $dom->recover = false; + + return $dom; + } } diff --git app/code/core/Mage/Core/Model/Layout/Validator.php app/code/core/Mage/Core/Model/Layout/Validator.php new file mode 100644 index 00000000000..fa390c9a60a --- /dev/null +++ app/code/core/Mage/Core/Model/Layout/Validator.php @@ -0,0 +1,258 @@ + + */ +class Mage_Core_Model_Layout_Validator extends Zend_Validate_Abstract +{ + const XML_PATH_LAYOUT_DISALLOWED_BLOCKS = 'validators/custom_layout/disallowed_block'; + const XML_INVALID = 'invalidXml'; + const INVALID_TEMPLATE_PATH = 'invalidTemplatePath'; + const INVALID_BLOCK_NAME = 'invalidBlockName'; + const PROTECTED_ATTR_HELPER_IN_TAG_ACTION_VAR = 'protectedAttrHelperInActionVar'; + const INVALID_XML_OBJECT_EXCEPTION = 'invalidXmlObject'; + + /** + * The Varien SimpleXml object + * + * @var Varien_Simplexml_Element + */ + protected $_value; + + /** + * XPath expression for checking layout update + * + * @var array + */ + protected $_disallowedXPathExpressions = array( + '*//template', + '*//@template', + '//*[@method=\'setTemplate\']', + '//*[@method=\'setDataUsingMethod\']//*[contains(translate(text(), + \'ABCDEFGHIJKLMNOPQRSTUVWXYZ\', \'abcdefghijklmnopqrstuvwxyz\'), \'template\')]/../*', + ); + + /** + * @var string + */ + protected $_xpathBlockValidationExpression = ''; + + /** + * Disallowed template name + * + * @var array + */ + protected $_disallowedBlock = array(); + + /** + * Protected expressions + * + * @var array + */ + protected $_protectedExpressions = array( + self::PROTECTED_ATTR_HELPER_IN_TAG_ACTION_VAR => '//action/*[@helper]', + ); + + /** + * Construct + */ + public function __construct() + { + $this->_initMessageTemplates(); + $this->getDisallowedBlocks(); + } + + /** + * Initialize messages templates with translating + * + * @return Mage_Core_Model_Layout_Validator + */ + protected function _initMessageTemplates() + { + if (!$this->_messageTemplates) { + $this->_messageTemplates = array( + self::PROTECTED_ATTR_HELPER_IN_TAG_ACTION_VAR => + Mage::helper('core')->__('Helper attributes should not be used in custom layout updates.'), + self::XML_INVALID => Mage::helper('core')->__('XML data is invalid.'), + self::INVALID_TEMPLATE_PATH => Mage::helper('core')->__( + 'Invalid template path used in layout update.' + ), + self::INVALID_BLOCK_NAME => Mage::helper('core')->__('Disallowed block name for frontend.'), + self::INVALID_XML_OBJECT_EXCEPTION => + Mage::helper('core')->__('XML object is not instance of "Varien_Simplexml_Element".'), + ); + } + return $this; + } + + /** + * @return array + */ + public function getDisallowedBlocks() + { + if (!count($this->_disallowedBlock)) { + $disallowedBlockConfig = $this->_getDisallowedBlockConfigValue(); + if (is_array($disallowedBlockConfig)) { + foreach ($disallowedBlockConfig as $blockName => $value) { + $this->_disallowedBlock[] = $blockName; + } + } + } + return $this->_disallowedBlock; + } + + /** + * @return mixed + */ + protected function _getDisallowedBlockConfigValue() + { + return Mage::getStoreConfig(self::XML_PATH_LAYOUT_DISALLOWED_BLOCKS); + } + + /** + * Returns true if and only if $value meets the validation requirements + * + * If $value fails validation, then this method returns false, and + * getMessages() will return an array of messages that explain why the + * validation failed. + * + * @throws Exception Throw exception when xml object is not + * instance of Varien_Simplexml_Element + * @param Varien_Simplexml_Element|string $value + * @return bool + */ + public function isValid($value) + { + if (is_string($value)) { + $value = trim($value); + try { + $value = new Varien_Simplexml_Element('' . $value . ''); + } catch (Exception $e) { + $this->_error(self::XML_INVALID); + return false; + } + } elseif (!($value instanceof Varien_Simplexml_Element)) { + throw new Exception($this->_messageTemplates[self::INVALID_XML_OBJECT_EXCEPTION]); + } + if ($value->xpath($this->getXpathBlockValidationExpression())) { + $this->_error(self::INVALID_BLOCK_NAME); + return false; + } + // if layout update declare custom templates then validate their paths + if ($templatePaths = $value->xpath($this->getXpathValidationExpression())) { + try { + $this->validateTemplatePath($templatePaths); + } catch (Exception $e) { + $this->_error(self::INVALID_TEMPLATE_PATH); + return false; + } + } + $this->_setValue($value); + + foreach ($this->_protectedExpressions as $key => $xpr) { + if ($this->_value->xpath($xpr)) { + $this->_error($key); + return false; + } + } + return true; + } + + /** + * @return array + */ + public function getProtectedExpressions() + { + return $this->_protectedExpressions; + } + + /** + * Returns xPath for validate incorrect path to template + * + * @return string xPath for validate incorrect path to template + */ + public function getXpathValidationExpression() + { + return implode(" | ", $this->_disallowedXPathExpressions); + } + + /** + * @return array + */ + public function getDisallowedXpathValidationExpression() + { + return $this->_disallowedXPathExpressions; + } + + /** + * Returns xPath for validate incorrect block name + * + * @return string xPath for validate incorrect block name + */ + public function getXpathBlockValidationExpression() + { + if (!$this->_xpathBlockValidationExpression) { + if (count($this->_disallowedBlock)) { + foreach ($this->_disallowedBlock as $key => $value) { + $this->_xpathBlockValidationExpression .= $key > 0 ? " | " : ''; + $this->_xpathBlockValidationExpression .= + "//block[translate(@type, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz') = "; + $this->_xpathBlockValidationExpression .= + "translate('$value', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')]"; + } + } + } + return $this->_xpathBlockValidationExpression; + } + + /** + * Validate template path for preventing access to the directory above + * If template path value has "../" + * + * @throws Exception + * + * @param $templatePaths | array + */ + public function validateTemplatePath(array $templatePaths) + { + /** @var $path Varien_Simplexml_Element */ + foreach ($templatePaths as $path) { + if ($path->hasChildren()) { + $path = stripcslashes(trim((string) $path->children(), '"')); + } + if (strpos($path, '..' . DS) !== false) { + throw new Exception(); + } + } + } +} diff --git app/code/core/Mage/Core/Model/Resource/File/Storage/Database.php app/code/core/Mage/Core/Model/Resource/File/Storage/Database.php index 82f156d67d6..89a24faf21e 100644 --- app/code/core/Mage/Core/Model/Resource/File/Storage/Database.php +++ app/code/core/Mage/Core/Model/Resource/File/Storage/Database.php @@ -71,7 +71,7 @@ class Mage_Core_Model_Resource_File_Storage_Database extends Mage_Core_Model_Res 'nullable' => false, 'default' => Varien_Db_Ddl_Table::TIMESTAMP_INIT ), 'Upload Timestamp') - ->addColumn('filename', Varien_Db_Ddl_Table::TYPE_TEXT, 100, array( + ->addColumn('filename', Varien_Db_Ddl_Table::TYPE_TEXT, 255, array( 'nullable' => false ), 'Filename') ->addColumn('directory_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array( diff --git app/code/core/Mage/Core/etc/config.xml app/code/core/Mage/Core/etc/config.xml index 58afa43cc42..31f51f7ce17 100644 --- app/code/core/Mage/Core/etc/config.xml +++ app/code/core/Mage/Core/etc/config.xml @@ -28,7 +28,7 @@ - 1.6.0.7.1.2 + 1.6.0.10 @@ -432,6 +432,7 @@ 2 2 1 + 0 @@ -499,6 +500,13 @@ + + + + + + + diff --git app/code/core/Mage/Core/etc/jstranslator.xml app/code/core/Mage/Core/etc/jstranslator.xml index 3ac9c909d18..b7fa871eae0 100644 --- app/code/core/Mage/Core/etc/jstranslator.xml +++ app/code/core/Mage/Core/etc/jstranslator.xml @@ -82,10 +82,10 @@ Please use only visible characters and spaces. - Please enter 6 or more characters without leading or trailing spaces. + Please enter more characters or clean leading or trailing spaces. - Please enter 7 or more characters. Password should contain both numeric and alphabetic characters. + Please enter more characters. Password should contain both numeric and alphabetic characters. Please make sure your passwords match. @@ -130,7 +130,7 @@ Please select State/Province. - Please enter 6 or more characters without leading or trailing spaces. + Please enter more characters or clean leading or trailing spaces. Please enter a number greater than 0 in this field. diff --git app/code/core/Mage/Core/etc/system.xml app/code/core/Mage/Core/etc/system.xml index e416041d320..a3ac96dbce1 100644 --- app/code/core/Mage/Core/etc/system.xml +++ app/code/core/Mage/Core/etc/system.xml @@ -119,6 +119,7 @@ 1 1 1 + 1 diff --git app/code/core/Mage/Core/sql/core_setup/upgrade-1.6.0.8-1.6.0.9.php app/code/core/Mage/Core/sql/core_setup/upgrade-1.6.0.8-1.6.0.9.php new file mode 100644 index 00000000000..1aede9c9a26 --- /dev/null +++ app/code/core/Mage/Core/sql/core_setup/upgrade-1.6.0.8-1.6.0.9.php @@ -0,0 +1,35 @@ +startSetup(); +$connection = $installer->getConnection(); + +$connection->addColumn($installer->getTable('core_config_data'), 'updated_at', Varien_Db_Ddl_Table::TYPE_TIMESTAMP); + +$installer->endSetup(); diff --git app/code/core/Mage/Core/sql/core_setup/upgrade-1.6.0.9-1.6.0.10.php app/code/core/Mage/Core/sql/core_setup/upgrade-1.6.0.9-1.6.0.10.php new file mode 100644 index 00000000000..b3726b957ae --- /dev/null +++ app/code/core/Mage/Core/sql/core_setup/upgrade-1.6.0.9-1.6.0.10.php @@ -0,0 +1,48 @@ +startSetup(); +$table = $installer->getTable('core/file_storage'); + +/** + * Change column + */ +if ($installer->getConnection()->isTableExists($table)) { + $installer->getConnection()->modifyColumn( + $table, + 'filename', + array( + 'type' => Varien_Db_Ddl_Table::TYPE_TEXT, + 'length' => 255, + 'nullable' => false, + 'comment' => 'Filename', + ) + ); +} + +$installer->endSetup(); diff --git app/code/core/Mage/Customer/Block/Account/Changeforgotten.php app/code/core/Mage/Customer/Block/Account/Changeforgotten.php index 2f1ffbf814e..fc17574e99c 100644 --- app/code/core/Mage/Customer/Block/Account/Changeforgotten.php +++ app/code/core/Mage/Customer/Block/Account/Changeforgotten.php @@ -33,5 +33,13 @@ */ class Mage_Customer_Block_Account_Changeforgotten extends Mage_Core_Block_Template { - + /** + * Retrieve minimum length of customer password + * + * @return int + */ + public function getMinPasswordLength() + { + return Mage::getModel('customer/customer')->getMinPasswordLength(); + } } diff --git app/code/core/Mage/Customer/Block/Address/Renderer/Default.php app/code/core/Mage/Customer/Block/Address/Renderer/Default.php index 6709baee880..92c8d227658 100644 --- app/code/core/Mage/Customer/Block/Address/Renderer/Default.php +++ app/code/core/Mage/Customer/Block/Address/Renderer/Default.php @@ -70,7 +70,13 @@ class Mage_Customer_Block_Address_Renderer_Default $countryFormat = is_null($address) ? false : $address->getCountryModel()->getFormat($this->getType()->getCode()); - $format = $countryFormat ? $countryFormat->getFormat() : $this->getType()->getDefaultFormat(); + if ($countryFormat) { + $format = $countryFormat->getFormat(); + } else { + $regExp = "/^[^()\n]*+(\((?>[^()\n]|(?1))*+\)[^()\n]*+)++$|^[^()]+?$/m"; + preg_match_all($regExp, $this->getType()->getDefaultFormat(), $matches, PREG_SET_ORDER); + $format = count($matches) ? $this->_prepareAddressTemplateData($this->getType()->getDefaultFormat()) : null; + } return $format; } @@ -132,9 +138,25 @@ class Mage_Customer_Block_Address_Renderer_Default } $formater->setVariables($data); - - $format = !is_null($format) ? $format : $this->getFormat($address); + $format = !is_null($format) ? $format : $this->_prepareAddressTemplateData($this->getFormat($address)); return $formater->filter($format); } + + /** + * Get address template data without url and js code + * @param $data + * @return string + */ + protected function _prepareAddressTemplateData($data) + { + $result = ''; + if (is_string($data)) { + $urlRegExp = "@(https?://([-\w\.]+[-\w])+(:\d+)?(/([\w/_\.#-]*(\?\S+)?[^\.\s])?)?)@"; + /** @var $maliciousCodeFilter Mage_Core_Model_Input_Filter_MaliciousCode */ + $maliciousCodeFilter = Mage::getSingleton('core/input_filter_maliciousCode'); + $result = preg_replace($urlRegExp, ' ', $maliciousCodeFilter->filter($data)); + } + return $result; + } } diff --git app/code/core/Mage/Customer/Block/Form/Register.php app/code/core/Mage/Customer/Block/Form/Register.php index 5ee07c1f307..c41fe7c5f60 100644 --- app/code/core/Mage/Customer/Block/Form/Register.php +++ app/code/core/Mage/Customer/Block/Form/Register.php @@ -161,4 +161,14 @@ class Mage_Customer_Block_Form_Register extends Mage_Directory_Block_Data return $this; } + + /** + * Retrieve minimum length of customer password + * + * @return int + */ + public function getMinPasswordLength() + { + return Mage::getModel('customer/customer')->getMinPasswordLength(); + } } diff --git app/code/core/Mage/Customer/Model/Customer.php app/code/core/Mage/Customer/Model/Customer.php index d23e8f18a10..c77b0be5130 100644 --- app/code/core/Mage/Customer/Model/Customer.php +++ app/code/core/Mage/Customer/Model/Customer.php @@ -71,8 +71,14 @@ class Mage_Customer_Model_Customer extends Mage_Core_Model_Abstract /** * Minimum Password Length + * @deprecated Use getMinPasswordLength() method instead */ - const MINIMUM_PASSWORD_LENGTH = 6; + const MINIMUM_PASSWORD_LENGTH = Mage_Core_Model_App::ABSOLUTE_MIN_PASSWORD_LENGTH; + + /** + * Configuration path for minimum length of password + */ + const XML_PATH_MIN_PASSWORD_LENGTH = 'customer/password/min_password_length'; /** * Maximum Password Length @@ -398,7 +404,7 @@ class Mage_Customer_Model_Customer extends Mage_Core_Model_Abstract public function hashPassword($password, $salt = null) { return $this->_getHelper('core') - ->getHash(trim($password), !is_null($salt) ? $salt : Mage_Admin_Model_User::HASH_SALT_LENGTH); + ->getHashPassword(trim($password), (bool) $salt ? $salt : Mage_Admin_Model_User::HASH_SALT_LENGTH); } /** @@ -420,6 +426,10 @@ class Mage_Customer_Model_Customer extends Mage_Core_Model_Abstract */ public function generatePassword($length = 8) { + $minPasswordLength = $this->getMinPasswordLength(); + if ($minPasswordLength > $length) { + $length = $minPasswordLength; + } $chars = Mage_Core_Helper_Data::CHARS_PASSWORD_LOWERS . Mage_Core_Helper_Data::CHARS_PASSWORD_UPPERS . Mage_Core_Helper_Data::CHARS_PASSWORD_DIGITS @@ -878,9 +888,10 @@ class Mage_Customer_Model_Customer extends Mage_Core_Model_Abstract if (!$this->getId() && !Zend_Validate::is($password , 'NotEmpty')) { $errors[] = Mage::helper('customer')->__('The password cannot be empty.'); } - if (strlen($password) && !Zend_Validate::is($password, 'StringLength', array(self::MINIMUM_PASSWORD_LENGTH))) { + $minPasswordLength = $this->getMinPasswordLength(); + if (strlen($password) && !Zend_Validate::is($password, 'StringLength', array($minPasswordLength))) { $errors[] = Mage::helper('customer') - ->__('The minimum password length is %s', self::MINIMUM_PASSWORD_LENGTH); + ->__('The minimum password length is %s', $minPasswordLength); } if (strlen($password) && !Zend_Validate::is($password, 'StringLength', array('max' => self::MAXIMUM_PASSWORD_LENGTH))) { $errors[] = Mage::helper('customer') @@ -922,9 +933,10 @@ class Mage_Customer_Model_Customer extends Mage_Core_Model_Abstract if (!Zend_Validate::is($password, 'NotEmpty')) { $errors[] = Mage::helper('customer')->__('The password cannot be empty.'); } - if (!Zend_Validate::is($password, 'StringLength', array(self::MINIMUM_PASSWORD_LENGTH))) { + $minPasswordLength = $this->getMinPasswordLength(); + if (!Zend_Validate::is($password, 'StringLength', array($minPasswordLength))) { $errors[] = Mage::helper('customer') - ->__('The minimum password length is %s', self::MINIMUM_PASSWORD_LENGTH); + ->__('The minimum password length is %s', $minPasswordLength); } if (!Zend_Validate::is($password, 'StringLength', array('max' => self::MAXIMUM_PASSWORD_LENGTH))) { $errors[] = Mage::helper('customer') @@ -1455,4 +1467,16 @@ class Mage_Customer_Model_Customer extends Mage_Core_Model_Abstract $this->setData('password_confirmation', null); return $this; } + + /** + * Retrieve minimum length of password + * + * @return int + */ + public function getMinPasswordLength() + { + $minLength = (int)Mage::getStoreConfig(self::XML_PATH_MIN_PASSWORD_LENGTH); + $absoluteMinLength = Mage_Core_Model_App::ABSOLUTE_MIN_PASSWORD_LENGTH; + return ($minLength < $absoluteMinLength) ? $absoluteMinLength : $minLength; + } } diff --git app/code/core/Mage/Customer/Model/Customer/Attribute/Backend/Password.php app/code/core/Mage/Customer/Model/Customer/Attribute/Backend/Password.php index b9033326b0a..8a95696111a 100644 --- app/code/core/Mage/Customer/Model/Customer/Attribute/Backend/Password.php +++ app/code/core/Mage/Customer/Model/Customer/Attribute/Backend/Password.php @@ -43,8 +43,12 @@ class Mage_Customer_Model_Customer_Attribute_Backend_Password extends Mage_Eav_M $password = trim($object->getPassword()); $len = Mage::helper('core/string')->strlen($password); if ($len) { - if ($len < 6) { - Mage::throwException(Mage::helper('customer')->__('The password must have at least 6 characters. Leading or trailing spaces will be ignored.')); + $minPasswordLength = Mage::getModel('customer/customer')->getMinPasswordLength(); + if ($len < $minPasswordLength) { + Mage::throwException(Mage::helper('customer')->__( + 'The password must have at least %d characters. Leading or trailing spaces will be ignored.', + $minPasswordLength + )); } $object->setPasswordHash($object->hashPassword($password)); } diff --git app/code/core/Mage/Customer/etc/config.xml app/code/core/Mage/Customer/etc/config.xml index bbf408ec786..82ab7a2bcd7 100644 --- app/code/core/Mage/Customer/etc/config.xml +++ app/code/core/Mage/Customer/etc/config.xml @@ -533,6 +533,7 @@ customer_password_remind_email_template 2 1 + 7
2 @@ -593,6 +594,7 @@ T: {{var telephone}} 1 5 5 + 14 diff --git app/code/core/Mage/Customer/etc/system.xml app/code/core/Mage/Customer/etc/system.xml index 0341ea0bc1d..85e678815d0 100644 --- app/code/core/Mage/Customer/etc/system.xml +++ app/code/core/Mage/Customer/etc/system.xml @@ -333,6 +333,17 @@ 0 0 + + + Please enter a number 7 or greater in this field. + text + required-entry validate-digits validate-digits-range digits-range-7- + adminhtml/system_config_backend_passwordlength + 60 + 1 + 0 + 0 +
@@ -551,6 +562,17 @@ 1 1,3 + + + Please enter a number 7 or greater in this field. + text + required-entry validate-digits validate-digits-range digits-range-7- + adminhtml/system_config_backend_passwordlength + 170 + 1 + 0 + 0 + diff --git app/code/core/Mage/Dataflow/Model/Convert/Container/Abstract.php app/code/core/Mage/Dataflow/Model/Convert/Container/Abstract.php index 303b8cc8bbd..ce9592bc4d5 100644 --- app/code/core/Mage/Dataflow/Model/Convert/Container/Abstract.php +++ app/code/core/Mage/Dataflow/Model/Convert/Container/Abstract.php @@ -55,9 +55,7 @@ abstract class Mage_Dataflow_Model_Convert_Container_Abstract */ protected function isSerialized($data) { - $pattern = - '/^a:\d+:\{(i:\d+;|s:\d+:\".+\";|N;|O:\d+:\"\w+\":\d+:\{\w:\d+:)+|^O:\d+:\"\w+\":\d+:\{(s:\d+:\"|i:\d+;)/'; - return (is_string($data) && preg_match($pattern, $data)); + return Mage::helper('core/string')->isSerializedArrayOrObject($data); } public function getVar($key, $default=null) diff --git app/code/core/Mage/Dataflow/Model/Convert/Parser/Csv.php app/code/core/Mage/Dataflow/Model/Convert/Parser/Csv.php index 229293101d2..19676b8a8e7 100644 --- app/code/core/Mage/Dataflow/Model/Convert/Parser/Csv.php +++ app/code/core/Mage/Dataflow/Model/Convert/Parser/Csv.php @@ -71,6 +71,7 @@ class Mage_Dataflow_Model_Convert_Parser_Csv extends Mage_Dataflow_Model_Convert if (!method_exists($adapter, $adapterMethod)) { $message = Mage::helper('dataflow') ->__('Method "%s" not defined in adapter %s.', $adapterMethod, $adapterName); + $message = Mage::helper('dataflow')->escapeHtml($message); $this->addException($message, Mage_Dataflow_Model_Convert_Exception::FATAL); return $this; } diff --git app/code/core/Mage/Dataflow/Model/Convert/Parser/Xml/Excel.php app/code/core/Mage/Dataflow/Model/Convert/Parser/Xml/Excel.php index 09609636619..a064fd92b53 100644 --- app/code/core/Mage/Dataflow/Model/Convert/Parser/Xml/Excel.php +++ app/code/core/Mage/Dataflow/Model/Convert/Parser/Xml/Excel.php @@ -71,6 +71,7 @@ class Mage_Dataflow_Model_Convert_Parser_Xml_Excel extends Mage_Dataflow_Model_C if (!method_exists($adapter, $adapterMethod)) { $message = Mage::helper('dataflow') ->__('Method "%s" was not defined in adapter %s.', $adapterMethod, $adapterName); + $message = Mage::helper('dataflow')->escapeHtml($message); $this->addException($message, Mage_Dataflow_Model_Convert_Exception::FATAL); return $this; } diff --git app/code/core/Mage/Dataflow/Model/Profile.php app/code/core/Mage/Dataflow/Model/Profile.php index ec46c9f4cbf..9cc65e05f7f 100644 --- app/code/core/Mage/Dataflow/Model/Profile.php +++ app/code/core/Mage/Dataflow/Model/Profile.php @@ -57,6 +57,20 @@ class Mage_Dataflow_Model_Profile extends Mage_Core_Model_Abstract const DEFAULT_EXPORT_PATH = 'var/export'; const DEFAULT_EXPORT_FILENAME = 'export_'; + /** + * Product table permanent attributes + * + * @var array + */ + protected $_productTablePermanentAttributes = array('sku'); + + /** + * Customer table permanent attributes + * + * @var array + */ + protected $_customerTablePermanentAttributes = array('email', 'website'); + protected function _construct() { $this->_init('dataflow/profile'); @@ -151,6 +165,9 @@ class Mage_Dataflow_Model_Profile extends Mage_Core_Model_Abstract ->setProfileId($this->getId()) ->setActionCode($this->getOrigData('profile_id') ? 'update' : 'create') ->save(); + $csvParser = new Varien_File_Csv(); + $xmlParser = new DOMDocument(); + $newUploadedFilenames = array(); if (isset($_FILES['file_1']['tmp_name']) || isset($_FILES['file_2']['tmp_name']) || isset($_FILES['file_3']['tmp_name'])) { @@ -160,9 +177,58 @@ class Mage_Dataflow_Model_Profile extends Mage_Core_Model_Abstract $uploader->setAllowedExtensions(array('csv','xml')); $path = Mage::app()->getConfig()->getTempVarDir() . '/import/'; $uploader->save($path); - if ($uploadFile = $uploader->getUploadedFileName()) { + $uploadFile = $uploader->getUploadedFileName(); + + if ($_FILES['file_' . ($index + 1)]['type'] == "text/csv") { + $fileData = $csvParser->getData($path . $uploadFile); + $fileData = array_shift($fileData); + } else { + try { + $xmlParser->loadXML(file_get_contents($path . $uploadFile)); + $cells = $this->getNode($xmlParser, 'Worksheet')->item(0); + $cells = $this->getNode($cells, 'Row')->item(0); + $cells = $this->getNode($cells, 'Cell'); + $fileData = array(); + foreach ($cells as $cell) { + $fileData[] = $this->getNode($cell, 'Data')->item(0)->nodeValue; + } + } catch (Exception $e) { + foreach ($newUploadedFilenames as $k => $v) { + unlink($path . $v); + } + unlink($path . $uploadFile); + Mage::throwException( + Mage::helper('Dataflow')->__( + 'Upload failed. Wrong data format in file: %s.', + $uploadFile + ) + ); + } + } + + if ($this->_data['entity_type'] == 'customer') { + $attributes = $this->_customerTablePermanentAttributes; + } else { + $attributes = $this->_productTablePermanentAttributes; + } + $colsAbsent = array_diff($attributes, $fileData); + if ($colsAbsent) { + foreach ($newUploadedFilenames as $k => $v) { + unlink($path . $v); + } + unlink($path . $uploadFile); + Mage::throwException( + Mage::helper('Dataflow')->__( + 'Upload failed. Can not find required columns: %s in file %s.', + implode(', ', $colsAbsent), + $uploadFile + ) + ); + } + if ($uploadFile) { $newFilename = 'import-' . date('YmdHis') . '-' . ($index+1) . '_' . $uploadFile; rename($path . $uploadFile, $path . $newFilename); + $newUploadedFilenames[] = $newFilename; } } //BOM deleting for UTF files @@ -431,4 +497,20 @@ echo "" . $xml . ""; die;*/ return $this; } + + /** + * Get node from xml object + * + * @param object $xmlObject + * @param string $nodeName + * @return object + * @throws Exception + */ + protected function getNode($xmlObject, $nodeName) + { + if ($xmlObject != null) { + return $xmlObject->getElementsByTagName($nodeName); + } + Mage::throwException(Mage::helper('Dataflow')->__('Invalid node.')); + } } diff --git app/code/core/Mage/Eav/Model/Entity/Attribute/Backend/Abstract.php app/code/core/Mage/Eav/Model/Entity/Attribute/Backend/Abstract.php index 9a3ede59334..a88a0f80401 100644 --- app/code/core/Mage/Eav/Model/Entity/Attribute/Backend/Abstract.php +++ app/code/core/Mage/Eav/Model/Entity/Attribute/Backend/Abstract.php @@ -246,6 +246,15 @@ abstract class Mage_Eav_Model_Entity_Attribute_Backend_Abstract return false; } + //Validate serialized data + if (!Mage::helper('core/string')->validateSerializedObject($value)) { + $label = $this->getAttribute()->getFrontend()->getLabel(); + throw Mage::exception( + 'Mage_Eav', + Mage::helper('eav')->__('The value of attribute "%s" contains invalid data.', $label) + ); + } + if ($this->getAttribute()->getIsUnique() && !$this->getAttribute()->getIsRequired() && ($value == '' || $this->getAttribute()->isValueEmpty($value))) diff --git app/code/core/Mage/ImportExport/Model/Import/Adapter/Abstract.php app/code/core/Mage/ImportExport/Model/Import/Adapter/Abstract.php index bd560319e04..6b64f6c9c60 100644 --- app/code/core/Mage/ImportExport/Model/Import/Adapter/Abstract.php +++ app/code/core/Mage/ImportExport/Model/Import/Adapter/Abstract.php @@ -183,4 +183,14 @@ abstract class Mage_ImportExport_Model_Import_Adapter_Abstract implements Seekab { return $this; } + + /** + * Get the source path + * + * @return string + */ + public function getSource() + { + return $this->_source; + } } diff --git app/code/core/Mage/ImportExport/Model/Import/Entity/Abstract.php app/code/core/Mage/ImportExport/Model/Import/Entity/Abstract.php index 3a2ac46bce2..01b8089a4aa 100644 --- app/code/core/Mage/ImportExport/Model/Import/Entity/Abstract.php +++ app/code/core/Mage/ImportExport/Model/Import/Entity/Abstract.php @@ -669,6 +669,7 @@ abstract class Mage_ImportExport_Model_Import_Entity_Abstract if (!$this->_dataValidated) { // does all permanent columns exists? if (($colsAbsent = array_diff($this->_permanentAttributes, $this->_getSource()->getColNames()))) { + file_put_contents($this->_getSource()->getSource(), ""); Mage::throwException( Mage::helper('importexport')->__('Can not find required columns: %s', implode(', ', $colsAbsent)) ); diff --git app/code/core/Mage/Install/Block/Admin.php app/code/core/Mage/Install/Block/Admin.php index 295a6af3d8e..812c27a09bd 100644 --- app/code/core/Mage/Install/Block/Admin.php +++ app/code/core/Mage/Install/Block/Admin.php @@ -51,4 +51,14 @@ class Mage_Install_Block_Admin extends Mage_Install_Block_Abstract } return $data; } + + /** + * Retrieve minimum length of admin password + * + * @return int + */ + public function getMinAdminPasswordLength() + { + return Mage::getModel('admin/user')->getMinAdminPasswordLength(); + } } diff --git app/code/core/Mage/Install/etc/config.xml app/code/core/Mage/Install/etc/config.xml index 11536d03ccf..cdc5f56df7b 100644 --- app/code/core/Mage/Install/etc/config.xml +++ app/code/core/Mage/Install/etc/config.xml @@ -57,6 +57,13 @@ + + + + + + + diff --git app/code/core/Mage/Review/controllers/ProductController.php app/code/core/Mage/Review/controllers/ProductController.php index 6a4033fac94..19468df12dc 100644 --- app/code/core/Mage/Review/controllers/ProductController.php +++ app/code/core/Mage/Review/controllers/ProductController.php @@ -304,7 +304,17 @@ class Mage_Review_ProductController extends Mage_Core_Controller_Front_Action $this->getLayout()->helper('page/layout') ->applyTemplate($product->getPageLayout()); } - $update->addUpdate($product->getCustomLayoutUpdate()); + $customLayout = $product->getCustomLayoutUpdate(); + if ($customLayout) { + try { + if (!Mage::getModel('core/layout_validator')->isValid($customLayout)) { + $customLayout = ''; + } + } catch (Exception $e) { + $customLayout = ''; + } + } + $update->addUpdate($customLayout); $this->generateLayoutXml()->generateLayoutBlocks(); } diff --git app/code/core/Mage/Rss/etc/config.xml app/code/core/Mage/Rss/etc/config.xml index 02e0321ac36..1963093b510 100644 --- app/code/core/Mage/Rss/etc/config.xml +++ app/code/core/Mage/Rss/etc/config.xml @@ -123,4 +123,13 @@ + + + + + + + + + diff --git app/code/core/Mage/Widget/controllers/Adminhtml/Widget/InstanceController.php app/code/core/Mage/Widget/controllers/Adminhtml/Widget/InstanceController.php index 4722da93d8c..71033be1558 100644 --- app/code/core/Mage/Widget/controllers/Adminhtml/Widget/InstanceController.php +++ app/code/core/Mage/Widget/controllers/Adminhtml/Widget/InstanceController.php @@ -295,6 +295,17 @@ class Mage_Widget_Adminhtml_Widget_InstanceController extends Mage_Adminhtml_Con $this->setBody($templateChooser->toHtml()); } + /** + * Controller predispatch method + * + * @return Mage_Adminhtml_Controller_Action + */ + public function preDispatch() + { + $this->_setForcedFormKeyActions('delete'); + return parent::preDispatch(); + } + /** * Check is allowed access to action * diff --git app/code/core/Mage/Wishlist/Block/Abstract.php app/code/core/Mage/Wishlist/Block/Abstract.php index fd2b373d776..d4661be0f6f 100644 --- app/code/core/Mage/Wishlist/Block/Abstract.php +++ app/code/core/Mage/Wishlist/Block/Abstract.php @@ -168,7 +168,7 @@ abstract class Mage_Wishlist_Block_Abstract extends Mage_Catalog_Block_Product_A */ public function getItemRemoveUrl($item) { - return $this->_getHelper()->getRemoveUrl($item); + return $this->getItemRemoveUrlCustom($item); } /** @@ -179,7 +179,7 @@ abstract class Mage_Wishlist_Block_Abstract extends Mage_Catalog_Block_Product_A */ public function getItemAddToCartUrl($item) { - return $this->_getHelper()->getAddToCartUrl($item); + return $this->getItemAddToCartUrlCustom($item); } /** @@ -201,7 +201,7 @@ abstract class Mage_Wishlist_Block_Abstract extends Mage_Catalog_Block_Product_A */ public function getAddToWishlistUrl($product) { - return $this->_getHelper()->getAddUrl($product); + return $this->getAddToWishlistUrlCustom($product); } /** @@ -408,4 +408,49 @@ abstract class Mage_Wishlist_Block_Abstract extends Mage_Catalog_Block_Product_A } return parent::getProductUrl($product, $additional); } + + /** + * Retrieve URL for adding Product to wishlist with or without Form Key + * + * @param Mage_Catalog_Model_Product $product + * @param bool $addFormKey + * @return string + */ + public function getAddToWishlistUrlCustom($product, $addFormKey = true) + { + if (!$addFormKey) { + return $this->_getHelper()->getAddUrlWithCustomParams($product, array(), false); + } + return $this->_getHelper()->getAddUrl($product); + } + + /** + * Retrieve URL for Removing item from wishlist with or without Form Key + * + * @param Mage_Catalog_Model_Product|Mage_Wishlist_Model_Item $item + * @param bool $addFormKey + * @return string + */ + public function getItemRemoveUrlCustom($item, $addFormKey = true) + { + if (!$addFormKey) { + return $this->_getHelper()->getRemoveUrlCustom($item, false); + } + return $this->_getHelper()->getRemoveUrl($item); + } + + /** + * Retrieve Add Item to shopping cart URL with or without Form Key + * + * @param string|Mage_Catalog_Model_Product|Mage_Wishlist_Model_Item $item + * @param bool $addFormKey + * @return string + */ + public function getItemAddToCartUrlCustom($item, $addFormKey = true) + { + if (!$addFormKey) { + return $this->_getHelper()->getAddToCartUrlCustom($item, false); + } + return $this->_getHelper()->getAddToCartUrl($item); + } } diff --git app/code/core/Mage/Wishlist/Block/Customer/Wishlist/Item/Column/Cart.php app/code/core/Mage/Wishlist/Block/Customer/Wishlist/Item/Column/Cart.php index 3bd53bc4ab6..026f8d3e163 100644 --- app/code/core/Mage/Wishlist/Block/Customer/Wishlist/Item/Column/Cart.php +++ app/code/core/Mage/Wishlist/Block/Customer/Wishlist/Item/Column/Cart.php @@ -54,7 +54,16 @@ class Mage_Wishlist_Block_Customer_Wishlist_Item_Column_Cart extends Mage_Wishli { $js = " function addWItemToCart(itemId) { - var url = '" . $this->getItemAddToCartUrl('%item%') . "'; + addWItemToCartCustom(itemId, true) + } + + function addWItemToCartCustom(itemId, sendGet) { + var url = ''; + if (sendGet) { + url = '" . $this->getItemAddToCartUrl('%item%') . "'; + } else { + url = '" . $this->getItemAddToCartUrlCustom('%item%', false) . "'; + } url = url.gsub('%item%', itemId); var form = $('wishlist-view-form'); if (form) { @@ -64,7 +73,11 @@ class Mage_Wishlist_Block_Customer_Wishlist_Item_Column_Cart extends Mage_Wishli url += separator + input.name + '=' + encodeURIComponent(input.value); } } - setLocation(url); + if (sendGet) { + setLocation(url); + } else { + customFormSubmit(url, '" . json_encode(array('form_key' => $this->getFormKey())) . "', 'post'); + } } "; diff --git app/code/core/Mage/Wishlist/Block/Item/Configure.php app/code/core/Mage/Wishlist/Block/Item/Configure.php index daac55a328d..19160fc2512 100644 --- app/code/core/Mage/Wishlist/Block/Item/Configure.php +++ app/code/core/Mage/Wishlist/Block/Item/Configure.php @@ -65,7 +65,9 @@ class Mage_Wishlist_Block_Item_Configure extends Mage_Core_Block_Template $block = $this->getLayout()->getBlock('product.info'); if ($block) { $url = Mage::helper('wishlist')->getAddToCartUrl($this->getWishlistItem()); + $postUrl = Mage::helper('wishlist')->getAddToCartUrlCustom($this->getWishlistItem(), false); $block->setCustomAddToCartUrl($url); + $block->setCustomAddToCartPostUrl($postUrl); } return parent::_prepareLayout(); diff --git app/code/core/Mage/Wishlist/Block/Share/Email/Items.php app/code/core/Mage/Wishlist/Block/Share/Email/Items.php index 7d5822e0b56..f140d4573bb 100644 --- app/code/core/Mage/Wishlist/Block/Share/Email/Items.php +++ app/code/core/Mage/Wishlist/Block/Share/Email/Items.php @@ -66,9 +66,7 @@ class Mage_Wishlist_Block_Share_Email_Items extends Mage_Wishlist_Block_Abstract */ public function getAddToCartUrl($product, $additional = array()) { - $additional['nocookie'] = 1; - $additional['_store_to_url'] = true; - return parent::getAddToCartUrl($product, $additional); + return $this->getAddToCartUrlCustom($product, $additional); } /** @@ -85,4 +83,19 @@ class Mage_Wishlist_Block_Share_Email_Items extends Mage_Wishlist_Block_Abstract } return $hasDescription; } + + /** + * Retrieve URL for add product to shopping cart with or without Form Key + * + * @param Mage_Catalog_Model_Product $product + * @param array $additional + * @param bool $addFormKey + * @return string + */ + public function getAddToCartUrlCustom($product, $additional = array(), $addFormKey = true) + { + $additional['nocookie'] = 1; + $additional['_store_to_url'] = true; + return parent::getAddToCartUrlCustom($product, $additional, $addFormKey); + } } diff --git app/code/core/Mage/Wishlist/Helper/Data.php app/code/core/Mage/Wishlist/Helper/Data.php index acae22f3c6d..e478a857646 100644 --- app/code/core/Mage/Wishlist/Helper/Data.php +++ app/code/core/Mage/Wishlist/Helper/Data.php @@ -273,12 +273,7 @@ class Mage_Wishlist_Helper_Data extends Mage_Core_Helper_Abstract */ public function getRemoveUrl($item) { - return $this->_getUrl('wishlist/index/remove', - array( - 'item' => $item->getWishlistItemId(), - Mage_Core_Model_Url::FORM_KEY => $this->_getSingletonModel('core/session')->getFormKey() - ) - ); + return $this->getRemoveUrlCustom($item); } /** @@ -352,21 +347,7 @@ class Mage_Wishlist_Helper_Data extends Mage_Core_Helper_Abstract */ public function getAddUrlWithParams($item, array $params = array()) { - $productId = null; - if ($item instanceof Mage_Catalog_Model_Product) { - $productId = $item->getEntityId(); - } - if ($item instanceof Mage_Wishlist_Model_Item) { - $productId = $item->getProductId(); - } - - if ($productId) { - $params['product'] = $productId; - $params[Mage_Core_Model_Url::FORM_KEY] = $this->_getSingletonModel('core/session')->getFormKey(); - return $this->_getUrlStore($item)->getUrl('wishlist/index/add', $params); - } - - return false; + return $this->getAddUrlWithCustomParams($item, $params); } /** @@ -377,19 +358,7 @@ class Mage_Wishlist_Helper_Data extends Mage_Core_Helper_Abstract */ public function getAddToCartUrl($item) { - $continueUrl = $this->_getHelperInstance('core')->urlEncode( - $this->_getUrl('*/*/*', array( - '_current' => true, - '_use_rewrite' => true, - '_store_to_url' => true, - )) - ); - $params = array( - 'item' => is_string($item) ? $item : $item->getWishlistItemId(), - Mage_Core_Controller_Front_Action::PARAM_NAME_URL_ENCODED => $continueUrl, - Mage_Core_Model_Url::FORM_KEY => $this->_getSingletonModel('core/session')->getFormKey() - ); - return $this->_getUrlStore($item)->getUrl('wishlist/index/cart', $params); + return $this->getAddToCartUrlCustom($item); } /** @@ -592,4 +561,78 @@ class Mage_Wishlist_Helper_Data extends Mage_Core_Helper_Abstract { return Mage::getStoreConfig(self::XML_PATH_WISHLIST_LINK_USE_QTY); } + + /** + * Retrieve url for adding product to wishlist with params with or without Form Key + * + * @param Mage_Catalog_Model_Product|Mage_Wishlist_Model_Item $item + * @param array $params + * @param bool $addFormKey + * @return string|bool + */ + public function getAddUrlWithCustomParams($item, array $params = array(), $addFormKey = true) + { + $productId = null; + if ($item instanceof Mage_Catalog_Model_Product) { + $productId = $item->getEntityId(); + } + if ($item instanceof Mage_Wishlist_Model_Item) { + $productId = $item->getProductId(); + } + + if ($productId) { + $params['product'] = $productId; + if ($addFormKey) { + $params[Mage_Core_Model_Url::FORM_KEY] = $this->_getSingletonModel('core/session')->getFormKey(); + } + return $this->_getUrlStore($item)->getUrl('wishlist/index/add', $params); + } + + return false; + } + + /** + * Retrieve URL for removing item from wishlist with params with or without Form Key + * + * @param Mage_Catalog_Model_Product|Mage_Wishlist_Model_Item $item + * @param bool $addFormKey + * @return string + */ + public function getRemoveUrlCustom($item, $addFormKey = true) + { + $params = array( + 'item' => $item->getWishlistItemId() + ); + if ($addFormKey) { + $params[Mage_Core_Model_Url::FORM_KEY] = $this->_getSingletonModel('core/session')->getFormKey(); + } + + return $this->_getUrl('wishlist/index/remove', $params); + } + + /** + * Retrieve URL for adding item to shopping cart with or without Form Key + * + * @param string|Mage_Catalog_Model_Product|Mage_Wishlist_Model_Item $item + * @param bool $addFormKey + * @return string + */ + public function getAddToCartUrlCustom($item, $addFormKey = true) + { + $continueUrl = $this->_getHelperInstance('core')->urlEncode( + $this->_getUrl('*/*/*', array( + '_current' => true, + '_use_rewrite' => true, + '_store_to_url' => true, + )) + ); + $params = array( + 'item' => is_string($item) ? $item : $item->getWishlistItemId(), + Mage_Core_Controller_Front_Action::PARAM_NAME_URL_ENCODED => $continueUrl, + ); + if ($addFormKey) { + $params[Mage_Core_Model_Url::FORM_KEY] = $this->_getSingletonModel('core/session')->getFormKey(); + } + return $this->_getUrlStore($item)->getUrl('wishlist/index/cart', $params); + } } diff --git app/code/core/Mage/XmlConnect/Helper/Translate.php app/code/core/Mage/XmlConnect/Helper/Translate.php index 9b4edc8a6da..800ad416cbe 100644 --- app/code/core/Mage/XmlConnect/Helper/Translate.php +++ app/code/core/Mage/XmlConnect/Helper/Translate.php @@ -328,7 +328,8 @@ class Mage_XmlConnect_Helper_Translate extends Mage_Core_Helper_Abstract 'OtherAmount' => $this->__('Other amount'), 'OutOfStock' => $this->__('Out of Stock'), 'ParsingError' => $this->__('Error while reading remote data'), - 'PasswordLength' => $this->__('The minimum password length is 6'), + 'PasswordLength' => $this->__('The minimum password length is ') + . Mage::getModel('customer/customer')->getMinPasswordLength(), 'PayPalCheckout' => $this->__('PayPal Checkout'), 'PayPalText' => $this->__('PayPal'), 'PaymentBridgeServiceErrorMessage' => $this->__('Unknown Payment Bridge Error'), diff --git app/design/adminhtml/default/default/template/resetforgottenpassword.phtml app/design/adminhtml/default/default/template/resetforgottenpassword.phtml index 144f6124266..2bfa951f9b4 100644 --- app/design/adminhtml/default/default/template/resetforgottenpassword.phtml +++ app/design/adminhtml/default/default/template/resetforgottenpassword.phtml @@ -50,12 +50,21 @@
getMessagesBlock()->toHtml(); ?>
-
+

- + +

+ + __('Password must be at least of %d characters.', $minAdminPasswordLength); ?> + +

diff --git app/design/frontend/base/default/template/bundle/catalog/product/view/option_tierprices.phtml app/design/frontend/base/default/template/bundle/catalog/product/view/option_tierprices.phtml index c670ac97422..94d4a289b78 100644 --- app/design/frontend/base/default/template/bundle/catalog/product/view/option_tierprices.phtml +++ app/design/frontend/base/default/template/bundle/catalog/product/view/option_tierprices.phtml @@ -197,9 +197,9 @@ if (Mage::helper('weee')->typeOfDisplay($_product, array(1,2,4))) { __('Click for price'); ?> diff --git app/design/frontend/base/default/template/catalog/product/price_msrp_noform.phtml app/design/frontend/base/default/template/catalog/product/price_msrp_noform.phtml index 38498b14477..4b610ce8a4a 100644 --- app/design/frontend/base/default/template/catalog/product/price_msrp_noform.phtml +++ app/design/frontend/base/default/template/catalog/product/price_msrp_noform.phtml @@ -48,7 +48,7 @@ diff --git app/design/frontend/rwd/default/template/catalog/product/compare/list.phtml app/design/frontend/rwd/default/template/catalog/product/compare/list.phtml index 2080ed58144..0a833662678 100644 --- app/design/frontend/rwd/default/template/catalog/product/compare/list.phtml +++ app/design/frontend/rwd/default/template/catalog/product/compare/list.phtml @@ -30,6 +30,7 @@ __('Print This Page') ?>
getItems()->count() ?> +escapeHtml(json_encode(array('form_key' => $this->getFormKey()))); ?> @@ -75,13 +76,30 @@ @@ -128,13 +146,32 @@ diff --git app/design/frontend/rwd/default/template/catalog/product/list.phtml app/design/frontend/rwd/default/template/catalog/product/list.phtml index 4c5a44c67e2..aba1f8d51bf 100644 --- app/design/frontend/rwd/default/template/catalog/product/list.phtml +++ app/design/frontend/rwd/default/template/catalog/product/list.phtml @@ -35,6 +35,7 @@ getLoadedProductCollection(); $_helper = $this->helper('catalog/output'); + $_params = $this->escapeHtml(json_encode(array('form_key' => $this->getFormKey()))); ?> count()): ?>

__('There are no products matching the selection.') ?>

@@ -87,7 +88,17 @@
canConfigure() && $_product->isSaleable()): ?> -

+

+ +

getStockItem() && $_product->getStockItem()->getIsInStock()): ?>

__('View Details') ?>

@@ -95,10 +106,26 @@
@@ -150,7 +177,15 @@
canConfigure() && $_product->isSaleable()): ?> - + getStockItem() && $_product->getStockItem()->getIsInStock()): ?> __('View Details') ?> @@ -158,10 +193,26 @@
diff --git app/design/frontend/rwd/default/template/catalog/product/list/related.phtml app/design/frontend/rwd/default/template/catalog/product/list/related.phtml index 5707274e051..a9902b5827e 100644 --- app/design/frontend/rwd/default/template/catalog/product/list/related.phtml +++ app/design/frontend/rwd/default/template/catalog/product/list/related.phtml @@ -45,7 +45,14 @@

escapeHtml($_item->getName()) ?>

getPriceHtml($_item, true, '-related') ?> helper('wishlist')->isAllow()) : ?> - __('Add to Wishlist') ?> + + __('Add to Wishlist') ?> + diff --git app/design/frontend/rwd/default/template/catalog/product/view.phtml app/design/frontend/rwd/default/template/catalog/product/view.phtml index ffd2b6e42b0..fa4eefa848a 100644 --- app/design/frontend/rwd/default/template/catalog/product/view.phtml +++ app/design/frontend/rwd/default/template/catalog/product/view.phtml @@ -39,7 +39,10 @@
getMessagesBlock()->toHtml() ?>
-
getOptions()): ?> enctype="multipart/form-data"> + getOptions()): ?> enctype="multipart/form-data" > getBlockHtml('formkey') ?>
diff --git app/design/frontend/rwd/default/template/catalog/product/view/addto.phtml app/design/frontend/rwd/default/template/catalog/product/view/addto.phtml index 91e62cc65f7..818e61c4683 100644 --- app/design/frontend/rwd/default/template/catalog/product/view/addto.phtml +++ app/design/frontend/rwd/default/template/catalog/product/view/addto.phtml @@ -26,17 +26,31 @@ ?> getProduct(); ?> -helper('wishlist')->getAddUrl($_product); ?> +helper('wishlist')->getAddUrlWithCustomParams($_product, array(), false); ?> +escapeHtml(json_encode(array('form_key' => $this->getFormKey()))); ?> diff --git app/design/frontend/rwd/default/template/catalog/product/view/sharing.phtml app/design/frontend/rwd/default/template/catalog/product/view/sharing.phtml index 637db026824..45dc3dffbe8 100644 --- app/design/frontend/rwd/default/template/catalog/product/view/sharing.phtml +++ app/design/frontend/rwd/default/template/catalog/product/view/sharing.phtml @@ -26,7 +26,7 @@ ?> getProduct(); ?> -helper('wishlist')->getAddUrl($_product); ?> +helper('wishlist')->getAddUrlWithCustomParams($_product, array(), false); ?>
diff --git app/design/frontend/rwd/default/template/checkout/cart/shipping.phtml app/design/frontend/rwd/default/template/checkout/cart/shipping.phtml index e293822471a..da0f873af88 100644 --- app/design/frontend/rwd/default/template/checkout/cart/shipping.phtml +++ app/design/frontend/rwd/default/template/checkout/cart/shipping.phtml @@ -87,7 +87,7 @@ getEstimateRates())): ?> - +
$_rates): ?>
escapeHtml($this->getCarrierName($code)) ?>
diff --git app/design/frontend/rwd/default/template/checkout/cart/sidebar/default.phtml app/design/frontend/rwd/default/template/checkout/cart/sidebar/default.phtml index 9249ea8568a..673bf2fa1f1 100644 --- app/design/frontend/rwd/default/template/checkout/cart/sidebar/default.phtml +++ app/design/frontend/rwd/default/template/checkout/cart/sidebar/default.phtml @@ -36,7 +36,14 @@ <?php echo $this->escapeHtml($this->getProductName()) ?>
- __('Remove This Item') ?> + + __('Remove This Item') ?> +

hasProductUrl()): ?>escapeHtml($this->getProductName()) ?>hasProductUrl()): ?>

__('Edit item')?> diff --git app/design/frontend/rwd/default/template/checkout/onepage/review/info.phtml app/design/frontend/rwd/default/template/checkout/onepage/review/info.phtml index a6b04b08c5b..14fb9fd2090 100644 --- app/design/frontend/rwd/default/template/checkout/onepage/review/info.phtml +++ app/design/frontend/rwd/default/template/checkout/onepage/review/info.phtml @@ -79,7 +79,7 @@
diff --git app/design/frontend/rwd/default/template/customer/form/changepassword.phtml app/design/frontend/rwd/default/template/customer/form/changepassword.phtml index bd81ba8a4e0..5475554aa45 100644 --- app/design/frontend/rwd/default/template/customer/form/changepassword.phtml +++ app/design/frontend/rwd/default/template/customer/form/changepassword.phtml @@ -43,7 +43,15 @@
- + getCustomer()->getMinPasswordLength(), Mage_Core_Model_App::ABSOLUTE_MIN_PASSWORD_LENGTH); ?> + +

+ __('The minimum password length is %s', $minPasswordLength) ?> +

diff --git app/design/frontend/rwd/default/template/customer/form/edit.phtml app/design/frontend/rwd/default/template/customer/form/edit.phtml index 11b41c8c46e..c8ad1615a4e 100644 --- app/design/frontend/rwd/default/template/customer/form/edit.phtml +++ app/design/frontend/rwd/default/template/customer/form/edit.phtml @@ -75,7 +75,15 @@
- + getCustomer()->getMinPasswordLength(); ?> + +

+ __('The minimum password length is %s', $minPasswordLength) ?> +

diff --git app/design/frontend/rwd/default/template/customer/form/resetforgottenpassword.phtml app/design/frontend/rwd/default/template/customer/form/resetforgottenpassword.phtml index 03fe520574e..894c4deb1cd 100644 --- app/design/frontend/rwd/default/template/customer/form/resetforgottenpassword.phtml +++ app/design/frontend/rwd/default/template/customer/form/resetforgottenpassword.phtml @@ -36,7 +36,14 @@
- + getMinPasswordLength(); ?> + +

+ __('The minimum password length is %s', $minPasswordLength); ?> +

diff --git app/design/frontend/rwd/default/template/downloadable/checkout/cart/item/default.phtml app/design/frontend/rwd/default/template/downloadable/checkout/cart/item/default.phtml index db1026bccaf..7a65d464e65 100644 --- app/design/frontend/rwd/default/template/downloadable/checkout/cart/item/default.phtml +++ app/design/frontend/rwd/default/template/downloadable/checkout/cart/item/default.phtml @@ -28,6 +28,8 @@ $_item = $this->getItem(); $isVisibleProduct = $_item->getProduct()->isVisibleInSiteVisibility(); $canApplyMsrp = Mage::helper('catalog')->canApplyMsrp($_item->getProduct(), Mage_Catalog_Model_Product_Attribute_Source_Msrp_Type::TYPE_BEFORE_ORDER_CONFIRM); +$_params = $this->escapeHtml(json_encode(array('form_key' => $this->getFormKey()))); +$_deleteUrl = $this->getDeleteUrlCustom(false); ?>
- + diff --git app/design/frontend/rwd/default/template/email/catalog/product/list.phtml app/design/frontend/rwd/default/template/email/catalog/product/list.phtml index 2a572c8eee5..4acb77b0ed1 100644 --- app/design/frontend/rwd/default/template/email/catalog/product/list.phtml +++ app/design/frontend/rwd/default/template/email/catalog/product/list.phtml @@ -35,6 +35,7 @@ getLoadedProductCollection(); $_helper = $this->helper('catalog/output'); +$_params = $this->escapeHtml(json_encode(array('form_key' => $this->getFormKey()))); ?> count()): ?>

__('There are no products matching the selection.') ?>

@@ -87,7 +88,17 @@ $_helper = $this->helper('catalog/output');
canConfigure() && $_product->isSaleable()): ?> -

+

+ +

getStockItem() && $_product->getStockItem()->getIsInStock()): ?>

__('View Details') ?>

@@ -95,10 +106,24 @@ $_helper = $this->helper('catalog/output');
@@ -150,7 +175,15 @@ $_helper = $this->helper('catalog/output');
canConfigure() && $_product->isSaleable()): ?> - + getStockItem() && $_product->getStockItem()->getIsInStock()): ?> __('View Details') ?> @@ -158,10 +191,26 @@ $_helper = $this->helper('catalog/output');
diff --git app/design/frontend/rwd/default/template/persistent/checkout/onepage/billing.phtml app/design/frontend/rwd/default/template/persistent/checkout/onepage/billing.phtml index de5e82eccd5..0d9a24ef9e0 100644 --- app/design/frontend/rwd/default/template/persistent/checkout/onepage/billing.phtml +++ app/design/frontend/rwd/default/template/persistent/checkout/onepage/billing.phtml @@ -160,7 +160,15 @@
- + getQuote()->getCustomer()->getMinPasswordLength(); ?> + +

+ __('The minimum password length is %s', $minPasswordLength) ?> +

diff --git app/design/frontend/rwd/default/template/persistent/checkout/onepage/login.phtml app/design/frontend/rwd/default/template/persistent/checkout/onepage/login.phtml index c0d86f47925..5c13eb71b87 100644 --- app/design/frontend/rwd/default/template/persistent/checkout/onepage/login.phtml +++ app/design/frontend/rwd/default/template/persistent/checkout/onepage/login.phtml @@ -102,7 +102,7 @@
  • - +
  • diff --git app/design/frontend/rwd/default/template/persistent/customer/form/login.phtml app/design/frontend/rwd/default/template/persistent/customer/form/login.phtml index 4b4a4966494..02df877586a 100644 --- app/design/frontend/rwd/default/template/persistent/customer/form/login.phtml +++ app/design/frontend/rwd/default/template/persistent/customer/form/login.phtml @@ -76,7 +76,7 @@
  • - +
  • getChildHtml('form.additional.info'); ?> diff --git app/design/frontend/rwd/default/template/persistent/customer/form/register.phtml app/design/frontend/rwd/default/template/persistent/customer/form/register.phtml index 9f825ff1192..50d4034399c 100644 --- app/design/frontend/rwd/default/template/persistent/customer/form/register.phtml +++ app/design/frontend/rwd/default/template/persistent/customer/form/register.phtml @@ -147,7 +147,15 @@
    - + getMinPasswordLength(); ?> + +

    + __('The minimum password length is %s', $minPasswordLength) ?> +

    diff --git app/design/frontend/rwd/default/template/reports/widget/compared/content/compared_grid.phtml app/design/frontend/rwd/default/template/reports/widget/compared/content/compared_grid.phtml index fa81f1b25c9..6fb9a85a99d 100644 --- app/design/frontend/rwd/default/template/reports/widget/compared/content/compared_grid.phtml +++ app/design/frontend/rwd/default/template/reports/widget/compared/content/compared_grid.phtml @@ -31,6 +31,7 @@
    getColumnCount(); ?> + escapeHtml(json_encode(array('form_key' => $this->getFormKey()))); ?>
      @@ -45,16 +46,39 @@ getReviewsSummaryHtml($_product, 'short') ?>
      isSaleable()): ?> - +

      __('Out of stock') ?>

      diff --git app/design/frontend/rwd/default/template/reports/widget/viewed/content/viewed_grid.phtml app/design/frontend/rwd/default/template/reports/widget/viewed/content/viewed_grid.phtml index 8f62cc60d7d..c08a9947df9 100644 --- app/design/frontend/rwd/default/template/reports/widget/viewed/content/viewed_grid.phtml +++ app/design/frontend/rwd/default/template/reports/widget/viewed/content/viewed_grid.phtml @@ -36,6 +36,7 @@
    getColumnCount(); ?> + escapeHtml(json_encode(array('form_key' => $this->getFormKey()))); ?>
    • @@ -49,16 +50,40 @@ getReviewsSummaryHtml($_product, 'short') ?>
      isSaleable()): ?> - +

      __('Out of stock') ?>

      diff --git app/design/frontend/rwd/default/template/wishlist/item/column/cart.phtml app/design/frontend/rwd/default/template/wishlist/item/column/cart.phtml index d80e31589ce..c5f0e04fbf3 100644 --- app/design/frontend/rwd/default/template/wishlist/item/column/cart.phtml +++ app/design/frontend/rwd/default/template/wishlist/item/column/cart.phtml @@ -34,7 +34,12 @@ $options = $this->getChild('customer.wishlist.item.options') ?>
      isSaleable()): ?> - + getIsSalable()): ?>

      diff --git app/design/frontend/rwd/default/template/wishlist/shared.phtml app/design/frontend/rwd/default/template/wishlist/shared.phtml index 738dd2c099b..89471988e8f 100644 --- app/design/frontend/rwd/default/template/wishlist/shared.phtml +++ app/design/frontend/rwd/default/template/wishlist/shared.phtml @@ -45,6 +45,7 @@

    + escapeHtml(json_encode(array('form_key' => $this->getFormKey()))); ?> getWishlistItems() as $item): ?> getProduct(); @@ -64,7 +65,16 @@ -

    __('Add to Wishlist') ?>

    +

    + getAddToWishlistUrlCustom($item, false); ?> + + __('Add to Wishlist') ?> + +

    diff --git app/design/frontend/rwd/default/template/wishlist/sidebar.phtml app/design/frontend/rwd/default/template/wishlist/sidebar.phtml index 045c914cb08..8ae2247ef32 100644 --- app/design/frontend/rwd/default/template/wishlist/sidebar.phtml +++ app/design/frontend/rwd/default/template/wishlist/sidebar.phtml @@ -34,15 +34,27 @@

    __('Last Added Items') ?>

    hasWishlistItems()): ?>
      - getWishlistItems() as $_item): ?> + getWishlistItems() as $_item): ?> getProduct(); ?> + escapeHtml(json_encode(array('form_key' => $this->getFormKey()))); ?>
    1. <?php echo $this->escapeHtml($product->getName()) ?>
      - __('Remove This Item') ?> + + __('Remove This Item') ?> +

      escapeHtml($product->getName()) ?>

      isSaleable() && $product->isVisibleInSiteVisibility()): ?> - __('Add to Cart') ?> + + __('Add to Cart') ?> + getPriceHtml($product, false, '-wishlist') ?>
      diff --git app/design/install/default/default/template/install/create_admin.phtml app/design/install/default/default/template/install/create_admin.phtml index f8b7a911977..730c25a75db 100644 --- app/design/install/default/default/template/install/create_admin.phtml +++ app/design/install/default/default/template/install/create_admin.phtml @@ -68,7 +68,18 @@
      - + getMinAdminPasswordLength(); ?> + +

      + + __('Password must be at least of %d characters.', $minAdminPasswordLength) ?> + +

    isSaleable()): ?> -

    +

    __('Out of stock') ?>

    helper('wishlist')->isAllow()) : ?> + getAddToWishlistUrlCustom($_item, false); ?>
    getPriceHtml($_item, true, '-compare-list-bottom') ?> isSaleable()): ?> -

    +

    + +

    __('Out of stock') ?>

    helper('wishlist')->isAllow()) : ?> + getAddToWishlistUrlCustom($_item, false); ?>
    @@ -56,7 +58,12 @@ $canApplyMsrp = Mage::helper('catalog')->canApplyMsrp($_item->getProduct(), Mage - __('Remove Item') ?> + + __('Remove Item') ?> +

    hasProductUrl()):?> @@ -325,7 +332,12 @@ $canApplyMsrp = Mage::helper('catalog')->canApplyMsrp($_item->getProduct(), Mage

    - __('Remove Item') ?> + + __('Remove Item') ?> +
    canApplyMsrp($_item->getProduct(), Mage - __('Remove Item') ?> + + __('Remove Item') ?> +

    escapeHtml($this->getProductName()) ?>

    @@ -341,6 +348,12 @@ $canApplyMsrp = Mage::helper('catalog')->canApplyMsrp($_item->getProduct(), Mage
    __('Remove Item') ?> + + __('Remove Item') ?> + +