diff --git a/STATUS.txt b/STATUS.txt deleted file mode 100644 index da8753d8a6..0000000000 --- a/STATUS.txt +++ /dev/null @@ -1,235 +0,0 @@ -This file tracks the status of Magento in the 1.2.x branch. - -FIXED BUGS: - - #6341: Duble subject line in e-mail - #7162: Wrong div class used in 'mini compared products box - #7400: In order view (admin panel) statuses history is different in tabs 'Information' and 'Comments History' - #7423: Cart Rules - Condition Limit Error - #7472: Invoices Report - #7612: Products are displayed in categories they are not included in - #7636: Catalog Product Attribute -> Catalog Input Type -> Dropdown - #8020: Custom catalog attributes created as "price" not displaying correctly - #8159: One page checkout :: doesn't work when inline translation was enabled - #8366: Not possible to translate tax identifier for two store views - #8411: (assign users to role) - #8413: Mass Delete through product update screen does not work - #8439: The checkout-process-page has no pagetitle - #8452: Layout Update Problem (Mage_Core_Model_Config) - #8492: Custom Options percentage Price Type: price rounded off unwantedly - #8503: Bundle products and decimal places in options quantity - #8523: Analytics does not show revenue with configurable products - #8573: lifetime sale incorrect when refunding order with discount code applied - #8595: Many numeric-only searches in Admin/Autocomplete - #8657: Spelling mistake in error msg - "Selected currency code () is not compatabile with PayPal" - #8674: User doesn't subscribed to newsletter. - #8726: Mage_Core_Model_Resource_Setup::getAllAttributeSetIds() belongs in another class - #8762: Filter settings on Sales - Orders not saved - #8770: [MAC, Safari] Unable to create new order in the admin with new customer creating & #8771: [MAC, Safari] Unable to create new order in the admin - #8784: Send product to a friend not under store configuration - #8803: Remove "Yes, No, Any" dropdown filter on Google Base Items - #8893: Trace error after clicking button "Search" - #8896: Applying unable coupons in the empty shopping cart - #8898: Free Shipping: 'For matching items only' cart rule doesn't work with UPS XML type method - #8903: SQL error when sorting Online Customers by Type attribute - #8925: Locale settings not applied after installation - #8928: Unable to create rule for Not logged in customer. - #8943: Import is not working in Safari - #8966: Google Base API - Mass Insert / Update -> CAPTCHA challenge issued - #8968: Category save process is very slow for big catalog - #8974: Content type validation - #8977: Google Analytics reports wrong URL when URL has no query string OR store resides in subfolder... - #8980: Shopping cart discount error - #8992: Mage_Sitemap / Varien_Io_File Bug - Destination not writeable error - #8993: 'No Data Found' for Web Site - #8995: Search does not return correct URL key for additional store view (e.g. 2nd language) - #9109: Sales Report disregards currency rates - #9135: Advanced search by price doesn't work at all - #9139: Admin: menu items not readable when images are disabled - #9166: Unable to add image to all types of product - #9167: AJAX will freeze during 'quick simple product creation' - #9171: Product's table doesn't hide after select products for adding SKU - #9172: Free Shipping: 'For matching items only' cart rule doesn't work with DHL type method - #9173: Calendar's button doesn't work in rules - #9195: [admin - reports - sales - tax] - no data - #9207: Field country is not marked as required - #9208: Unable to add bundle items to bundle product - #9228: cart error after product delete - #9248: On admin page, search function does not work - #9250: Import doesn't work - #9278: Peruvian Nuevo Sol Shown as PES (Peruvian Sol) - #9279: Catalog price rules do not apply when attribute selected has Catalog Input Type for Store Owner ='Multiple Select' - #9296: Customer DOB saved not correctly - #9324: Bad counting products - #9326: Verification in "Contact Us" - #9348: Sales Tax Reports Give False Results (No Results) - #9354: Date Format - #9358: Unable add products to Google Base after filtering - #9359: Google Analytics Revenue Not Working - #9375: Fatal error: Call to a member function getItemsCollection() in Address.php - #9389: SQL-error while creating custom option forproduct - #9390: In "Advanced Search" all text is not displayed - #9392: The field is too broad insert text - #9440: Error subscription to newsletter - #9452: Email Reply Address - #9468: The same group name in an attribute set can be created but it can NOT be saved - #9470: Gift message is not moved over on an order edit - #9479: Reorder / shipping method price doesn't displayed in the "Order Totals" area - #9481: Broken design of the Expiration Date field for CC payment method - #9492: Dataflow export doesn't recognize absolute path - #9493: Buggy Sorting in Manage Tax Rates - Mantis - #9505: Missing echo statement in blank/default/template/shipping/tracking/popup.phtml - #9517: Impossible to set custom admin theme in configuration - #9536: User permissions - Manage Attributes setup - #9540: Google Base Adding SID to urls in multi domain environmnet - #9544: Zero tax total folding/unfolding - #9556: Fatal error during Store View creating - #9566: table rate shipping uploading csv broken - #9596: Store-specific payment method name not in order email - #9611: Not correct message, when you remove the product. - #9619: On front-end Serch is not working - #9622: Unable to add Configurable product to the shopping cart - #9639: Design crushing and SQL-error in admin Dashboard - #9649: Fatal error after reordering orders that contains gift message - #9651: Total revenu always 0 on Google Analytics - #9657: Email to a friend -> User can send more than 5 emails in an hour - #9659: Email to a Friend -> "Add Recipient" button doesn't work - #9660: newsletter subscribers: "Select All" working as select visible - #9665: Export action on Manage Customers and Newsletter Subscribers exports only visible page content - #9683: Orders: Function "Move to shopping cart" does not work. - #9684: Orders: Action "Hold" leads to fatal error. - #9685: No tax data in Reports - Sales - Tax - #9688: Incorrect update qty of the bundle product in the shopping cart - #9695: Manage Attribute Sets: Does not create new group - #9696: Unable to assign existing products to any web sites - #9697: Enable/Disable status works incorrect - #9699: Blank theme :: Pay Pal's Review page :: button doesn't work + products names doesn't shows - #9700: Search synonym does not work - #9707: Customers->Manage Customers->*user* - orders with DP doesn't displayed - #9708: Manage Attribute Sets: Error when creating and deleting groups - #9711: Google checkout are returning Comments History with HTML tags - #9712: Parameter "Maximum Package Weight ", leads to error 404. - #9716: Creating of Bundle Product -> SQLSTATE error - #9717: "Shipment email not sent" status does not change when you send a letter. - #9738: Downloadable product + Tax Rules = error 404 - #9742: Notice on products sitemap - #9743: Wrong count of related products, upsells and crosssells in admin - #9760: Free Shipping : 'For matching items only' incorrect works with USPS + FedEx method - - Fixed Bundle with custom options final price calculation - Fixed CatalogSearch events - Fixed EAV attribute save bug - Fixed EAV use joinAttribute method in conditions addAttributeToFilter method - Fixed MySQL 4.1 bug with NO_AUTO_VALUE_ON_ZERO mode and ALTER TABLE command - Fixed Online customers - Fixed REQUEST_URI for GA - Fixed Varieb_Db_Select::resetJoinLeft (find tables in conditions) - Fixed Varien_Data_Collection_Db::getSelectCountSql - Fixed _joinAttributeToSelect for abstract catalog collection (using attribute in select result and filter condition) - Fixed adding product to shopping cart - Fixed admin notification window block ACL - Fixed autobinding unescaped SQL variables - Fixed bug with categories tree interface after switching store - Fixed catalog price rule validation (case if rule is wrong: need to remove existing generated price changes) - Fixed cleanup call in catalog index - Fixed command line installation with index.php - Fixed customer and product grid performance in admin - Fixed cybersource payment for virtual order - Fixed generate xml string for config cache (0 value was ignored) - Fixed getting table names during installation - Fixed refreshing catalog rewrites after save catalog configuration and url resource model for getting static attributes value - Fixed reindex prices after saving catalog configuration section - Fixed reorder of grouped products - Fixed tax data joining (join tax classes just for special cases) - Fixed tierprice rendering for different product types - Fixed translations in permissions titles - Fixed PayPalUk Redirect url wrong type - Fixed create unique index in install - Fixed catalog product index - Fixed session validate and re-validate sent cookie - Added customer group id for price condition in advanced search, replaced 'or' on 'in' for price layered navigation condition - Fixed Google Checkout displaying of button when it is disabled - Fixed PayPal css/html - Fixed USPS Express Mail free shipping - Fixed applying catalog price rule with empty from date - Fixed catalog search in multistore setup - Fixed checkout crosssell block: when there are no products in cart, the filter was working incorrect - Fixed displaying of shipping name in orders history (if there are only downloadable or virtual products in orders) - Fixed displaying of uploaded files; changed redirecting after log in action while trying to download is not shearable link - Fixed downloadable products renderers for multishipping checkout - Fixed fixed amount product taxes - Fixed foreign key upgrade in core DB upgrade 0.8.10-0.8.11 - Fixed getting massaction_key from POST - Fixed issues with applying coupon codes - Fixed js error in manage rules interface - Fixed downlodable products admin interface in IE - Updated Flex-Javascript bridge, fixed IE/Safari issues - Added applying frontend translation when sending emails from admin - Fixed recreating new instances of Flex-Ajax bridges on hide/display flash objects - Fixed category selection in URL-rewrites management form - Fixed fatal error in downloader - Fixed command line installer - Fixed fixed amount product taxes for products without discounts - Fixed hiding of flex uploader after removing row of downloadbale sample|link - Fixed FPT editing for bundle products - Fixed generatting filenames for create custom extensions interface in Windows - Fixed calling final step of dataflow import - Fixed bundle js for calculating children with FPT - Fixed grid to select products SKU in price rules in IE6/7 - Fixed duplicate diplaying prices in bundle product price ranges - Fixed displaying category image in blank theme - Fixed cross sells issues on frontend - Fixed serialized data checking when reading FPT data from order item - Fixed checking order status for downloadable products to become available - Fixed #9757: Paypal Payment Pro Direct not visible - - -CHANGES: - - Upgraded ZF library to version 1.7.2 (r13445 from http://framework.zend.com/svn/framework/standard/trunk/library/Zend) - Added downlodable product type - Implented fulltext search - Added layred navigation to search results - Added option to disable google checkout for selected products - Added fixed amount product taxes - Moved information about product visibility to catalog_product_category_index - Changed Mage::app()->isInstalled to Mage::isInstalled to prevent db upgrades - Removed session ID encryption - Changed catalogindex price to store prices per website - Changed modules dependencies: Mage_Shipment and Mage_Payment now depend on Mage_Catalog, Mage_GoogleCheckout depends on Mage_Payment, Mage_CatalogInventory doesn't depend on Mage_Sales - Added "Add Field with URL" option for product export - Added configuration field to include some additional output on the HTML page before head closing tag - Added Spanish - Costa Rica locale - Extended Mage_Adminhtml_Controller_Action->_prepareDownloadResponse() to avoid copy-pasting in admin controllers - Removed adding ?ft parameter in admin to prevent the issues it caused - Made category URL suffix to be .html by default - Added setting body class on tag for admin pages (similar to frontend - full action name separated by dashes) - Added local.xml.additional file to list/explain possible additional configuration nodes/values for local.xml - Added currency rates into order info box in backend - Added ability to display form buttons on bottom in admin container widget, fixed button levels - Added ability to use memcached to store sessions and to be used as cache backend - Added additional permissions to WS api, fixed bugs with custom permissions - Added option "Disable Guest Checkout if cart contains downloadable items" - Removed store view name from page titles on catalog pages - Commented out required_once in lib/Zend - Added permanent redirect option for URL Rewrites - Added ability to display custom child blocks on success page - Added collecting results of non-asynchronous event handlers in adminhtml/events.js - Added confirmation dialog before switching from 'Images' and 'Downloadable Information' tabs in product edit form to prevent losing selected files - Added firing 'tabChangeBefore' event before switching tab in adminhtml/tabs.js (event handler can return 'cannotchange' to prevent switching) - Rewritten URL Rewrite Management interface - Added checking of file size before uploading - Added downloadable order items pdf renderers - Added downloadable products templates to blank, iphone, modern theme - Added flex uploader source code - Added support of allowed tags into Mage_Core_Helper_Abstract->htmlEscape() method - Added unquoting autobinded quoted values in SQL adapter - Added validation for selected, but not uploaded files - Updated downloader version to 1.2.0 - Changed app/etc/local.xml* license to AFL - Added autoguessing mime type of a file if mimemagic extension is not installed - - -NOTES: - - Please check the SVN log if you are looking for the changes that are not listed here. diff --git a/app/Mage.php b/app/Mage.php index 9b39268796..6702f50c6a 100644 --- a/app/Mage.php +++ b/app/Mage.php @@ -31,8 +31,8 @@ Mage::register('original_include_path', get_include_path()); if (defined('COMPILER_INCLUDE_PATH')) { - $app_path = COMPILER_INCLUDE_PATH; - set_include_path($app_path . PS . Mage::registry('original_include_path')); + $appPath = COMPILER_INCLUDE_PATH; + set_include_path($appPath . PS . Mage::registry('original_include_path')); include_once "Mage_Core_functions.php"; include_once "Varien_Autoload.php"; } else { @@ -44,8 +44,8 @@ $paths[] = BP . DS . 'app' . DS . 'code' . DS . 'core'; $paths[] = BP . DS . 'lib'; - $app_path = implode(PS, $paths); - set_include_path($app_path . PS . Mage::registry('original_include_path')); + $appPath = implode(PS, $paths); + set_include_path($appPath . PS . Mage::registry('original_include_path')); include_once "Mage/Core/functions.php"; include_once "Varien/Autoload.php"; } @@ -57,13 +57,21 @@ * * @author Magento Core Team */ -final class Mage { +final class Mage +{ /** * Registry collection * * @var array */ - static private $_registry = array(); + static private $_registry = array(); + + /** + * Application root absolute path + * + * @var string + */ + static private $_appRoot; /** * Application model @@ -72,19 +80,63 @@ final class Mage { */ static private $_app; - static private $_useCache = array(); + /** + * Config Model + * + * @var Mage_Core_Model_Config + */ + static private $_config; + + /** + * Event Collection Object + * + * @var Varien_Event_Collection + */ + static private $_events; + /** + * Object cache instance + * + * @var Varien_Object_Cache + */ static private $_objects; - static private $_isDownloader = false; + /** + * Is downloader flag + * + * @var bool + */ + static private $_isDownloader = false; - static private $_isDeveloperMode = false; + /** + * Is developer mode flag + * + * @var bool + */ + static private $_isDeveloperMode = false; - public static $headersSentThrowsException = true; + /** + * Is allow throw Exception about headers already sent + * + * @var bool + */ + public static $headersSentThrowsException = true; + /** + * Is installed flag + * + * @var bool + */ + static private $_isInstalled; + + /** + * Retrieve current Magento version + * + * @return string + */ public static function getVersion() { - return '1.3.2.4'; + return '1.4.0.0-alpha1'; } /** @@ -93,10 +145,11 @@ public static function getVersion() */ public static function reset() { - self::$_registry = array(); - self::$_app = null; - self::$_useCache = array(); - self::$_objects = null; + self::$_registry = array(); + self::$_app = null; + self::$_config = null; + self::$_events = null; + self::$_objects = null; self::$_isDownloader = false; self::$_isDeveloperMode = false; // do not reset $headersSentThrowsException @@ -108,22 +161,28 @@ public static function reset() * @param string $key * @param mixed $value * @param bool $graceful + * @throws Mage_Core_Exception */ public static function register($key, $value, $graceful = false) { - if(isset(self::$_registry[$key])) { + if (isset(self::$_registry[$key])) { if ($graceful) { return; } - Mage::throwException('Mage registry key "'.$key.'" already exists'); + self::throwException('Mage registry key "'.$key.'" already exists'); } self::$_registry[$key] = $value; } + /** + * Unregister a variable from register by key + * + * @param string $key + */ public static function unregister($key) { if (isset(self::$_registry[$key])) { - if (is_object(self::$_registry[$key]) && (method_exists(self::$_registry[$key],'__destruct'))) { + if (is_object(self::$_registry[$key]) && (method_exists(self::$_registry[$key], '__destruct'))) { self::$_registry[$key]->__destruct(); } unset(self::$_registry[$key]); @@ -148,13 +207,15 @@ public static function registry($key) * Set application root absolute path * * @param string $appRoot + * @throws Mage_Core_Exception */ - public static function setRoot($appRoot='') + public static function setRoot($appRoot = '') { - if (self::registry('appRoot')) { + if (self::$_appRoot) { return ; } - if (''===$appRoot) { + + if ('' === $appRoot) { // automagically find application root by dirname of Mage.php $appRoot = dirname(__FILE__); } @@ -162,21 +223,30 @@ public static function setRoot($appRoot='') $appRoot = realpath($appRoot); if (is_dir($appRoot) and is_readable($appRoot)) { - Mage::register('appRoot', $appRoot); + self::$_appRoot = $appRoot; } else { - Mage::throwException($appRoot.' is not a directory or not readable by this user'); + self::throwException($appRoot . ' is not a directory or not readable by this user'); } } /** - * Get application root absolute path + * Retrieve application root absolute path * * @return string */ - public static function getRoot() { - return Mage::registry('appRoot'); + return self::$_appRoot; + } + + /** + * Retrieve Events Collection + * + * @return Varien_Event_Collection $collection + */ + public static function getEvents() + { + return self::$_events; } /** @@ -185,7 +255,7 @@ public static function getRoot() * @param string $key optional, if specified will load this key * @return Varien_Object_Cache */ - public static function objects($key=null) + public static function objects($key = null) { if (!self::$_objects) { self::$_objects = new Varien_Object_Cache; @@ -200,26 +270,48 @@ public static function objects($key=null) /** * Retrieve application root absolute path * + * @param string $type * @return string */ - public static function getBaseDir($type='base') + public static function getBaseDir($type = 'base') { - return Mage::getConfig()->getOptions()->getDir($type); + return self::getConfig()->getOptions()->getDir($type); } + /** + * Retrieve module absolute path by directory type + * + * @param string $type + * @param string $moduleName + * @return string + */ public static function getModuleDir($type, $moduleName) { - return Mage::getConfig()->getModuleDir($type, $moduleName); + return self::getConfig()->getModuleDir($type, $moduleName); } - public static function getStoreConfig($path, $id=null) + /** + * Retrieve config value for store by path + * + * @param string $path + * @param mixed $store + * @return mixed + */ + public static function getStoreConfig($path, $store = null) { - return self::app()->getStore($id)->getConfig($path); + return self::app()->getStore($store)->getConfig($path); } - public static function getStoreConfigFlag($path, $id=null) + /** + * Retrieve config flag for store by path + * + * @param string $path + * @param mixed $store + * @return bool + */ + public static function getStoreConfigFlag($path, $store = null) { - $flag = strtolower(Mage::getStoreConfig($path, $id)); + $flag = strtolower(self::getStoreConfig($path, $store)); if (!empty($flag) && 'false'!==$flag && '0'!==$flag) { return true; } else { @@ -233,9 +325,9 @@ public static function getStoreConfigFlag($path, $id=null) * @param string $type * @return string */ - public static function getBaseUrl($type=Mage_Core_Model_Store::URL_TYPE_LINK, $secure=null) + public static function getBaseUrl($type = Mage_Core_Model_Store::URL_TYPE_LINK, $secure = null) { - return Mage::app()->getStore()->getBaseUrl($type, $secure); + return self::app()->getStore()->getBaseUrl($type, $secure); } /** @@ -245,9 +337,9 @@ public static function getBaseUrl($type=Mage_Core_Model_Store::URL_TYPE_LINK, $s * @param array $params * @return string */ - public static function getUrl($route='', $params=array()) + public static function getUrl($route = '', $params = array()) { - return Mage::getModel('core/url')->getUrl($route, $params); + return self::getModel('core/url')->getUrl($route, $params); } /** @@ -257,17 +349,17 @@ public static function getUrl($route='', $params=array()) */ public static function getDesign() { - return Mage::getSingleton('core/design_package'); + return self::getSingleton('core/design_package'); } /** - * Get a config object + * Retrieve a config instance * * @return Mage_Core_Model_Config */ public static function getConfig() { - return Mage::registry('config'); + return self::$_config; } /** @@ -278,14 +370,14 @@ public static function getConfig() * @param array $arguments * @param string $observerName */ - public static function addObserver($eventName, $callback, $data=array(), $observerName='', $observerClass='') + public static function addObserver($eventName, $callback, $data = array(), $observerName = '', $observerClass = '') { - if ($observerClass=='') { + if ($observerClass == '') { $observerClass = 'Varien_Event_Observer'; } $observer = new $observerClass(); $observer->setName($observerName)->addData($data)->setEventName($eventName)->setCallback($callback); - return Mage::registry('events')->addObserver($observer); + return self::getEvents()->addObserver($observer); } /** @@ -296,12 +388,13 @@ public static function addObserver($eventName, $callback, $data=array(), $observ * * @param string $name * @param array $args + * @return Mage_Core_Model_App */ - public static function dispatchEvent($name, array $data=array()) + public static function dispatchEvent($name, array $data = array()) { Varien_Profiler::start('DISPATCH EVENT:'.$name); - $result = Mage::app()->dispatchEvent($name, $data); - #$result = Mage::registry('events')->dispatch($name, $data); + $result = self::app()->dispatchEvent($name, $data); + #$result = self::registry('events')->dispatch($name, $data); Varien_Profiler::stop('DISPATCH EVENT:'.$name); return $result; } @@ -314,9 +407,9 @@ public static function dispatchEvent($name, array $data=array()) * @param array $arguments * @return Mage_Core_Model_Abstract */ - public static function getModel($modelClass='', $arguments=array()) + public static function getModel($modelClass = '', $arguments = array()) { - return Mage::getConfig()->getModelInstance($modelClass, $arguments); + return self::getConfig()->getModelInstance($modelClass, $arguments); } /** @@ -329,10 +422,10 @@ public static function getModel($modelClass='', $arguments=array()) public static function getSingleton($modelClass='', array $arguments=array()) { $registryKey = '_singleton/'.$modelClass; - if (!Mage::registry($registryKey)) { - Mage::register($registryKey, Mage::getModel($modelClass, $arguments)); + if (!self::registry($registryKey)) { + self::register($registryKey, self::getModel($modelClass, $arguments)); } - return Mage::registry($registryKey); + return self::registry($registryKey); } /** @@ -342,9 +435,23 @@ public static function getSingleton($modelClass='', array $arguments=array()) * @param array $arguments * @return Object */ - public static function getResourceModel($modelClass, $arguments=array()) + public static function getResourceModel($modelClass, $arguments = array()) { - return Mage::getConfig()->getResourceModelInstance($modelClass, $arguments); + return self::getConfig()->getResourceModelInstance($modelClass, $arguments); + } + + /** + * Retrieve Controller instance by ClassName + * + * @param string $class + * @param Mage_Core_Controller_Request_Http $request + * @param Mage_Core_Controller_Response_Http $response + * @param array $invokeArgs + * @return Mage_Core_Controller_Front_Action + */ + public static function getControllerInstance($class, $request, $response, array $invokeArgs = array()) + { + return new $class($request, $response, $invokeArgs); } /** @@ -354,36 +461,45 @@ public static function getResourceModel($modelClass, $arguments=array()) * @param array $arguments * @return object */ - public static function getResourceSingleton($modelClass='', array $arguments=array()) + public static function getResourceSingleton($modelClass = '', array $arguments = array()) { $registryKey = '_resource_singleton/'.$modelClass; - if (!Mage::registry($registryKey)) { - Mage::register($registryKey, Mage::getResourceModel($modelClass, $arguments)); + if (!self::registry($registryKey)) { + self::register($registryKey, self::getResourceModel($modelClass, $arguments)); } - return Mage::registry($registryKey); + return self::registry($registryKey); } /** - * Deprecated, use Mage::helper() + * Deprecated, use self::helper() * * @param string $type * @return object */ public static function getBlockSingleton($type) { - $action = Mage::app()->getFrontController()->getAction(); + $action = self::app()->getFrontController()->getAction(); return $action ? $action->getLayout()->getBlockSingleton($type) : false; } /** * Retrieve helper object * - * @param helper name $name - * @return Mage_Core_Helper_Abstract + * @param string $name the helper name + * @return Mage_Core_Helper_Abstract */ public static function helper($name) { - return Mage::app()->getHelper($name); + if (strpos($name, '/') === false) { + $name .= '/data'; + } + + $registryKey = '_helper/' . $name; + if (!self::registry($registryKey)) { + $helperClass = self::getConfig()->getHelperClassName($name); + self::register($registryKey, new $helperClass); + } + return self::registry($registryKey); } /** @@ -392,16 +508,23 @@ public static function helper($name) * @param string $module * @param string $message * @param integer $code + * @return Mage_Core_Exception */ - public static function exception($module='Mage_Core', $message='', $code=0) + public static function exception($module = 'Mage_Core', $message = '', $code = 0) { $className = $module.'_Exception'; return new $className($message, $code); } - public static function throwException($message, $messageStorage=null) + /** + * Throw Exception + * + * @param string $message + * @param string $messageStorage + */ + public static function throwException($message, $messageStorage = null) { - if ($messageStorage && ($storage = Mage::getSingleton($messageStorage))) { + if ($messageStorage && ($storage = self::getSingleton($messageStorage))) { $storage->addError($message); } throw new Mage_Core_Exception($message); @@ -410,29 +533,29 @@ public static function throwException($message, $messageStorage=null) /** * Initialize and retrieve application * - * @param string $code - * @param string $type - * @param string|array $options - * @return Mage_Core_Model_App + * @param string $code + * @param string $type + * @param string|array $options + * @return Mage_Core_Model_App */ - public static function app($code = '', $type = 'store', $options=array()) + public static function app($code = '', $type = 'store', $options = array()) { if (null === self::$_app) { - Varien_Profiler::start('mage::app::construct'); + Varien_Profiler::start('self::app::construct'); self::$_app = new Mage_Core_Model_App(); - Varien_Profiler::stop('mage::app::construct'); + Varien_Profiler::stop('self::app::construct'); - Mage::setRoot(); - Mage::register('events', new Varien_Event_Collection()); + self::setRoot(); + self::$_events = new Varien_Event_Collection(); - Varien_Profiler::start('mage::app::register_config'); - Mage::register('config', new Mage_Core_Model_Config()); - Varien_Profiler::stop('mage::app::register_config'); + Varien_Profiler::start('self::app::register_config'); + self::$_config = new Mage_Core_Model_Config(); + Varien_Profiler::stop('self::app::register_config'); - Varien_Profiler::start('mage::app::init'); + Varien_Profiler::start('self::app::init'); self::$_app->init($code, $type, $options); - Varien_Profiler::stop('mage::app::init'); + Varien_Profiler::stop('self::app::init'); self::$_app->loadAreaPart(Mage_Core_Model_App_Area::AREA_GLOBAL, Mage_Core_Model_App_Area::PART_EVENTS); } @@ -451,26 +574,25 @@ public static function run($code = '', $type = 'store', $options=array()) try { Varien_Profiler::start('mage'); - Varien_Profiler::start('mage::app'); + Varien_Profiler::start('self::app'); self::app($code, $type, $options); - Varien_Profiler::stop('mage::app'); + Varien_Profiler::stop('self::app'); - Varien_Profiler::start('mage::dispatch'); + Varien_Profiler::start('self::dispatch'); self::app()->getFrontController()->dispatch(); - Varien_Profiler::stop('mage::dispatch'); + Varien_Profiler::stop('self::dispatch'); Varien_Profiler::stop('mage'); } catch (Mage_Core_Model_Session_Exception $e) { - header('Location: ' . Mage::getBaseUrl()); + header('Location: ' . self::getBaseUrl()); die(); } catch (Mage_Core_Model_Store_Exception $e) { $baseUrl = self::getScriptSystemUrl('404'); if (!headers_sent()) { header('Location: ' . rtrim($baseUrl, '/').'/404/'); - } - else { + } else { print ''; @@ -486,8 +608,7 @@ public static function run($code = '', $type = 'store', $options=array()) self::dispatchEvent('mage_run_exception', array('exception' => $e)); if (!headers_sent()) { header('Location:'.self::getUrl('install')); - } - else { + } else { self::printException($e); } } @@ -505,8 +626,7 @@ public static function run($code = '', $type = 'store', $options=array()) */ public static function isInstalled($options = array()) { - $isInstalled = self::registry('_is_installed'); - if ($isInstalled === null) { + if (self::$_isInstalled === null) { self::setRoot(); if (is_string($options)) { @@ -520,18 +640,17 @@ public static function isInstalled($options = array()) } $localConfigFile = self::getRoot() . DS . $etcDir . DS . 'local.xml'; - $isInstalled = false; + self::$_isInstalled = false; if (is_readable($localConfigFile)) { $localConfig = simplexml_load_file($localConfigFile); date_default_timezone_set('UTC'); if (($date = $localConfig->global->install->date) && strtotime($date)) { - $isInstalled = true; + self::$_isInstalled = true; } } - self::register('_is_installed', $isInstalled); } - return $isInstalled; + return self::$_isInstalled; } /** @@ -541,12 +660,12 @@ public static function isInstalled($options = array()) * @param integer $level * @param string $file */ - public static function log($message, $level=null, $file = '') + public static function log($message, $level = null, $file = '') { if (!self::getConfig()) { return; } - if (!Mage::getStoreConfig('dev/log/active')) { + if (!self::getStoreConfig('dev/log/active')) { return; } @@ -554,21 +673,20 @@ public static function log($message, $level=null, $file = '') $level = is_null($level) ? Zend_Log::DEBUG : $level; if (empty($file)) { - $file = Mage::getStoreConfig('dev/log/file'); + $file = self::getStoreConfig('dev/log/file'); $file = empty($file) ? 'system.log' : $file; } try { if (!isset($loggers[$file])) { - $logFile = Mage::getBaseDir('var').DS.'log'.DS.$file; - $logDir = Mage::getBaseDir('var').DS.'log'; + $logFile = self::getBaseDir('var') . DS . 'log' . DS . $file; - if (!is_dir(Mage::getBaseDir('var').DS.'log')) { - mkdir(Mage::getBaseDir('var').DS.'log', 0777); + if (!is_dir(self::getBaseDir('var').DS.'log')) { + mkdir(self::getBaseDir('var').DS.'log', 0777); } if (!file_exists($logFile)) { - file_put_contents($logFile,''); + file_put_contents($logFile, ''); chmod($logFile, 0777); } @@ -585,18 +703,22 @@ public static function log($message, $level=null, $file = '') $loggers[$file]->log($message, $level); } - catch (Exception $e){ - + catch (Exception $e) { } } + /** + * Write exception to log + * + * @param Exception $e + */ public static function logException(Exception $e) { if (!self::getConfig()) { return; } - $file = Mage::getStoreConfig('dev/log/exception_file'); - self::log("\n".(string)$e, Zend_Log::ERR, $file); + $file = self::getStoreConfig('dev/log/exception_file'); + self::log("\n" . $e->__toString(), Zend_Log::ERR, $file); } /** @@ -638,10 +760,9 @@ public static function printException(Exception $e, $extra = '') print $e->getMessage() . "\n\n"; print $e->getTraceAsString(); print ''; - } - else { + } else { self::getConfig()->createDirIfNotExists(self::getBaseDir('var') . DS . 'report'); - $reportId = intval(microtime(true) * rand(100, 1000)); + $reportId = abs(intval(microtime(true) * rand(100, 1000))); $reportFile = self::getBaseDir('var') . DS . 'report' . DS . $reportId; $reportData = array( !empty($extra) ? $extra . "\n\n" : '' . $e->getMessage(), @@ -656,7 +777,8 @@ public static function printException(Exception $e, $extra = '') try { $storeCode = self::app()->getStore()->getCode(); } - catch (Exception $e) {} + catch (Exception $e) { + } $baseUrl = self::getScriptSystemUrl('report', true); $reportUrl = rtrim($baseUrl, '/') . '/report/?id=' @@ -664,8 +786,7 @@ public static function printException(Exception $e, $extra = '') if (!headers_sent()) { header('Location: ' . $reportUrl); - } - else { + } else { print ''; @@ -693,8 +814,8 @@ public static function getScriptSystemUrl($folder, $exitIfNot = false) $baseUrl = str_replace(DS, '/', $runDirUrl); } else { $runDirUrlArray = explode('/', $runDirUrl); - $runDirArray = explode('/', $runDir); - $count = count($runDirArray); + $runDirArray = explode('/', $runDir); + $count = count($runDirArray); for ($i=0; $i < $count; $i++) { array_pop($runDirUrlArray); @@ -706,7 +827,7 @@ public static function getScriptSystemUrl($folder, $exitIfNot = false) if (is_dir($_runDir.$folder)) { $_runDirUrl = implode('/', $runDirUrlArray); - $baseUrl = str_replace(DS, '/', $_runDirUrl); + $baseUrl = str_replace(DS, '/', $_runDirUrl); break; } } @@ -725,7 +846,12 @@ public static function getScriptSystemUrl($folder, $exitIfNot = false) return $baseUrl; } - public static function setIsDownloader($flag=true) + /** + * Set is downloader flag + * + * @param bool $flag + */ + public static function setIsDownloader($flag = true) { self::$_isDownloader = $flag; } diff --git a/app/code/core/Mage/Admin/Model/User.php b/app/code/core/Mage/Admin/Model/User.php index 1c7d85ae06..aee3ccb533 100644 --- a/app/code/core/Mage/Admin/Model/User.php +++ b/app/code/core/Mage/Admin/Model/User.php @@ -36,6 +36,7 @@ class Mage_Admin_Model_User extends Mage_Core_Model_Abstract const XML_PATH_FORGOT_EMAIL_TEMPLATE = 'admin/emails/forgot_email_template'; const XML_PATH_FORGOT_EMAIL_IDENTITY = 'admin/emails/forgot_email_identity'; const XML_PATH_STARTUP_PAGE = 'admin/startup/page'; + const MIN_PASSWORD_LENGTH = 7; protected $_eventPrefix = 'admin_user'; @@ -371,7 +372,7 @@ public function getStartupPageUrl() $startupPage = Mage::getStoreConfig(self::XML_PATH_STARTUP_PAGE); $aclResource = 'admin/' . $startupPage; if (Mage::getSingleton('admin/session')->isAllowed($aclResource)) { - $nodePath = 'adminhtml/menu/' . join('/children/', split('/', $startupPage)) . '/action'; + $nodePath = 'adminhtml/menu/' . join('/children/', explode('/', $startupPage)) . '/action'; if ($url = Mage::getConfig()->getNode($nodePath)) { return $url; } @@ -379,4 +380,54 @@ public function getStartupPageUrl() return $this->findFirstAvailableMenu(); } + /** + * Validate user attribute values. + * Returns TRUE or array of errors. + * + * @return mixed + */ + public function validate() + { + $errors = array(); + + if (!Zend_Validate::is($this->getUsername(), 'NotEmpty')) { + $errors[] = Mage::helper('adminhtml')->__('User Name is required field.'); + } + + if (!Zend_Validate::is($this->getFirstname(), 'NotEmpty')) { + $errors[] = Mage::helper('adminhtml')->__('First Name is required field.'); + } + + if (!Zend_Validate::is($this->getLastname(), 'NotEmpty')) { + $errors[] = Mage::helper('adminhtml')->__('Last Name is required field.'); + } + + if (!Zend_Validate::is($this->getEmail(), 'EmailAddress')) { + $errors[] = Mage::helper('adminhtml')->__('Please enter a valid email.'); + } + + 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); + } + + 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 ($this->hasPasswordConfirmation() && $this->getNewPassword() != $this->getPasswordConfirmation()) { + $errors[] = Mage::helper('adminhtml')->__('Password confirmation must be same as password.'); + } + } + + if ($this->userExists()) { + $errors[] = Mage::helper('adminhtml')->__('User with the same User Name or Email aleady exists'); + } + + if (empty($errors)) { + return true; + } + return $errors; + } + } diff --git a/app/code/core/Mage/Admin/etc/config.xml b/app/code/core/Mage/Admin/etc/config.xml index b3ff73d82a..2a7e371ce3 100644 --- a/app/code/core/Mage/Admin/etc/config.xml +++ b/app/code/core/Mage/Admin/etc/config.xml @@ -28,7 +28,7 @@ - 0.7.1 + 0.7.2 diff --git a/app/code/core/Mage/Admin/sql/admin_setup/mysql4-install-0.7.0.php b/app/code/core/Mage/Admin/sql/admin_setup/mysql4-install-0.7.0.php index 00302615f2..5c5462f388 100644 --- a/app/code/core/Mage/Admin/sql/admin_setup/mysql4-install-0.7.0.php +++ b/app/code/core/Mage/Admin/sql/admin_setup/mysql4-install-0.7.0.php @@ -88,9 +88,6 @@ `is_active` tinyint(1) NOT NULL default '1', PRIMARY KEY (`user_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Users'; - -insert into {$this->getTable('admin_user')}(`user_id`,`firstname`,`lastname`,`email`,`username`,`password`,`created`,`modified`,`logdate`,`lognum`,`reload_acl_flag`,`is_active`) values (1,'admin','admin','admin@your_domain.com','admin','4297f44b13955235245b2497399d7a93',NOW(),NOW(),NOW(),1,0,1); - - "); +"); $installer->endSetup(); diff --git a/app/code/core/Mage/Adminhtml/Block/Api/Role/Grid/User.php b/app/code/core/Mage/Adminhtml/Block/Api/Role/Grid/User.php index e4ae7ae1ae..268bb661e6 100644 --- a/app/code/core/Mage/Adminhtml/Block/Api/Role/Grid/User.php +++ b/app/code/core/Mage/Adminhtml/Block/Api/Role/Grid/User.php @@ -165,7 +165,7 @@ protected function _getUsers($json=false) if ( $json ) { $jsonUsers = Array(); foreach($users as $usrid) $jsonUsers[$usrid] = 0; - return Zend_Json::encode((object)$jsonUsers); + return Mage::helper('core')->jsonEncode((object)$jsonUsers); } else { return array_values($users); } diff --git a/app/code/core/Mage/Adminhtml/Block/Api/Tab/Rolesedit.php b/app/code/core/Mage/Adminhtml/Block/Api/Tab/Rolesedit.php index da2bcbd835..522717b75e 100644 --- a/app/code/core/Mage/Adminhtml/Block/Api/Tab/Rolesedit.php +++ b/app/code/core/Mage/Adminhtml/Block/Api/Tab/Rolesedit.php @@ -63,7 +63,7 @@ public function getResTreeJson() $rootArray = $this->_getNodeJson($resources,1); - $json = Zend_Json::encode(isset($rootArray['children']) ? $rootArray['children'] : array()); + $json = Mage::helper('core')->jsonEncode(isset($rootArray['children']) ? $rootArray['children'] : array()); return $json; } diff --git a/app/code/core/Mage/Adminhtml/Block/Api/User/Edit/Tab/Main.php b/app/code/core/Mage/Adminhtml/Block/Api/User/Edit/Tab/Main.php index b02f24424c..54f186078e 100644 --- a/app/code/core/Mage/Adminhtml/Block/Api/User/Edit/Tab/Main.php +++ b/app/code/core/Mage/Adminhtml/Block/Api/User/Edit/Tab/Main.php @@ -94,7 +94,7 @@ protected function _prepareForm() '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-admin-password', )); $fieldset->addField('confirmation', 'password', array( @@ -110,7 +110,7 @@ protected function _prepareForm() '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-admin-password', 'required' => true, )); $fieldset->addField('confirmation', 'password', array( diff --git a/app/code/core/Mage/Adminhtml/Block/Api/User/Edit/Tab/Roles.php b/app/code/core/Mage/Adminhtml/Block/Api/User/Edit/Tab/Roles.php index cfd1335730..9e1e5f65a1 100644 --- a/app/code/core/Mage/Adminhtml/Block/Api/User/Edit/Tab/Roles.php +++ b/app/code/core/Mage/Adminhtml/Block/Api/User/Edit/Tab/Roles.php @@ -110,7 +110,7 @@ protected function _getSelectedRoles($json=false) if ($json) { $jsonRoles = Array(); foreach($uRoles as $urid) $jsonRoles[$urid] = 0; - return Zend_Json::encode((object)$jsonRoles); + return Mage::helper('core')->jsonEncode((object)$jsonRoles); } else { return $uRoles; } diff --git a/app/code/core/Mage/Adminhtml/Block/Catalog/Category/Abstract.php b/app/code/core/Mage/Adminhtml/Block/Catalog/Category/Abstract.php index 40e90c125f..51c985d3e8 100644 --- a/app/code/core/Mage/Adminhtml/Block/Catalog/Category/Abstract.php +++ b/app/code/core/Mage/Adminhtml/Block/Catalog/Category/Abstract.php @@ -39,6 +39,11 @@ public function __construct() parent::__construct(); } + /** + * Retrieve current category instance + * + * @return Mage_Catalog_Model_Category + */ public function getCategory() { return Mage::registry('category'); diff --git a/app/code/core/Mage/Adminhtml/Block/Catalog/Category/Edit/Form.php b/app/code/core/Mage/Adminhtml/Block/Catalog/Category/Edit/Form.php index 008d765080..c79ba06c52 100644 --- a/app/code/core/Mage/Adminhtml/Block/Catalog/Category/Edit/Form.php +++ b/app/code/core/Mage/Adminhtml/Block/Catalog/Category/Edit/Form.php @@ -75,11 +75,12 @@ protected function _prepareLayout() } if (!$this->getCategory()->isReadonly()) { + $resetPath = $this->getCategory()->getId() ? '*/*/edit' : '*/*/add'; $this->setChild('reset_button', $this->getLayout()->createBlock('adminhtml/widget_button') ->setData(array( 'label' => Mage::helper('catalog')->__('Reset'), - 'onclick' => "categoryReset('".$this->getUrl('*/*/edit', array('_current'=>true))."',true)" + 'onclick' => "categoryReset('".$this->getUrl($resetPath, array('_current'=>true))."',true)" )) ); } @@ -186,11 +187,24 @@ public function getDeleteUrl(array $args = array()) return $this->getUrl('*/*/delete', $params); } + /** + * Return URL for refresh input element 'path' in form + * + * @param array $args + * @return string + */ + public function getRefreshPathUrl(array $args = array()) + { + $params = array('_current'=>true); + $params = array_merge($params, $args); + return $this->getUrl('*/*/refreshPath', $params); + } + public function getProductsJson() { $products = $this->getCategory()->getProductsPosition(); if (!empty($products)) { - return Zend_Json::encode($products); + return Mage::helper('core')->jsonEncode($products); } return '{}'; } diff --git a/app/code/core/Mage/Adminhtml/Block/Catalog/Category/Helper/Sortby/Available.php b/app/code/core/Mage/Adminhtml/Block/Catalog/Category/Helper/Sortby/Available.php index 24d0c40ce1..879bd77150 100644 --- a/app/code/core/Mage/Adminhtml/Block/Catalog/Category/Helper/Sortby/Available.php +++ b/app/code/core/Mage/Adminhtml/Block/Catalog/Category/Helper/Sortby/Available.php @@ -1,68 +1,67 @@ - - */ -class Mage_Adminhtml_Block_Catalog_Category_Helper_Sortby_Available - extends Varien_Data_Form_Element_Multiselect -{ -/** - * Retrieve Element HTML fragment - * - * @return string - */ - public function getElementHtml() - { - $disabled = false; - if (!$this->getValue()) { - $this->setData('disabled', 'disabled'); - $disabled = true; - } - $html = parent::getElementHtml(); - - $htmlId = 'use_config_' . $this->getHtmlId(); - $html .= 'getReadonly()) { - $html .= ' disabled="disabled"'; - } - - $html .= 'onclick="toggleValueElements(this, this.parentNode);" class="checkbox" type="checkbox">'; - - $html .= ' '; - $html .= ''; - - return $html; - } -} + + */ +class Mage_Adminhtml_Block_Catalog_Category_Helper_Sortby_Available + extends Varien_Data_Form_Element_Multiselect +{ +/** + * Retrieve Element HTML fragment + * + * @return string + */ + public function getElementHtml() + { + $disabled = false; + if (!$this->getValue()) { + $this->setData('disabled', 'disabled'); + $disabled = true; + } + $html = parent::getElementHtml(); + $htmlId = 'use_config_' . $this->getHtmlId(); + $html .= 'getReadonly()) { + $html .= ' disabled="disabled"'; + } + + $html .= 'onclick="toggleValueElements(this, this.parentNode);" class="checkbox" type="checkbox">'; + + $html .= ' '; + $html .= ''; + + return $html; + } +} diff --git a/app/code/core/Mage/Adminhtml/Block/Catalog/Category/Helper/Sortby/Default.php b/app/code/core/Mage/Adminhtml/Block/Catalog/Category/Helper/Sortby/Default.php index 9ed1bc3e84..6d5d74e9c9 100644 --- a/app/code/core/Mage/Adminhtml/Block/Catalog/Category/Helper/Sortby/Default.php +++ b/app/code/core/Mage/Adminhtml/Block/Catalog/Category/Helper/Sortby/Default.php @@ -1,68 +1,67 @@ - - */ -class Mage_Adminhtml_Block_Catalog_Category_Helper_Sortby_Default - extends Varien_Data_Form_Element_Select -{ - /** - * Retrieve Element HTML fragment - * - * @return string - */ - public function getElementHtml() - { - $disabled = false; - if (!$this->getValue()) { - $this->setData('disabled', 'disabled'); - $disabled = true; - } - $html = parent::getElementHtml(); - - $htmlId = 'use_config_' . $this->getHtmlId(); - $html .= 'getReadonly()) { - $html .= ' disabled="disabled"'; - } - $html .= 'onclick="toggleValueElements(this, this.parentNode);" class="checkbox" type="checkbox">'; - - - - $html .= ' '; - $html .= ''; - - return $html; - } -} + + */ +class Mage_Adminhtml_Block_Catalog_Category_Helper_Sortby_Default + extends Varien_Data_Form_Element_Select +{ + /** + * Retrieve Element HTML fragment + * + * @return string + */ + public function getElementHtml() + { + $disabled = false; + if (!$this->getValue()) { + $this->setData('disabled', 'disabled'); + $disabled = true; + } + $html = parent::getElementHtml(); + $htmlId = 'use_config_' . $this->getHtmlId(); + $html .= 'getReadonly()) { + $html .= ' disabled="disabled"'; + } + $html .= 'onclick="toggleValueElements(this, this.parentNode);" class="checkbox" type="checkbox">'; + + + + $html .= ' '; + $html .= ''; + + return $html; + } +} diff --git a/app/code/core/Mage/Adminhtml/Block/Catalog/Category/Tree.php b/app/code/core/Mage/Adminhtml/Block/Catalog/Category/Tree.php index 24d482278f..993c5bbc67 100644 --- a/app/code/core/Mage/Adminhtml/Block/Catalog/Category/Tree.php +++ b/app/code/core/Mage/Adminhtml/Block/Catalog/Category/Tree.php @@ -174,7 +174,7 @@ public function getTree($parenNodeCategory=null) public function getTreeJson($parenNodeCategory=null) { $rootArray = $this->_getNodeJson($this->getRoot($parenNodeCategory)); - $json = Zend_Json::encode(isset($rootArray['children']) ? $rootArray['children'] : array()); + $json = Mage::helper('core')->jsonEncode(isset($rootArray['children']) ? $rootArray['children'] : array()); return $json; } @@ -190,7 +190,9 @@ public function getBreadcrumbsJavascript($path, $javascriptVarName) if (empty($path)) { return ''; } - $categories = Mage::getResourceSingleton('catalog/category_tree')->loadBreadcrumbsArray($path); + + $categories = Mage::getResourceSingleton('catalog/category_tree') + ->setStoreId($this->getStore()->getId())->loadBreadcrumbsArray($path); if (empty($categories)) { return ''; } @@ -199,7 +201,7 @@ public function getBreadcrumbsJavascript($path, $javascriptVarName) } return ''; } diff --git a/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Attribute/Edit.php b/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Attribute/Edit.php index 67e7171cf5..8de5e13945 100644 --- a/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Attribute/Edit.php +++ b/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Attribute/Edit.php @@ -53,18 +53,19 @@ public function __construct() 'level' => -1 ) ); + } else { + $this->_addButton( + 'save_and_edit_button', + array( + 'label' => Mage::helper('catalog')->__('Save And Continue Edit'), + 'onclick' => 'saveAndContinueEdit()', + 'class' => 'save' + ), + 100 + ); } $this->_updateButton('save', 'label', Mage::helper('catalog')->__('Save Attribute')); - $this->_addButton( - 'save_and_edit_button', - array( - 'label' => Mage::helper('catalog')->__('Save And Continue Edit'), - 'onclick' => 'saveAndContinueEdit()', - 'class' => 'save' - ), - 100 - ); if (! Mage::registry('entity_attribute')->getIsUserDefined()) { $this->_removeButton('delete'); diff --git a/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Attribute/Edit/Tab/Main.php b/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Attribute/Edit/Tab/Main.php index 06ea1114b2..8526e7d60b 100644 --- a/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Attribute/Edit/Tab/Main.php +++ b/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Attribute/Edit/Tab/Main.php @@ -46,22 +46,23 @@ protected function _prepareForm() )); $disableAttributeFields = array( - 'sku' => array( + 'sku' => array( 'is_global', 'is_unique', ), - 'url_key' => array( + 'url_key' => array( 'is_unique', ), - 'status' => array( - 'is_configurable' - ) - ); - - $rewriteAttributeValue = array( - 'status' => array( - 'is_configurable' => 0 - ) + 'status' => array( + 'is_configurable', + 'is_filterable', + 'is_filterable_in_search' + ), + 'visibility' => array( + 'is_configurable', + 'is_filterable', + 'is_filterable_in_search' + ), ); $fieldset = $form->addFieldset('base_fieldset', @@ -141,16 +142,19 @@ protected function _prepareForm() 'value' => 'price', 'label' => Mage::helper('catalog')->__('Price') ), - array( - 'value' => 'gallery', - 'label' => Mage::helper('catalog')->__('Gallery') - ), array( 'value' => 'media_image', 'label' => Mage::helper('catalog')->__('Media Image') ), ); + if ($model->getFrontendInput() == 'gallery') { + $inputTypes[] = array( + 'value' => 'gallery', + 'label' => Mage::helper('catalog')->__('Gallery') + ); + } + $response = new Varien_Object(); $response->setTypes(array()); Mage::dispatchEvent('adminhtml_product_attribute_types', array('response'=>$response)); @@ -385,6 +389,7 @@ protected function _prepareForm() if (isset($disableAttributeFields[$model->getAttributeCode()])) { foreach ($disableAttributeFields[$model->getAttributeCode()] as $field) { $form->getElement($field)->setDisabled(1); + $form->getElement($field)->setReadonly(1); } } } @@ -394,12 +399,6 @@ protected function _prepareForm() $form->addValues($model->getData()); - if ($model->getId() && isset($rewriteAttributeValue[$model->getAttributeCode()])) { - foreach ($rewriteAttributeValue[$model->getAttributeCode()] as $field => $value) { - $form->getElement($field)->setValue($value); - } - } - $form->getElement('apply_to')->setSize(5); if ($applyTo = $model->getApplyTo()) { diff --git a/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Attribute/New/Product/Created.php b/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Attribute/New/Product/Created.php index f84cde7fd0..d621842598 100644 --- a/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Attribute/New/Product/Created.php +++ b/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Attribute/New/Product/Created.php @@ -84,6 +84,6 @@ public function getAttributesBlockJson() $this->getRequest()->getParam('tab') => $this->getChildHtml('attributes') ); - return Zend_Json::encode($result); + return Mage::helper('core')->jsonEncode($result); } } // Class Mage_Adminhtml_Block_Catalog_Product_Attribute_New_Product_Created End \ No newline at end of file diff --git a/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Attribute/Set/Main.php b/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Attribute/Set/Main.php index a754e0a7e9..bca0c3bbcb 100644 --- a/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Attribute/Set/Main.php +++ b/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Attribute/Set/Main.php @@ -18,25 +18,35 @@ * versions in the future. If you wish to customize Magento for your * needs please refer to http://www.magentocommerce.com for more information. * - * @category Mage - * @package Mage_Adminhtml - * @copyright Copyright (c) 2008 Irubin Consulting Inc. DBA Varien (http://www.varien.com) - * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @category Mage + * @package Mage_Adminhtml + * @copyright Copyright (c) 2009 Irubin Consulting Inc. DBA Varien (http://www.varien.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ /** - * @category Mage - * @package Mage_Adminhtml + * Adminhtml Catalog Attribute Set Main Block + * + * @category Mage + * @package Mage_Adminhtml * @author Magento Core Team */ - class Mage_Adminhtml_Block_Catalog_Product_Attribute_Set_Main extends Mage_Adminhtml_Block_Template { + /** + * Initialize template + * + */ protected function _construct() { $this->setTemplate('catalog/product/attribute/set/main.phtml'); } + /** + * Prepare Global Layout + * + * @return Mage_Adminhtml_Block_Catalog_Product_Attribute_Set_Main + */ protected function _prepareLayout() { $setId = $this->_getSetId(); @@ -50,203 +60,258 @@ protected function _prepareLayout() ); $this->setChild('delete_group_button', - $this->getLayout()->createBlock('adminhtml/widget_button') - ->setData(array( - 'label' => Mage::helper('catalog')->__('Delete Selected Group'), - 'onclick' => 'editSet.submit();', - 'class' => 'delete' + $this->getLayout()->createBlock('adminhtml/widget_button')->setData(array( + 'label' => Mage::helper('catalog')->__('Delete Selected Group'), + 'onclick' => 'editSet.submit();', + 'class' => 'delete' ))); $this->setChild('add_group_button', - $this->getLayout()->createBlock('adminhtml/widget_button') - ->setData(array( - 'label' => Mage::helper('catalog')->__('Add New'), - 'onclick' => 'editSet.addGroup();', - 'class' => 'add' + $this->getLayout()->createBlock('adminhtml/widget_button')->setData(array( + 'label' => Mage::helper('catalog')->__('Add New'), + 'onclick' => 'editSet.addGroup();', + 'class' => 'add' ))); $this->setChild('back_button', - $this->getLayout()->createBlock('adminhtml/widget_button') - ->setData(array( - 'label' => Mage::helper('catalog')->__('Back'), - 'onclick' => 'setLocation(\''.$this->getUrl('*/*/').'\')', - 'class' => 'back' + $this->getLayout()->createBlock('adminhtml/widget_button')->setData(array( + 'label' => Mage::helper('catalog')->__('Back'), + 'onclick' => 'setLocation(\''.$this->getUrl('*/*/').'\')', + 'class' => 'back' ))); $this->setChild('reset_button', - $this->getLayout()->createBlock('adminhtml/widget_button') - ->setData(array( - 'label' => Mage::helper('catalog')->__('Reset'), - 'onclick' => 'window.location.reload()' + $this->getLayout()->createBlock('adminhtml/widget_button')->setData(array( + 'label' => Mage::helper('catalog')->__('Reset'), + 'onclick' => 'window.location.reload()' ))); $this->setChild('save_button', - $this->getLayout()->createBlock('adminhtml/widget_button') - ->setData(array( - 'label' => Mage::helper('catalog')->__('Save Attribute Set'), - 'onclick' => 'editSet.save();', - 'class' => 'save' + $this->getLayout()->createBlock('adminhtml/widget_button')->setData(array( + 'label' => Mage::helper('catalog')->__('Save Attribute Set'), + 'onclick' => 'editSet.save();', + 'class' => 'save' ))); $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)) . '\')', - 'class' => 'delete' + $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)) . '\')', + 'class' => 'delete' ))); $this->setChild('rename_button', - $this->getLayout()->createBlock('adminhtml/widget_button') - ->setData(array( - 'label' => Mage::helper('catalog')->__('New Set Name'), - 'onclick' => 'editSet.rename()' - )) - ); + $this->getLayout()->createBlock('adminhtml/widget_button')->setData(array( + 'label' => Mage::helper('catalog')->__('New Set Name'), + 'onclick' => 'editSet.rename()' + ))); + return parent::_prepareLayout(); } + /** + * Retrieve Attribute Set Group Tree HTML + * + * @return string + */ public function getGroupTreeHtml() { return $this->getChildHtml('group_tree'); } + /** + * Retrieve Attribute Set Edit Form HTML + * + * @return string + */ public function getSetFormHtml() { return $this->getChildHtml('edit_set_form'); } + /** + * Retrieve Block Header Text + * + * @return string + */ protected function _getHeader() { - return Mage::helper('catalog')->__("Edit Attribute Set '%s'", $this->_getSetData()->getAttributeSetName()); + return Mage::helper('catalog')->__("Edit Attribute Set '%s'", $this->_getAttributeSet()->getAttributeSetName()); } + /** + * Retrieve Attribute Set Save URL + * + * @return string + */ public function getMoveUrl() { return $this->getUrl('*/catalog_product_set/save', array('id' => $this->_getSetId())); } + /** + * Retrieve Attribute Set Group Save URL + * + * @return string + */ public function getGroupUrl() { return $this->getUrl('*/catalog_product_group/save', array('id' => $this->_getSetId())); } + /** + * Retrieve Attribute Set Group Tree as JSON format + * + * @return string + */ public function getGroupTreeJson() { + $items = array(); $setId = $this->_getSetId(); + /* @var $groups Mage_Eav_Model_Mysql4_Entity_Attribute_Group_Collection */ $groups = Mage::getModel('eav/entity_attribute_group') - ->getResourceCollection() - ->setAttributeSetFilter($setId) - ->load(); + ->getResourceCollection() + ->setAttributeSetFilter($setId) + ->load(); - $items = array(); - foreach( $groups as $node ) { + $configurable = Mage::getResourceModel('catalog/product_type_configurable_attribute') + ->getUsedAttributes($setId); + + /* @var $node Mage_Eav_Model_Entity_Attribute_Group */ + foreach ($groups as $node) { $item = array(); - $item['text']= $node->getAttributeGroupName(); - $item['id'] = $node->getAttributeGroupId(); - $item['cls'] = 'folder'; - $item['allowDrop'] = true; - $item['allowDrag'] = true; + $item['text'] = $node->getAttributeGroupName(); + $item['id'] = $node->getAttributeGroupId(); + $item['cls'] = 'folder'; + $item['allowDrop'] = true; + $item['allowDrag'] = true; $nodeChildren = Mage::getModel('eav/entity_attribute') - ->getResourceCollection() - ->setAttributeGroupFilter($node->getAttributeGroupId()) - ->addVisibleFilter() - /** - * TODO: issue #5126 - * @see Mage_Eav_Model_Mysql4_Entity_Attribute_Collection - */ - ->checkConfigurableProducts() - ->load(); - - if ( $nodeChildren->getSize() > 0 ) { + ->getResourceCollection() + ->setAttributeGroupFilter($node->getId()) + ->addVisibleFilter() + ->checkConfigurableProducts() + ->load(); + + if ($nodeChildren->getSize() > 0) { $item['children'] = array(); - foreach( $nodeChildren->getItems() as $child ) { - $tmpArr = array(); - $tmpArr['text'] = $child->getAttributeCode(); - $tmpArr['id'] = $child->getAttributeId(); - $tmpArr['cls'] = ( $child->getIsUserDefined() == 0 ) ? 'system-leaf' : 'leaf'; - $tmpArr['allowDrop'] = false; - $tmpArr['allowDrag'] = true; - $tmpArr['leaf'] = true; - $tmpArr['is_user_defined'] = $child->getIsUserDefined(); - // TODO: issue #5126. Template already has reuqired changes - $tmpArr['is_used_in_configurable'] = false; // (bool)$child->getIsUsedInConfigurable(); // TODO: issue #5126 - $tmpArr['entity_id'] = $child->getEntityAttributeId(); - - $item['children'][] = $tmpArr; + foreach ($nodeChildren->getItems() as $child) { + /* @var $child Mage_Eav_Model_Entity_Attribute */ + $attr = array( + 'text' => $child->getAttributeCode(), + 'id' => $child->getAttributeId(), + 'cls' => (!$child->getIsUserDefined()) ? 'system-leaf' : 'leaf', + 'allowDrop' => false, + 'allowDrag' => true, + 'leaf' => true, + 'is_user_defined' => $child->getIsUserDefined(), + 'is_configurable' => (int)in_array($child->getAttributeId(), $configurable), + 'entity_id' => $child->getEntityId() + ); + + $item['children'][] = $attr; } } $items[] = $item; } - return Zend_Json::encode($items); + return Mage::helper('core')->jsonEncode($items); } + /** + * Retrieve Unused in Attribute Set Attribute Tree as JSON + * + * @return string + */ public function getAttributeTreeJson() { + $items = array(); $setId = $this->_getSetId(); - $attributesIdsObj = Mage::getModel('eav/entity_attribute') - ->getResourceCollection() - ->setAttributeSetFilter($setId) - ->load(); + $collection = Mage::getModel('eav/entity_attribute') + ->getResourceCollection() + ->setAttributeSetFilter($setId) + ->load(); + $attributesIds = array('0'); - foreach( $attributesIdsObj->getItems() as $item ) { + /* @var $item Mage_Eav_Model_Entity_Attribute */ + foreach ($collection->getItems() as $item) { $attributesIds[] = $item->getAttributeId(); } - $attributes = Mage::getModel('eav/entity_attribute') - ->getResourceCollection() - ->setEntityTypeFilter(Mage::registry('entityType')) - ->setAttributesExcludeFilter($attributesIds) - ->addVisibleFilter() - ->load(); - $items = array(); - foreach( $attributes as $node ) { - $item = array(); - $item['text']= $node->getAttributeCode(); - $item['id'] = $node->getAttributeId(); - $item['cls'] = 'leaf'; - $item['allowDrop'] = false; - $item['allowDrag'] = true; - $item['leaf'] = true; - $item['is_user_defined'] = $node->getIsUserDefined(); - $item['is_used_in_configurable'] = false; + $attributes = Mage::getModel('eav/entity_attribute') + ->getResourceCollection() + ->setEntityTypeFilter(Mage::registry('entityType')) + ->setAttributesExcludeFilter($attributesIds) + ->addVisibleFilter() + ->load(); + + foreach ($attributes as $child) { + $attr = array( + 'text' => $child->getAttributeCode(), + 'id' => $child->getAttributeId(), + 'cls' => 'leaf', + 'allowDrop' => false, + 'allowDrag' => true, + 'leaf' => true, + 'is_user_defined' => $child->getIsUserDefined(), + 'is_configurable' => false, + 'entity_id' => $child->getEntityId() + ); - $items[] = $item; + $items[] = $attr; } - if( count($items) == 0 ) { + if (count($items) == 0) { $items[] = array( - 'text' => Mage::helper('catalog')->__('Empty'), - 'id' => 'empty', - 'cls' => 'folder', + 'text' => Mage::helper('catalog')->__('Empty'), + 'id' => 'empty', + 'cls' => 'folder', 'allowDrop' => false, 'allowDrag' => false, ); } - return Zend_Json::encode($items); + return Mage::helper('core')->jsonEncode($items); } + /** + * Retrieve Back Button HTML + * + * @return string + */ public function getBackButtonHtml() { return $this->getChildHtml('back_button'); } + /** + * Retrieve Reset Button HTML + * + * @return string + */ public function getResetButtonHtml() { return $this->getChildHtml('reset_button'); } + /** + * Retrieve Save Button HTML + * + * @return string + */ public function getSaveButtonHtml() { return $this->getChildHtml('save_button'); } + /** + * Retrieve Delete Button HTML + * + * @return string + */ public function getDeleteButtonHtml() { if ($this->getIsCurrentSetDefault()) { @@ -255,26 +320,61 @@ public function getDeleteButtonHtml() return $this->getChildHtml('delete_button'); } + /** + * Retrieve Delete Group Button HTML + * + * @return string + */ public function getDeleteGroupButton() { return $this->getChildHtml('delete_group_button'); } + /** + * Retrieve Add New Group Button HTML + * + * @return string + */ public function getAddGroupButton() { return $this->getChildHtml('add_group_button'); } + /** + * Retrieve Rename Button HTML + * + * @return string + */ public function getRenameButton() { return $this->getChildHtml('rename_button'); } + /** + * Retrieve current Attribute Set object + * + * @return Mage_Eav_Model_Entity_Attribute_Set + */ + protected function _getAttributeSet() + { + return Mage::registry('current_attribute_set'); + } + + /** + * Retrieve current attribute set Id + * + * @return int + */ protected function _getSetId() { - return Mage::registry('current_attribute_set')->getId(); + return $this->_getAttributeSet()->getId(); } + /** + * Check Current Attribute Set is a default + * + * @return bool + */ public function getIsCurrentSetDefault() { $isDefault = $this->getData('is_current_set_default'); @@ -288,14 +388,25 @@ public function getIsCurrentSetDefault() return $isDefault; } + /** + * Retrieve current Attribute Set object + * + * @deprecated use _getAttributeSet + * @return Mage_Eav_Model_Entity_Attribute_Set + */ protected function _getSetData() { - return Mage::getModel('eav/entity_attribute_set')->load( $this->_getSetId() ); + return $this->_getAttributeSet(); } + /** + * Prepare HTML + * + * @return string + */ protected function _toHtml() { Mage::dispatchEvent('adminhtml_catalog_product_attribute_set_main_html_before', array('block' => $this)); return parent::_toHtml(); } -} \ No newline at end of file +} diff --git a/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Created.php b/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Created.php index 606f30e16d..318412ac26 100644 --- a/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Created.php +++ b/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Created.php @@ -1,152 +1,152 @@ - - */ -class Mage_Adminhtml_Block_Catalog_Product_Created extends Mage_Adminhtml_Block_Widget -{ - protected $_configurableProduct; - protected $_product; - - public function __construct() - { - parent::__construct(); - $this->setTemplate('catalog/product/created.phtml'); - } - - - protected function _prepareLayout() - { - $this->setChild( - 'close_button', - $this->getLayout()->createBlock('adminhtml/widget_button') - ->setData(array( - 'label' => Mage::helper('catalog')->__('Close Window'), - 'onclick' => 'addProduct(true)' - )) - ); - } - - - public function getCloseButtonHtml() - { - return $this->getChildHtml('close_button'); - } - - public function getProductId() - { - return (int) $this->getRequest()->getParam('id'); - } - - /** - * Indentifies edit mode of popup - * - * @return boolean - */ - public function isEdit() - { - return (bool) $this->getRequest()->getParam('edit'); - } - - /** - * Retrive serialized json with configurable attributes values of simple - * - * @return string - */ - public function getAttributesJson() - { - $result = array(); - foreach ($this->getAttributes() as $attribute) { - $value = $this->getProduct()->getAttributeText($attribute->getAttributeCode()); - - $result[] = array( - 'label' => $value, - 'value_index' => $this->getProduct()->getData($attribute->getAttributeCode()), - 'attribute_id' => $attribute->getId() - ); - } - - return Zend_Json::encode($result); - } - - public function getAttributes() - { - if ($this->getConfigurableProduct()->getId()) { - return $this->getConfigurableProduct()->getTypeInstance(true)->getUsedProductAttributes($this->getConfigurableProduct()); - } - - $attributes = array(); - - $attributesIds = $this->getRequest()->getParam('required'); - if ($attributesIds) { - $attributesIds = explode(',', $attributesIds); - foreach ($attributesIds as $attributeId) { - $attribute = $this->getProduct()->getTypeInstance(true)->getAttributeById($attributeId, $this->getProduct()); - if (!$attribute) { - continue; - } - $attributes[] = $attribute; - } - } - - return $attributes; - } - - /** - * Retrive configurable product for created/edited simple - * - * @return Mage_Catalog_Model_Product - */ - public function getConfigurableProduct() - { - if (is_null($this->_configurableProduct)) { - $this->_configurableProduct = Mage::getModel('catalog/product') - ->setStore(0) - ->load($this->getRequest()->getParam('product')); - } - return $this->_configurableProduct; - } - - /** - * Retrive product - * - * @return Mage_Catalog_Model_Product - */ - public function getProduct() - { - if (is_null($this->_product)) { - $this->_product = Mage::getModel('catalog/product') - ->setStore(0) - ->load($this->getRequest()->getParam('id')); - } - return $this->_product; - } + + */ +class Mage_Adminhtml_Block_Catalog_Product_Created extends Mage_Adminhtml_Block_Widget +{ + protected $_configurableProduct; + protected $_product; + + public function __construct() + { + parent::__construct(); + $this->setTemplate('catalog/product/created.phtml'); + } + + + protected function _prepareLayout() + { + $this->setChild( + 'close_button', + $this->getLayout()->createBlock('adminhtml/widget_button') + ->setData(array( + 'label' => Mage::helper('catalog')->__('Close Window'), + 'onclick' => 'addProduct(true)' + )) + ); + } + + + public function getCloseButtonHtml() + { + return $this->getChildHtml('close_button'); + } + + public function getProductId() + { + return (int) $this->getRequest()->getParam('id'); + } + + /** + * Indentifies edit mode of popup + * + * @return boolean + */ + public function isEdit() + { + return (bool) $this->getRequest()->getParam('edit'); + } + + /** + * Retrive serialized json with configurable attributes values of simple + * + * @return string + */ + public function getAttributesJson() + { + $result = array(); + foreach ($this->getAttributes() as $attribute) { + $value = $this->getProduct()->getAttributeText($attribute->getAttributeCode()); + + $result[] = array( + 'label' => $value, + 'value_index' => $this->getProduct()->getData($attribute->getAttributeCode()), + 'attribute_id' => $attribute->getId() + ); + } + + return Mage::helper('core')->jsonEncode($result); + } + + public function getAttributes() + { + if ($this->getConfigurableProduct()->getId()) { + return $this->getConfigurableProduct()->getTypeInstance(true)->getUsedProductAttributes($this->getConfigurableProduct()); + } + + $attributes = array(); + + $attributesIds = $this->getRequest()->getParam('required'); + if ($attributesIds) { + $attributesIds = explode(',', $attributesIds); + foreach ($attributesIds as $attributeId) { + $attribute = $this->getProduct()->getTypeInstance(true)->getAttributeById($attributeId, $this->getProduct()); + if (!$attribute) { + continue; + } + $attributes[] = $attribute; + } + } + + return $attributes; + } + + /** + * Retrive configurable product for created/edited simple + * + * @return Mage_Catalog_Model_Product + */ + public function getConfigurableProduct() + { + if (is_null($this->_configurableProduct)) { + $this->_configurableProduct = Mage::getModel('catalog/product') + ->setStore(0) + ->load($this->getRequest()->getParam('product')); + } + return $this->_configurableProduct; + } + + /** + * Retrive product + * + * @return Mage_Catalog_Model_Product + */ + public function getProduct() + { + if (is_null($this->_product)) { + $this->_product = Mage::getModel('catalog/product') + ->setStore(0) + ->load($this->getRequest()->getParam('id')); + } + return $this->_product; + } } // Class Mage_Adminhtml_Block_Catalog_Product_Created End \ No newline at end of file diff --git a/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/Tab/Attributes/Create.php b/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/Tab/Attributes/Create.php index bb71e28d03..ec7caee367 100644 --- a/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/Tab/Attributes/Create.php +++ b/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/Tab/Attributes/Create.php @@ -90,7 +90,7 @@ protected function _toHtml() $html = parent::_toHtml(); $html .= Mage::helper('adminhtml/js')->getScript( "var {$this->getJsObjectName()} = new Product.Attributes('{$this->getId()}');\n" - . "{$this->getJsObjectName()}.setConfig(" . Zend_Json::encode($this->getConfig()->getData()) . ");\n" + . "{$this->getJsObjectName()}.setConfig(" . Mage::helper('core')->jsonEncode($this->getConfig()->getData()) . ");\n" ); return $html; diff --git a/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/Tab/Categories.php b/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/Tab/Categories.php index 009f8efcc8..4d99e52969 100644 --- a/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/Tab/Categories.php +++ b/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/Tab/Categories.php @@ -192,7 +192,7 @@ public function getCategoryChildrenJson($categoryId) $children[] = $this->_getNodeJson($child); } - return Zend_Json::encode($children); + return Mage::helper('core')->jsonEncode($children); } public function getLoadTreeUrl($expanded=null) diff --git a/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/Tab/Super/Config.php b/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/Tab/Super/Config.php index 29f90a807c..43bdf22d78 100644 --- a/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/Tab/Super/Config.php +++ b/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/Tab/Super/Config.php @@ -126,7 +126,7 @@ public function getAttributesJson() if(!$attributes) { return '[]'; } - return Zend_Json::encode($attributes); + return Mage::helper('core')->jsonEncode($attributes); } /** @@ -145,7 +145,7 @@ public function getLinksJson() foreach ($products as $product) { $data[$product->getId()] = $this->getConfigurableSettings($product); } - return Zend_Json::encode($data); + return Mage::helper('core')->jsonEncode($data); } /** diff --git a/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/Tab/Super/Config/Grid/Renderer/Checkbox.php b/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/Tab/Super/Config/Grid/Renderer/Checkbox.php index ab1c58aff6..49d14c62a2 100644 --- a/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/Tab/Super/Config/Grid/Renderer/Checkbox.php +++ b/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/Tab/Super/Config/Grid/Renderer/Checkbox.php @@ -67,6 +67,6 @@ public function getAttributesJson(Varien_Object $row) $result[] = $item; } - return Zend_Json::encode($result); + return Mage::helper('core')->jsonEncode($result); } }// Class Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Super_Config_Grid_Renderer_Checkbox END \ No newline at end of file diff --git a/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Helper/Form/Gallery/Content.php b/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Helper/Form/Gallery/Content.php index 83b36bc35c..6bd38b042a 100644 --- a/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Helper/Form/Gallery/Content.php +++ b/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Helper/Form/Gallery/Content.php @@ -104,7 +104,7 @@ public function getImagesJson() $image['url'] = Mage::getSingleton('catalog/product_media_config') ->getMediaUrl($image['file']); } - return Zend_Json::encode($value['images']); + return Mage::helper('core')->jsonEncode($value['images']); } } return '[]'; @@ -119,7 +119,7 @@ public function getImagesValuesJson() $attribute->getAttributeCode() ); } - return Zend_Json::encode($values); + return Mage::helper('core')->jsonEncode($values); } /** @@ -164,7 +164,7 @@ public function getMediaAttributes() public function getImageTypesJson() { - return Zend_Json::encode($this->getImageTypes()); + return Mage::helper('core')->jsonEncode($this->getImageTypes()); } } diff --git a/app/code/core/Mage/Adminhtml/Block/Customer/Edit/Renderer/Region.php b/app/code/core/Mage/Adminhtml/Block/Customer/Edit/Renderer/Region.php index bdffd13d39..586c120073 100644 --- a/app/code/core/Mage/Adminhtml/Block/Customer/Edit/Renderer/Region.php +++ b/app/code/core/Mage/Adminhtml/Block/Customer/Edit/Renderer/Region.php @@ -42,6 +42,7 @@ public function render(Varien_Data_Form_Element_Abstract $element) } $regionId = $element->getForm()->getElement('region_id')->getValue(); + $postcode = $element->getForm()->getElement('postcode'); $html = ''; $element->setClass('input-text'); @@ -54,9 +55,23 @@ public function render(Varien_Data_Form_Element_Abstract $element) $html.= ''; $html.= ''; $html.= ''; $html.= ''."\n"; return $html; diff --git a/app/code/core/Mage/Adminhtml/Block/Customer/Edit/Tab/Account.php b/app/code/core/Mage/Adminhtml/Block/Customer/Edit/Tab/Account.php index 2d17235dcd..bcde34a2d9 100644 --- a/app/code/core/Mage/Adminhtml/Block/Customer/Edit/Tab/Account.php +++ b/app/code/core/Mage/Adminhtml/Block/Customer/Edit/Tab/Account.php @@ -132,16 +132,24 @@ public function initForm() 'name' => 'sendemail', 'id' => 'sendemail', )); + if (!Mage::app()->isSingleStoreMode()) { + $fieldset->addField('store_id', 'select', array( + 'label' => $this->helper('customer')->__('Send From'), + 'name' => 'store_id', + 'values' => Mage::getSingleton('adminhtml/system_store')->getStoreValuesForForm() + )); + } } - // make sendemail disabled, if website_id has empty value - if ($sendemail = $form->getElement('sendemail')) { + // make sendemail and store_id disabled, if website_id has empty value + if ($sendemail = $form->getElement('store_id')) { $prefix = $form->getHtmlIdPrefix(); $sendemail->setAfterElementHtml( ' '; + echo ''; } echo ''; //print $this->getUrl('*/*/batchFinish', array('id' => $batchModel->getId())); diff --git a/app/code/core/Mage/Adminhtml/Block/Tax/Rule/Grid.php b/app/code/core/Mage/Adminhtml/Block/Tax/Rule/Grid.php index 4ec551f2b1..c10efb02a5 100644 --- a/app/code/core/Mage/Adminhtml/Block/Tax/Rule/Grid.php +++ b/app/code/core/Mage/Adminhtml/Block/Tax/Rule/Grid.php @@ -90,6 +90,7 @@ protected function _prepareColumns() 'index' => 'customer_tax_classes', 'filter_index' => 'ctc.customer_tax_class_id', 'type' => 'options', + 'show_missing_option_values' => true, 'options' => Mage::getModel('tax/class')->getCollection()->setClassTypeFilter('CUSTOMER')->toOptionHash(), ) ); @@ -102,6 +103,7 @@ protected function _prepareColumns() 'index' => 'product_tax_classes', 'filter_index' => 'ptc.product_tax_class_id', 'type' => 'options', + 'show_missing_option_values' => true, 'options' => Mage::getModel('tax/class')->getCollection()->setClassTypeFilter('PRODUCT')->toOptionHash(), ) ); @@ -114,6 +116,7 @@ protected function _prepareColumns() 'index' => 'tax_rates', 'filter_index' => 'rate.tax_calculation_rate_id', 'type' => 'options', + 'show_missing_option_values' => true, 'options' => Mage::getModel('tax/calculation_rate')->getCollection()->toOptionHash(), ) ); diff --git a/app/code/core/Mage/Adminhtml/Block/Urlrewrite.php b/app/code/core/Mage/Adminhtml/Block/Urlrewrite.php index f26a6b94ef..eeaf3cb50a 100644 --- a/app/code/core/Mage/Adminhtml/Block/Urlrewrite.php +++ b/app/code/core/Mage/Adminhtml/Block/Urlrewrite.php @@ -46,8 +46,8 @@ class Mage_Adminhtml_Block_Urlrewrite extends Mage_Adminhtml_Block_Widget_Grid_C */ public function __construct() { - $this->_headerText = Mage::helper('adminhtml')->__('Url Rewrite Management'); - $this->_addButtonLabel = Mage::helper('adminhtml')->__('Add Urlrewrite'); + $this->_headerText = Mage::helper('adminhtml')->__('URL Rewrite Management'); + $this->_addButtonLabel = Mage::helper('adminhtml')->__('Add URL Rewrite'); parent::__construct(); } diff --git a/app/code/core/Mage/Adminhtml/Block/Urlrewrite/Category/Tree.php b/app/code/core/Mage/Adminhtml/Block/Urlrewrite/Category/Tree.php index b6548bb19a..163b2955fa 100644 --- a/app/code/core/Mage/Adminhtml/Block/Urlrewrite/Category/Tree.php +++ b/app/code/core/Mage/Adminhtml/Block/Urlrewrite/Category/Tree.php @@ -67,7 +67,7 @@ public function getTreeArray($parentId = null, $asJson = false, $recursionLevel $result = $this->_getNodesArray($this->getRoot(null, $recursionLevel)); } if ($asJson) { - return Zend_Json::encode($result); + return Mage::helper('core')->jsonEncode($result); } return $result; } diff --git a/app/code/core/Mage/Adminhtml/Block/Urlrewrite/Edit.php b/app/code/core/Mage/Adminhtml/Block/Urlrewrite/Edit.php index 141b7e0e84..a76a9ca295 100644 --- a/app/code/core/Mage/Adminhtml/Block/Urlrewrite/Edit.php +++ b/app/code/core/Mage/Adminhtml/Block/Urlrewrite/Edit.php @@ -87,15 +87,15 @@ protected function _prepareLayout() ); } - $this->_headerText = Mage::helper('adminhtml')->__('Add New Urlrewrite'); + $this->_headerText = Mage::helper('adminhtml')->__('Add New URL Rewrite'); // edit form for existing urlrewrite if ($this->getUrlrewriteId()) { - $this->_headerText = Mage::helper('adminhtml')->__('Edit Urlrewrite'); + $this->_headerText = Mage::helper('adminhtml')->__('Edit URL Rewrite'); $this->_setFormChild(); } elseif ($this->getProductId()) { - $this->_headerText = Mage::helper('adminhtml')->__('Add Urlrewrite for a Product'); + $this->_headerText = Mage::helper('adminhtml')->__('Add URL Rewrite for a Product'); // edit form for product with or without category if ($this->getCategoryId() || !$this->isMode('category')) { @@ -119,7 +119,7 @@ protected function _prepareLayout() } // edit form for category elseif ($this->getCategoryId()) { - $this->_headerText = Mage::helper('adminhtml')->__('Add Urlrewrite for a Category'); + $this->_headerText = Mage::helper('adminhtml')->__('Add URL Rewrite for a Category'); $this->_setFormChild(); } // modes selector and products/categories selectors, as well as edit form for custom urlrewrite diff --git a/app/code/core/Mage/Adminhtml/Block/Urlrewrite/Edit/Form.php b/app/code/core/Mage/Adminhtml/Block/Urlrewrite/Edit/Form.php index fe982f7daa..eabf76556c 100644 --- a/app/code/core/Mage/Adminhtml/Block/Urlrewrite/Edit/Form.php +++ b/app/code/core/Mage/Adminhtml/Block/Urlrewrite/Edit/Form.php @@ -75,7 +75,7 @@ protected function _prepareForm() } $fieldset = $form->addFieldset('base_fieldset', array( - 'legend' => Mage::helper('adminhtml')->__('Urlrewrite Information') + 'legend' => Mage::helper('adminhtml')->__('URL Rewrite Information') )); $fieldset->addField('is_system', 'select', array( diff --git a/app/code/core/Mage/Adminhtml/Block/Urlrewrite/Selector.php b/app/code/core/Mage/Adminhtml/Block/Urlrewrite/Selector.php index f0b1e58b5b..c328c1266a 100644 --- a/app/code/core/Mage/Adminhtml/Block/Urlrewrite/Selector.php +++ b/app/code/core/Mage/Adminhtml/Block/Urlrewrite/Selector.php @@ -72,7 +72,7 @@ public function getModes() */ public function getSelectorLabel() { - return Mage::helper('adminhtml')->__('Create Urlrewrite:'); + return Mage::helper('adminhtml')->__('Create URL Rewrite:'); } /** diff --git a/app/code/core/Mage/Adminhtml/Block/Widget/Button.php b/app/code/core/Mage/Adminhtml/Block/Widget/Button.php index a54c0b1879..772cc66581 100644 --- a/app/code/core/Mage/Adminhtml/Block/Widget/Button.php +++ b/app/code/core/Mage/Adminhtml/Block/Widget/Button.php @@ -61,7 +61,7 @@ protected function _toHtml() . ' onclick="'.$this->getOnClick().'"' . ' style="'.$this->getStyle() .'"' . ($this->getValue()?' value="'.$this->getValue() . '"':'') - . ($this->getDisabled() ? 'disabled="disabled"' : '') + . ($this->getDisabled() ? ' disabled="disabled"' : '') . '>' .$this->getLabel().''.$this->getAfterHtml(); return $html; diff --git a/app/code/core/Mage/Adminhtml/Block/Widget/Grid.php b/app/code/core/Mage/Adminhtml/Block/Widget/Grid.php index b37c891ce8..92051b521d 100644 --- a/app/code/core/Mage/Adminhtml/Block/Widget/Grid.php +++ b/app/code/core/Mage/Adminhtml/Block/Widget/Grid.php @@ -274,6 +274,38 @@ public function addColumn($columnId, $column) return $this; } + /** + * Add column to grid after specified column. + * + * @param string $columnId + * @param array|Varien_Object $column + * @param string $after + * @return Mage_Adminhtml_Block_Widget_Grid + */ + public function addColumnAfter($columnId, $column, $after) + { + $this->addColumn($columnId, $column); + // Moving grid column + $keys = array_keys($this->_columns); + $values = array_values($this->_columns); + $positionCurrent = array_search($columnId, $keys); + + if (array_search($after, $keys) === false || $positionCurrent === false) { + return $this; + } + + $key = array_splice($keys, $positionCurrent, 1); + $value = array_splice($values, $positionCurrent, 1); + $positionTarget = array_search($after, $keys) + 1; + array_splice($keys, $positionTarget, 0, $key); + array_splice($values, $positionTarget, 0, $value); + + $this->_columns = array_combine($keys, $values); + end($this->_columns); + $this->_lastColumnId = key($this->_columns); + return $this; + } + public function getLastColumnId() { return $this->_lastColumnId; diff --git a/app/code/core/Mage/Adminhtml/Block/Widget/Grid/Column.php b/app/code/core/Mage/Adminhtml/Block/Widget/Grid/Column.php index bbcf9a3b10..f690ece8ca 100644 --- a/app/code/core/Mage/Adminhtml/Block/Widget/Grid/Column.php +++ b/app/code/core/Mage/Adminhtml/Block/Widget/Grid/Column.php @@ -125,7 +125,21 @@ public function getHeaderHtmlProperty() */ public function getRowField(Varien_Object $row) { - return $this->getRenderer()->render($row); + $renderedValue = $this->getRenderer()->render($row); + + /* + * if column has determined callback for framing call + * it before give away rendered value + * + * callback_function($renderedValue, $row, $column, $isExport) + * should return new version of rendered value + */ + $frameCallback = $this->getFrameCallback(); + if (is_array($frameCallback)) { + $renderedValue = call_user_func($frameCallback, $renderedValue, $row, $this, false); + } + + return $renderedValue; } /** @@ -136,7 +150,21 @@ public function getRowField(Varien_Object $row) */ public function getRowFieldExport(Varien_Object $row) { - return $this->getRenderer()->renderExport($row); + $renderedValue = $this->getRenderer()->renderExport($row); + + /* + * if column has determined callback for framing call + * it before give away rendered value + * + * callback_function($renderedValue, $row, $column, $isExport) + * should return new version of rendered value + */ + $frameCallback = $this->getFrameCallback(); + if (is_array($frameCallback)) { + $renderedValue = call_user_func($frameCallback, $renderedValue, $row, $this, true); + } + + return $renderedValue; } public function setRenderer($renderer) @@ -328,4 +356,4 @@ public function getExportHeader() } return $this->getHeader(); } -} \ No newline at end of file +} diff --git a/app/code/core/Mage/Adminhtml/Block/Widget/Grid/Column/Renderer/Action.php b/app/code/core/Mage/Adminhtml/Block/Widget/Grid/Column/Renderer/Action.php index e27a37e669..1865727c36 100644 --- a/app/code/core/Mage/Adminhtml/Block/Widget/Grid/Column/Renderer/Action.php +++ b/app/code/core/Mage/Adminhtml/Block/Widget/Grid/Column/Renderer/Action.php @@ -82,7 +82,7 @@ protected function _toOptionHtml($action, Varien_Object $row) $actionCaption = ''; $this->_transformActionData($action, $actionCaption, $row); - $htmlAttibutes = array('value'=>$this->htmlEscape(Zend_Json::encode($action))); + $htmlAttibutes = array('value'=>$this->htmlEscape(Mage::helper('core')->jsonEncode($action))); $actionAttributes->setData($htmlAttibutes); return ''; } diff --git a/app/code/core/Mage/Adminhtml/Block/Widget/Grid/Column/Renderer/Checkbox.php b/app/code/core/Mage/Adminhtml/Block/Widget/Grid/Column/Renderer/Checkbox.php index 23c6649b4d..bceadb0f60 100644 --- a/app/code/core/Mage/Adminhtml/Block/Widget/Grid/Column/Renderer/Checkbox.php +++ b/app/code/core/Mage/Adminhtml/Block/Widget/Grid/Column/Renderer/Checkbox.php @@ -59,18 +59,29 @@ public function render(Varien_Object $row) else { $checked = ($value === $this->getColumn()->getValue()) ? ' checked="checked"' : ''; } - if ($this->getNoObjectId() || $this->getColumn()->getUseIndex()){ - //WTF: why getNoObjectId??? - $v = $value; - } else { + + $disabledValues = $this->getColumn()->getDisabledValues(); + if (is_array($disabledValues)) { + $disabled = in_array($value, $disabledValues) ? ' disabled="disabled"' : ''; + } + else { + $disabled = ($value === $this->getColumn()->getDisabledValue()) ? ' disabled="disabled"' : ''; + } + + $this->setDisabled($disabled); + + if ($this->getNoObjectId() || $this->getColumn()->getUseIndex()){ + $v = $value; + } else { $v = ($row->getId() != "") ? $row->getId():$value; - } + } + return $this->_getCheckboxHtml($v, $checked); } protected function _getCheckboxHtml($value, $checked) { - return ''; + return 'getDisabled().'/>'; } public function renderHeader() @@ -81,8 +92,13 @@ public function renderHeader() $checked = ''; if ($filter = $this->getColumn()->getFilter()) { - $checked = $filter->getValue() ? 'checked="checked"' : ''; + $checked = $filter->getValue() ? ' checked="checked"' : ''; + } + + $disabled = ''; + if ($this->getColumn()->getDisabled()) { + $disabled = ' disabled="disabled"'; } - return ''; + return ''; } } diff --git a/app/code/core/Mage/Adminhtml/Block/Widget/Grid/Massaction/Abstract.php b/app/code/core/Mage/Adminhtml/Block/Widget/Grid/Massaction/Abstract.php index d84e8d7ae7..5e505849b7 100644 --- a/app/code/core/Mage/Adminhtml/Block/Widget/Grid/Massaction/Abstract.php +++ b/app/code/core/Mage/Adminhtml/Block/Widget/Grid/Massaction/Abstract.php @@ -114,7 +114,7 @@ public function getItemsJson() $result[$itemId] = $item->toArray(); } - return Zend_Json::encode($result); + return Mage::helper('core')->jsonEncode($result); } /** @@ -187,7 +187,7 @@ public function getSelectedJson() if($selected = $this->getRequest()->getParam($this->getFormFieldNameInternal())) { $selected = explode(',', $selected); return join(',', $selected); -// return Zend_Json::encode($selected); +// return Mage::helper('core')->jsonEncode($selected); } else { return ''; // return '[]'; @@ -235,7 +235,7 @@ public function getGridIdsJson() if(!empty($gridIds)) { return join(",", $gridIds); - //return Zend_Json::encode($gridIds); + //return Mage::helper('core')->jsonEncode($gridIds); } return ''; //return '[]'; diff --git a/app/code/core/Mage/Adminhtml/Block/Widget/Tabs.php b/app/code/core/Mage/Adminhtml/Block/Widget/Tabs.php index 38044813b2..b7b92ca7d8 100644 --- a/app/code/core/Mage/Adminhtml/Block/Widget/Tabs.php +++ b/app/code/core/Mage/Adminhtml/Block/Widget/Tabs.php @@ -345,7 +345,7 @@ public function getAllShadowTabs($asJson = true) } } if ($asJson) { - return Zend_Json::encode($result); + return Mage::helper('core')->jsonEncode($result); } return $result; } diff --git a/app/code/core/Mage/Adminhtml/Controller/Action.php b/app/code/core/Mage/Adminhtml/Controller/Action.php index 322582f8df..0b96c50644 100644 --- a/app/code/core/Mage/Adminhtml/Controller/Action.php +++ b/app/code/core/Mage/Adminhtml/Controller/Action.php @@ -144,7 +144,7 @@ public function preDispatch() $this->setFlag('', self::FLAG_NO_DISPATCH, true); $this->setFlag('', self::FLAG_NO_POST_DISPATCH, true); if ($this->getRequest()->getQuery('isAjax', false) || $this->getRequest()->getQuery('ajax', false)) { - $this->getResponse()->setBody(Zend_Json::encode(array( + $this->getResponse()->setBody(Mage::helper('core')->jsonEncode(array( 'error' => true, 'message' => $_keyErrorMsg ))); @@ -192,7 +192,7 @@ protected function _checkUrlSettings() if ($defaultSecure == '{{base_url}}' || $defaultUnsecure == '{{base_url}}') { $this->_getSession()->addNotice( - $this->__('{{base_url}} is not recommended to use in a production environment to declare the Base Unsecure Url / Base Secure Url. It is highly recommended to change this value in your Magento configuration.', $this->getUrl('adminhtml/system_config/edit', array('section'=>'web'))) + $this->__('{{base_url}} is not recommended to use in a production environment to declare the Base Unsecure URL / Base Secure URL. It is highly recommended to change this value in your Magento configuration.', $this->getUrl('adminhtml/system_config/edit', array('section'=>'web'))) ); return $this; } @@ -213,7 +213,7 @@ protected function _checkUrlSettings() if ($url) { $this->_getSession()->addNotice( - $this->__('{{base_url}} is not recommended to use in a production environment to declare the Base Unsecure Url / Base Secure Url. It is highly recommended to change this value in your Magento configuration.', $url) + $this->__('{{base_url}} is not recommended to use in a production environment to declare the Base Unsecure URL / Base Secure URL. It is highly recommended to change this value in your Magento configuration.', $url) ); return $this; } diff --git a/app/code/core/Mage/Adminhtml/Helper/Dashboard/Data.php b/app/code/core/Mage/Adminhtml/Helper/Dashboard/Data.php index b025f803e0..efa04da104 100644 --- a/app/code/core/Mage/Adminhtml/Helper/Dashboard/Data.php +++ b/app/code/core/Mage/Adminhtml/Helper/Dashboard/Data.php @@ -56,7 +56,7 @@ public function getDatePeriods() return array( '24h'=>$this->__('Last 24 hours'), '7d'=>$this->__('Last 7 days'), - '1m'=>$this->__('Last Month'), + '1m'=>$this->__('Month-To-Date'), '1y'=>$this->__('YTD'), '2y'=>$this->__('2YTD') ); diff --git a/app/code/core/Mage/Adminhtml/Model/Observer.php b/app/code/core/Mage/Adminhtml/Model/Observer.php index df4a9b41e8..4633ac3471 100644 --- a/app/code/core/Mage/Adminhtml/Model/Observer.php +++ b/app/code/core/Mage/Adminhtml/Model/Observer.php @@ -60,7 +60,7 @@ public function massactionPrepareKey() { $request = Mage::app()->getFrontController()->getRequest(); if ($key = $request->getPost('massaction_prepare_key')) { - $value = is_array($request->getPost($key)) ? $request->getPost($key) : split(',', $request->getPost($key)); + $value = is_array($request->getPost($key)) ? $request->getPost($key) : explode(',', $request->getPost($key)); $request->setPost($key, $value ? $value : null); } return $this; diff --git a/app/code/core/Mage/Adminhtml/Model/Sales/Order/Create.php b/app/code/core/Mage/Adminhtml/Model/Sales/Order/Create.php index aab7bd5e4c..e3e654c568 100644 --- a/app/code/core/Mage/Adminhtml/Model/Sales/Order/Create.php +++ b/app/code/core/Mage/Adminhtml/Model/Sales/Order/Create.php @@ -420,8 +420,6 @@ public function moveQuoteItem($item, $moveTo, $qty) $product->unsSkipCheckRequiredOption(); $newItem->checkData(); $newItem->setQty($qty); - $this->getQuote()->collectTotals() - ->save(); break; case 'cart': if (($cart = $this->getCustomerCart()) && is_null($item->getOptionByCode('additional_options'))) { @@ -1123,7 +1121,7 @@ protected function _validate() { $customerId = $this->getSession()->getCustomerId(); if (is_null($customerId)) { - Mage::throwException(Mage::helper('adminhtml')->__('Please select a custmer')); + Mage::throwException(Mage::helper('adminhtml')->__('Please select a customer')); } if (!$this->getSession()->getStore()->getId()) { diff --git a/app/code/core/Mage/Adminhtml/Model/Search/Catalog.php b/app/code/core/Mage/Adminhtml/Model/Search/Catalog.php index 5b57b35d57..6070efa804 100644 --- a/app/code/core/Mage/Adminhtml/Model/Search/Catalog.php +++ b/app/code/core/Mage/Adminhtml/Model/Search/Catalog.php @@ -36,7 +36,7 @@ public function load() return $this; } - $collection = Mage::helper('catalogSearch')->getQuery()->getResultCollection() + $collection = Mage::helper('catalogsearch')->getQuery()->getResultCollection() ->addAttributeToSelect('name') ->addAttributeToSelect('description') ->addSearchFilter($this->getQuery()) diff --git a/app/code/core/Mage/Adminhtml/Model/System/Config/Backend/Currency/Abstract.php b/app/code/core/Mage/Adminhtml/Model/System/Config/Backend/Currency/Abstract.php index 1abd9e1602..75415d4c19 100644 --- a/app/code/core/Mage/Adminhtml/Model/System/Config/Backend/Currency/Abstract.php +++ b/app/code/core/Mage/Adminhtml/Model/System/Config/Backend/Currency/Abstract.php @@ -44,7 +44,7 @@ abstract class Mage_Adminhtml_Model_System_Config_Backend_Currency_Abstract exte protected function _getAllowedCurrencies() { if ($this->getData('groups/options/fields/allow/inherit')) { - return split(',', Mage::getConfig()->getNode('currency/options/allow', $this->getScope(), $this->getScopeId())); + return explode(',', Mage::getConfig()->getNode('currency/options/allow', $this->getScope(), $this->getScopeId())); } return $this->getData('groups/options/fields/allow/value'); } @@ -56,7 +56,7 @@ protected function _getAllowedCurrencies() */ protected function _getInstalledCurrencies() { - return split(',', Mage::getStoreConfig('system/currency/installed')); + return explode(',', Mage::getStoreConfig('system/currency/installed')); } /** diff --git a/app/code/core/Mage/Adminhtml/Model/System/Config/Backend/Currency/Cron.php b/app/code/core/Mage/Adminhtml/Model/System/Config/Backend/Currency/Cron.php index cf26d3a998..9358402af3 100644 --- a/app/code/core/Mage/Adminhtml/Model/System/Config/Backend/Currency/Cron.php +++ b/app/code/core/Mage/Adminhtml/Model/System/Config/Backend/Currency/Cron.php @@ -41,7 +41,7 @@ protected function _afterSave() $enabled = $this->getData('groups/import/fields/enabled/value'); $service = $this->getData('groups/import/fields/service/value'); $time = $this->getData('groups/import/fields/time/value'); - $frequncy = $this->getData('groups/import/fields/frequncy/value'); + $frequency = $this->getData('groups/import/fields/frequency/value'); $errorEmail = $this->getData('groups/import/fields/error_email/value'); $frequencyDaily = Mage_Adminhtml_Model_System_Config_Source_Cron_Frequency::CRON_DAILY; @@ -53,9 +53,9 @@ protected function _afterSave() $cronExprArray = array( intval($time[1]), # Minute intval($time[0]), # Hour - ($frequncy == $frequencyMonthly) ? '1' : '*', # Day of the Month + ($frequency == $frequencyMonthly) ? '1' : '*', # Day of the Month '*', # Month of the Year - ($frequncy == $frequencyWeekly) ? '1' : '*', # Day of the Week + ($frequency == $frequencyWeekly) ? '1' : '*', # Day of the Week ); $cronExprString = join(' ', $cronExprArray); diff --git a/app/code/core/Mage/Adminhtml/Model/System/Config/Backend/Email/Sender.php b/app/code/core/Mage/Adminhtml/Model/System/Config/Backend/Email/Sender.php index 8e8e368af8..eb129ad66f 100644 --- a/app/code/core/Mage/Adminhtml/Model/System/Config/Backend/Email/Sender.php +++ b/app/code/core/Mage/Adminhtml/Model/System/Config/Backend/Email/Sender.php @@ -37,8 +37,8 @@ class Mage_Adminhtml_Model_System_Config_Backend_Email_Sender extends Mage_Core_ protected function _beforeSave() { $value = $this->getValue(); - if (!preg_match("/^[A-Za-z0-9_\s]+$/", $value)) { - Mage::throwException(Mage::helper('adminhtml')->__('Invalid sender name "%s"', $value)); + if (!preg_match("/^[\S ]+$/", $value)) { + Mage::throwException(Mage::helper('adminhtml')->__('Invalid sender name "%s". Please use only visible characters and spaces.', $value)); } return $this; } diff --git a/app/code/core/Mage/Adminhtml/Model/System/Config/Backend/Locale.php b/app/code/core/Mage/Adminhtml/Model/System/Config/Backend/Locale.php index fe48b7aa43..3cc42063e3 100644 --- a/app/code/core/Mage/Adminhtml/Model/System/Config/Backend/Locale.php +++ b/app/code/core/Mage/Adminhtml/Model/System/Config/Backend/Locale.php @@ -46,7 +46,7 @@ protected function _afterSave() ->getCollection() ->addPathFilter('currency/options'); - $values = split(',', $this->getValue()); + $values = explode(',', $this->getValue()); $exceptions = array(); foreach ($collection as $data) { $match = false; diff --git a/app/code/core/Mage/Adminhtml/Model/System/Config/Source/Checktype.php b/app/code/core/Mage/Adminhtml/Model/System/Config/Source/Checktype.php index 2a0240bce5..e3b27215b9 100644 --- a/app/code/core/Mage/Adminhtml/Model/System/Config/Source/Checktype.php +++ b/app/code/core/Mage/Adminhtml/Model/System/Config/Source/Checktype.php @@ -18,20 +18,38 @@ * versions in the future. If you wish to customize Magento for your * needs please refer to http://www.magentocommerce.com for more information. * - * @category Mage - * @package Mage_Adminhtml - * @copyright Copyright (c) 2008 Irubin Consulting Inc. DBA Varien (http://www.varien.com) - * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @category Mage + * @package Mage_Adminhtml + * @copyright Copyright (c) 2009 Irubin Consulting Inc. DBA Varien (http://www.varien.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ +/** + * Send to a Friend Limit sending by Source + * + * @category Mage + * @package Mage_Adminhtml + * @author Magento Core Team + */ class Mage_Adminhtml_Model_System_Config_Source_Checktype { + /** + * Retrieve Check Type Option array + * + * @return array + */ public function toOptionArray() { return array( - array('value'=>0, 'label'=>Mage::helper('adminhtml')->__('IP Address')), - array('value'=>1, 'label'=>Mage::helper('adminhtml')->__('Cookie (Unsafe)')), + array( + 'value' => Mage_Sendfriend_Helper_Data::CHECK_IP, + 'label' => Mage::helper('adminhtml')->__('IP Address') + ), + array( + 'value' => Mage_Sendfriend_Helper_Data::CHECK_COOKIE, + 'label' => Mage::helper('adminhtml')->__('Cookie (Unsafe)') + ), ); } -} \ No newline at end of file +} diff --git a/app/code/core/Mage/Adminhtml/Model/System/Config/Source/Watermark/Position.php b/app/code/core/Mage/Adminhtml/Model/System/Config/Source/Watermark/Position.php index db04ee4d7e..82e1d7c7f1 100644 --- a/app/code/core/Mage/Adminhtml/Model/System/Config/Source/Watermark/Position.php +++ b/app/code/core/Mage/Adminhtml/Model/System/Config/Source/Watermark/Position.php @@ -49,6 +49,7 @@ public function toOptionArray() array('value' => 'top-right', 'label' => Mage::helper('catalog')->__('Top/Right')), array('value' => 'bottom-left', 'label' => Mage::helper('catalog')->__('Bottom/Left')), array('value' => 'bottom-right', 'label' => Mage::helper('catalog')->__('Bottom/Right')), + array('value' => 'center', 'label' => Mage::helper('catalog')->__('Center')), ); } diff --git a/app/code/core/Mage/Adminhtml/Model/Url.php b/app/code/core/Mage/Adminhtml/Model/Url.php index c474df6183..2915ee133f 100644 --- a/app/code/core/Mage/Adminhtml/Model/Url.php +++ b/app/code/core/Mage/Adminhtml/Model/Url.php @@ -69,8 +69,13 @@ public function setRouteParams(array $data, $unsetOldParams=true) */ public function getUrl($routePath=null, $routeParams=null) { - $result = parent::getUrl($routePath, $routeParams); + $cacheSecretKey = false; + if (is_array($routeParams) && isset($routeParams['_cache_secret_key'])) { + unset($routeParams['_cache_secret_key']); + $cacheSecretKey = true; + } + $result = parent::getUrl($routePath, $routeParams); if (!$this->useSecretKey()) { return $result; } @@ -78,7 +83,13 @@ public function getUrl($routePath=null, $routeParams=null) $_route = $this->getRouteName() ? $this->getRouteName() : '*'; $_controller = $this->getControllerName() ? $this->getControllerName() : $this->getDefaultControllerName(); $_action = $this->getActionName() ? $this->getActionName() : $this->getDefaultActionName(); - $secret = array(self::SECRET_KEY_PARAM_NAME => $this->getSecretKey($_controller, $_action)); + + if ($cacheSecretKey) { + $secret = array(self::SECRET_KEY_PARAM_NAME => "\${$_controller}/{$_action}\$"); + } + else { + $secret = array(self::SECRET_KEY_PARAM_NAME => $this->getSecretKey($_controller, $_action)); + } if (is_array($routeParams)) { $routeParams = array_merge($secret, $routeParams); } else { @@ -87,6 +98,7 @@ public function getUrl($routePath=null, $routeParams=null) if (is_array($this->getRouteParams())) { $routeParams = array_merge($this->getRouteParams(), $routeParams); } + return parent::getUrl("{$_route}/{$_controller}/{$_action}", $routeParams); } diff --git a/app/code/core/Mage/Adminhtml/controllers/Catalog/CategoryController.php b/app/code/core/Mage/Adminhtml/controllers/Catalog/CategoryController.php index 73ec707e44..b208cf163a 100644 --- a/app/code/core/Mage/Adminhtml/controllers/Catalog/CategoryController.php +++ b/app/code/core/Mage/Adminhtml/controllers/Catalog/CategoryController.php @@ -246,6 +246,15 @@ public function saveAction() } } + /** + * Process "Use Config Settings" checkboxes + */ + if ($useConfig = $this->getRequest()->getPost('use_config')) { + foreach ($useConfig as $attributeCode) { + $category->setData($attributeCode, null); + } + } + $category->setAttributeSetId($category->getDefaultAttributeSetId()); if (isset($data['category_products']) && @@ -370,7 +379,7 @@ public function treeAction() $block = $this->getLayout()->createBlock('adminhtml/catalog_category_tree'); $root = $block->getRoot(); - $this->getResponse()->setBody(Zend_Json::encode(array( + $this->getResponse()->setBody(Mage::helper('core')->jsonEncode(array( 'data' => $block->getTree(), 'parameters' => array( 'text' => $block->buildNodeName($root), @@ -384,8 +393,24 @@ public function treeAction() )))); } + /** + * Build response for refresh input element 'path' in form + */ + public function refreshPathAction() + { + if ($id = (int) $this->getRequest()->getParam('id')) { + $category = Mage::getModel('catalog/category')->load($id); + $this->getResponse()->setBody( + Mage::helper('core')->jsonEncode(array( + 'id' => $id, + 'path' => $category->getPath(), + )) + ); + } + } + protected function _isAllowed() { - return Mage::getSingleton('admin/session')->isAllowed('catalog/categories'); + return Mage::getSingleton('admin/session')->isAllowed('catalog/categories'); } } diff --git a/app/code/core/Mage/Adminhtml/controllers/Catalog/Product/AttributeController.php b/app/code/core/Mage/Adminhtml/controllers/Catalog/Product/AttributeController.php index d677c4e2a4..5a41353317 100644 --- a/app/code/core/Mage/Adminhtml/controllers/Catalog/Product/AttributeController.php +++ b/app/code/core/Mage/Adminhtml/controllers/Catalog/Product/AttributeController.php @@ -158,6 +158,12 @@ public function saveAction() if (!isset($data['is_configurable'])) { $data['is_configurable'] = 0; } + if (!isset($data['is_filterable'])) { + $data['is_filterable'] = 0; + } + if (!isset($data['is_filterable_in_search'])) { + $data['is_filterable_in_search'] = 0; + } if (is_null($model->getIsUserDefined()) || $model->getIsUserDefined() != 0) { $data['backend_type'] = $model->getBackendTypeByInput($data['frontend_input']); diff --git a/app/code/core/Mage/Adminhtml/controllers/Catalog/Product/GalleryController.php b/app/code/core/Mage/Adminhtml/controllers/Catalog/Product/GalleryController.php index 362853bd20..21525943af 100644 --- a/app/code/core/Mage/Adminhtml/controllers/Catalog/Product/GalleryController.php +++ b/app/code/core/Mage/Adminhtml/controllers/Catalog/Product/GalleryController.php @@ -58,7 +58,7 @@ public function uploadAction() $result = array('error'=>$e->getMessage(), 'errorcode'=>$e->getCode()); } - $this->getResponse()->setBody(Zend_Json::encode($result)); + $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result)); } protected function _isAllowed() diff --git a/app/code/core/Mage/Adminhtml/controllers/Catalog/ProductController.php b/app/code/core/Mage/Adminhtml/controllers/Catalog/ProductController.php index 7fb0d9ad2e..aaeec49e77 100644 --- a/app/code/core/Mage/Adminhtml/controllers/Catalog/ProductController.php +++ b/app/code/core/Mage/Adminhtml/controllers/Catalog/ProductController.php @@ -515,10 +515,10 @@ protected function _initProductSave() * Initialize data for configurable product */ if (($data = $this->getRequest()->getPost('configurable_products_data')) && !$product->getConfigurableReadonly()) { - $product->setConfigurableProductsData(Zend_Json::decode($data)); + $product->setConfigurableProductsData(Mage::helper('core')->jsonDecode($data)); } if (($data = $this->getRequest()->getPost('configurable_attributes_data')) && !$product->getConfigurableReadonly()) { - $product->setConfigurableAttributesData(Zend_Json::decode($data)); + $product->setConfigurableAttributesData(Mage::helper('core')->jsonDecode($data)); } $product->setCanSaveConfigurableAttributes((bool)$this->getRequest()->getPost('affect_configurable_product_attributes') && !$product->getConfigurableReadonly()); @@ -893,7 +893,7 @@ public function quickCreateAction() ); } - $this->getResponse()->setBody(Zend_Json::encode($result)); + $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result)); } protected function _isAllowed() diff --git a/app/code/core/Mage/Adminhtml/controllers/CustomerController.php b/app/code/core/Mage/Adminhtml/controllers/CustomerController.php index 9fd89d8fc1..ede6002828 100644 --- a/app/code/core/Mage/Adminhtml/controllers/CustomerController.php +++ b/app/code/core/Mage/Adminhtml/controllers/CustomerController.php @@ -203,15 +203,15 @@ public function saveAction() ); $customer->save(); - // send welcome email if ($customer->getWebsiteId() && $customer->hasData('sendemail')) { + $store_id = $customer->getStoreId(); if ($isNewCustomer) { - $customer->sendNewAccountEmail(); + $customer->sendNewAccountEmail('registered', '', $store_id); } // confirm not confirmed customer elseif ((!$customer->getConfirmation())) { - $customer->sendNewAccountEmail('confirmed'); + $customer->sendNewAccountEmail('confirmed', '', $store_id); } } diff --git a/app/code/core/Mage/Adminhtml/controllers/IndexController.php b/app/code/core/Mage/Adminhtml/controllers/IndexController.php index 88d9ab2124..e455fbec04 100644 --- a/app/code/core/Mage/Adminhtml/controllers/IndexController.php +++ b/app/code/core/Mage/Adminhtml/controllers/IndexController.php @@ -146,7 +146,7 @@ public function deniedJsonAction() protected function _getDeniedJson() { - return Zend_Json::encode( + return Mage::helper('core')->jsonEncode( array( 'ajaxExpired' => 1, 'ajaxRedirect' => $this->getUrl('*/index/login') diff --git a/app/code/core/Mage/Adminhtml/controllers/JsonController.php b/app/code/core/Mage/Adminhtml/controllers/JsonController.php index 3085026309..dcc5882875 100644 --- a/app/code/core/Mage/Adminhtml/controllers/JsonController.php +++ b/app/code/core/Mage/Adminhtml/controllers/JsonController.php @@ -47,6 +47,6 @@ public function countryRegionAction() } } - $this->getResponse()->setBody(Zend_Json::encode($arrRes)); + $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($arrRes)); } } \ No newline at end of file diff --git a/app/code/core/Mage/Adminhtml/controllers/Media/UploaderController.php b/app/code/core/Mage/Adminhtml/controllers/Media/UploaderController.php index a8675a8e9d..c00ea66383 100644 --- a/app/code/core/Mage/Adminhtml/controllers/Media/UploaderController.php +++ b/app/code/core/Mage/Adminhtml/controllers/Media/UploaderController.php @@ -36,7 +36,7 @@ class Mage_Adminhtml_Media_UploaderController extends Mage_Adminhtml_Controller_ public function uploadAction() { - $this->getResponse()->setBody(Zend_Json::encode($_REQUEST)); + $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($_REQUEST)); } public function indexAction() diff --git a/app/code/core/Mage/Adminhtml/controllers/Newsletter/TemplateController.php b/app/code/core/Mage/Adminhtml/controllers/Newsletter/TemplateController.php index 05e1e7c858..4fde237585 100644 --- a/app/code/core/Mage/Adminhtml/controllers/Newsletter/TemplateController.php +++ b/app/code/core/Mage/Adminhtml/controllers/Newsletter/TemplateController.php @@ -116,6 +116,9 @@ public function editAction () public function saveAction () { $request = $this->getRequest(); + if (!$request->isPost()) { + $this->getResponse()->setRedirect($this->getUrl('*/newsletter_template')); + } $template = Mage::getModel('newsletter/template'); if ($id = (int)$request->getParam('id')) { diff --git a/app/code/core/Mage/Adminhtml/controllers/Permissions/UserController.php b/app/code/core/Mage/Adminhtml/controllers/Permissions/UserController.php index 569da7ed70..7968d8b88a 100644 --- a/app/code/core/Mage/Adminhtml/controllers/Permissions/UserController.php +++ b/app/code/core/Mage/Adminhtml/controllers/Permissions/UserController.php @@ -84,6 +84,17 @@ public function saveAction() if ($data = $this->getRequest()->getPost()) { $model = Mage::getModel('admin/user'); $model->setData($data); + + $result = $model->validate(); + if (is_array($result)) { + Mage::getSingleton('adminhtml/session')->setUserData($data); + foreach ($result as $message) { + Mage::getSingleton('adminhtml/session')->addError($message); + } + $this->_redirect('*/*/edit', array('_current' => true)); + return $this; + } + try { $model->save(); if ( $uRoles = $this->getRequest()->getParam('roles', false) ) { @@ -105,7 +116,7 @@ public function saveAction() Mage::getSingleton('adminhtml/session')->setUserData(false); $this->_redirect('*/*/edit', array('user_id' => $model->getUserId())); return; - } catch (Exception $e) { + } catch (Mage_Core_Exception $e) { Mage::getSingleton('adminhtml/session')->addError($e->getMessage()); Mage::getSingleton('adminhtml/session')->setUserData($data); $this->_redirect('*/*/edit', array('user_id' => $model->getUserId())); diff --git a/app/code/core/Mage/Adminhtml/controllers/Promo/QuoteController.php b/app/code/core/Mage/Adminhtml/controllers/Promo/QuoteController.php index cf1d0477c5..a159239baa 100644 --- a/app/code/core/Mage/Adminhtml/controllers/Promo/QuoteController.php +++ b/app/code/core/Mage/Adminhtml/controllers/Promo/QuoteController.php @@ -101,11 +101,12 @@ public function editAction() public function saveAction() { - if ($data = $this->getRequest()->getPost()) { + $data = $this->getRequest()->getPost(); + if ($data) { try { $model = Mage::getModel('salesrule/rule'); - - if ($id = $this->getRequest()->getParam('rule_id')) { + $id = $this->getRequest()->getParam('rule_id'); + if ($id) { $model->load($id); if ($id != $model->getId()) { Mage::throwException(Mage::helper('salesrule')->__('Wrong rule specified.')); @@ -121,14 +122,14 @@ public function saveAction() $data['actions'] = $data['rule']['actions']; } unset($data['rule']); - $model->loadPost($data); - Mage::getSingleton('adminhtml/session')->setPageData($model->getData()); + $session = Mage::getSingleton('adminhtml/session'); + $session->setPageData($model->getData()); $model->save(); - Mage::getSingleton('adminhtml/session')->addSuccess(Mage::helper('salesrule')->__('Rule was successfully saved')); - Mage::getSingleton('adminhtml/session')->setPageData(false); + $session->addSuccess(Mage::helper('salesrule')->__('Rule was successfully saved')); + $session->setPageData(false); $this->_redirect('*/*/'); return; } catch (Exception $e) { diff --git a/app/code/core/Mage/Adminhtml/controllers/Sales/Order/CreateController.php b/app/code/core/Mage/Adminhtml/controllers/Sales/Order/CreateController.php index c8e00a5807..0c6f31d22f 100644 --- a/app/code/core/Mage/Adminhtml/controllers/Sales/Order/CreateController.php +++ b/app/code/core/Mage/Adminhtml/controllers/Sales/Order/CreateController.php @@ -175,7 +175,7 @@ protected function _processData() * Adding products to quote from special grid and */ if ($data = $this->getRequest()->getPost('add_products')) { - $this->_getOrderCreateModel()->addProducts(Zend_Json::decode($data)); + $this->_getOrderCreateModel()->addProducts(Mage::helper('core')->jsonDecode($data)); } /** @@ -236,7 +236,7 @@ protected function _processData() * Importing gift message allow items from specific product grid */ if ($data = $this->getRequest()->getPost('add_products')) { - $this->_getGiftmessageSaveModel()->importAllowQuoteItemsFromProducts(Zend_Json::decode($data)); + $this->_getGiftmessageSaveModel()->importAllowQuoteItemsFromProducts(Mage::helper('core')->jsonDecode($data)); } /** diff --git a/app/code/core/Mage/Adminhtml/controllers/Sales/Order/CreditmemoController.php b/app/code/core/Mage/Adminhtml/controllers/Sales/Order/CreditmemoController.php index 0389e8dd32..605c6130e5 100644 --- a/app/code/core/Mage/Adminhtml/controllers/Sales/Order/CreditmemoController.php +++ b/app/code/core/Mage/Adminhtml/controllers/Sales/Order/CreditmemoController.php @@ -190,14 +190,9 @@ protected function _initCreditmemo($update = false) } if (isset($data['shipping_amount'])) { - $creditmemo->setShippingAmount($data['shipping_amount']); + $creditmemo->setBaseShippingAmount((float)$data['shipping_amount']); } elseif ($invoice) { - $creditmemo->setShippingAmount($invoice->getShippingAmount()); - } - else { - $creditmemo->setShippingAmount( - $order->getBaseShippingAmount()-$order->getBaseShippingRefunded() - ); + $creditmemo->setBaseShippingAmount($invoice->getBaseShippingAmount()); } if (isset($data['adjustment_positive'])) { @@ -295,14 +290,14 @@ public function updateQtyAction() 'error' => true, 'message' => $e->getMessage() ); - $response = Zend_Json::encode($response); + $response = Mage::helper('core')->jsonEncode($response); } catch (Exception $e) { $response = array( 'error' => true, 'message' => $this->__('Can not update item qty') ); - $response = Zend_Json::encode($response); + $response = Mage::helper('core')->jsonEncode($response); } $this->getResponse()->setBody($response); } @@ -435,14 +430,14 @@ public function addCommentAction() 'error' => true, 'message' => $e->getMessage() ); - $response = Zend_Json::encode($response); + $response = Mage::helper('core')->jsonEncode($response); } catch (Exception $e) { $response = array( 'error' => true, 'message' => $this->__('Can not add new comment.') ); - $response = Zend_Json::encode($response); + $response = Mage::helper('core')->jsonEncode($response); } $this->getResponse()->setBody($response); } diff --git a/app/code/core/Mage/Adminhtml/controllers/Sales/Order/InvoiceController.php b/app/code/core/Mage/Adminhtml/controllers/Sales/Order/InvoiceController.php index 5350dc1741..e699c31544 100644 --- a/app/code/core/Mage/Adminhtml/controllers/Sales/Order/InvoiceController.php +++ b/app/code/core/Mage/Adminhtml/controllers/Sales/Order/InvoiceController.php @@ -271,14 +271,14 @@ public function updateQtyAction() 'error' => true, 'message' => $e->getMessage() ); - $response = Zend_Json::encode($response); + $response = Mage::helper('core')->jsonEncode($response); } catch (Exception $e) { $response = array( 'error' => true, 'message' => $this->__('Can not update item qty') ); - $response = Zend_Json::encode($response); + $response = Mage::helper('core')->jsonEncode($response); } $this->getResponse()->setBody($response); } @@ -453,14 +453,14 @@ public function addCommentAction() 'error' => true, 'message' => $e->getMessage() ); - $response = Zend_Json::encode($response); + $response = Mage::helper('core')->jsonEncode($response); } catch (Exception $e) { $response = array( 'error' => true, 'message' => $this->__('Can not add new comment.') ); - $response = Zend_Json::encode($response); + $response = Mage::helper('core')->jsonEncode($response); } $this->getResponse()->setBody($response); } diff --git a/app/code/core/Mage/Adminhtml/controllers/Sales/Order/ShipmentController.php b/app/code/core/Mage/Adminhtml/controllers/Sales/Order/ShipmentController.php index b147784b6f..efdb56b9a6 100644 --- a/app/code/core/Mage/Adminhtml/controllers/Sales/Order/ShipmentController.php +++ b/app/code/core/Mage/Adminhtml/controllers/Sales/Order/ShipmentController.php @@ -288,7 +288,7 @@ public function addTrackAction() ); } if (is_array($response)) { - $response = Zend_Json::encode($response); + $response = Mage::helper('core')->jsonEncode($response); } $this->getResponse()->setBody($response); } @@ -327,7 +327,7 @@ public function removeTrackAction() ); } if (is_array($response)) { - $response = Zend_Json::encode($response); + $response = Mage::helper('core')->jsonEncode($response); } $this->getResponse()->setBody($response); } @@ -368,7 +368,7 @@ public function viewTrackAction() } else { if (is_array($response)) { - $response = Zend_Json::encode($response); + $response = Mage::helper('core')->jsonEncode($response); } $this->getResponse()->setBody($response); @@ -399,14 +399,14 @@ public function addCommentAction() 'error' => true, 'message' => $e->getMessage() ); - $response = Zend_Json::encode($response); + $response = Mage::helper('core')->jsonEncode($response); } catch (Exception $e) { $response = array( 'error' => true, 'message' => $this->__('Can not add new comment.') ); - $response = Zend_Json::encode($response); + $response = Mage::helper('core')->jsonEncode($response); } $this->getResponse()->setBody($response); } diff --git a/app/code/core/Mage/Adminhtml/controllers/Sales/OrderController.php b/app/code/core/Mage/Adminhtml/controllers/Sales/OrderController.php index a5b8131838..79e8b926b0 100644 --- a/app/code/core/Mage/Adminhtml/controllers/Sales/OrderController.php +++ b/app/code/core/Mage/Adminhtml/controllers/Sales/OrderController.php @@ -217,7 +217,7 @@ public function addCommentAction() ); } if (is_array($response)) { - $response = Zend_Json::encode($response); + $response = Mage::helper('core')->jsonEncode($response); $this->getResponse()->setBody($response); } } diff --git a/app/code/core/Mage/Adminhtml/controllers/System/AccountController.php b/app/code/core/Mage/Adminhtml/controllers/System/AccountController.php index 00cd23b06a..43ec1f6313 100644 --- a/app/code/core/Mage/Adminhtml/controllers/System/AccountController.php +++ b/app/code/core/Mage/Adminhtml/controllers/System/AccountController.php @@ -42,6 +42,9 @@ public function indexAction() $this->renderLayout(); } + /** + * Saving edited user information + */ public function saveAction() { $userId = Mage::getSingleton('admin/session')->getUser()->getId(); @@ -53,36 +56,33 @@ public function saveAction() ->setFirstname($this->getRequest()->getParam('firstname', false)) ->setLastname($this->getRequest()->getParam('lastname', false)) ->setEmail(strtolower($this->getRequest()->getParam('email', false))); - if ( $this->getRequest()->getParam('password', false) ) { - $user->setPassword($this->getRequest()->getParam('password', false)); + if ( $this->getRequest()->getParam('new_password', false) ) { + $user->setNewPassword($this->getRequest()->getParam('new_password', false)); } - try { - try { - $_isValid = Zend_Validate::is($user->getUsername(), 'NotEmpty') - && Zend_Validate::is($user->getFirstname(), 'NotEmpty') - && Zend_Validate::is($user->getLastname(), 'NotEmpty') - && Zend_Validate::is($user->getEmail(), 'EmailAddress'); + if ($this->getRequest()->getParam('password_confirmation', false)) { + $user->setPasswordConfirmation($this->getRequest()->getParam('password_confirmation', false)); + } - if (!$_isValid) { - Mage::throwException(Mage::helper('adminhtml')->__('Error while saving account. Please check all required fields')); - } - if ($user->userExists()) { - Mage::throwException(Mage::helper('adminhtml')->__('User with the same User Name or Email aleady exists')); - } - $user->save(); - Mage::getSingleton('adminhtml/session')->addSuccess(Mage::helper('adminhtml')->__('Account successfully saved')); - } - catch (Mage_Core_Exception $e) { - throw $e; - } - catch (Exception $e) { - throw new Exception(Mage::helper('adminhtml')->__('Error while saving account. Please try again later')); + $result = $user->validate(); + if (is_array($result)) { + foreach($result as $error) { + Mage::getSingleton('adminhtml/session')->addError($error); } + $this->getResponse()->setRedirect($this->getUrl("*/*/")); + return; } - catch (Exception $e) { + + try { + $user->save(); + Mage::getSingleton('adminhtml/session')->addSuccess(Mage::helper('adminhtml')->__('Account successfully saved')); + } + catch (Mage_Core_Exception $e) { Mage::getSingleton('adminhtml/session')->addError($e->getMessage()); } + catch (Exception $e) { + Mage::getSingleton('adminhtml/session')->addError(Mage::helper('adminhtml')->__('Error while saving account. Please try again later')); + } $this->getResponse()->setRedirect($this->getUrl("*/*/")); } diff --git a/app/code/core/Mage/Adminhtml/controllers/System/ConfigController.php b/app/code/core/Mage/Adminhtml/controllers/System/ConfigController.php index 959e271762..348e98a94d 100644 --- a/app/code/core/Mage/Adminhtml/controllers/System/ConfigController.php +++ b/app/code/core/Mage/Adminhtml/controllers/System/ConfigController.php @@ -151,7 +151,7 @@ public function saveAction() $session->addSuccess(Mage::helper('adminhtml')->__('Configuration successfully saved')); } catch (Mage_Core_Exception $e) { - foreach(split("\n", $e->getMessage()) as $message) { + foreach(explode("\n", $e->getMessage()) as $message) { $session->addError($message); } } diff --git a/app/code/core/Mage/Adminhtml/controllers/System/Convert/ProfileController.php b/app/code/core/Mage/Adminhtml/controllers/System/Convert/ProfileController.php index dc01be85f5..bfcbe3bc73 100644 --- a/app/code/core/Mage/Adminhtml/controllers/System/Convert/ProfileController.php +++ b/app/code/core/Mage/Adminhtml/controllers/System/Convert/ProfileController.php @@ -256,7 +256,7 @@ public function batchRunAction() 'savedRows' => $saved, 'errors' => $errors ); - $this->getResponse()->setBody(Zend_Json::encode($result)); + $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result)); } } @@ -278,7 +278,7 @@ public function batchFinishAction() $result['error'] = Mage::helper('adminhtml')->__('Error while finished process. Please refresh cache'); } $batchModel->delete(); - $this->getResponse()->setBody(Zend_Json::encode($result)); + $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result)); } } } diff --git a/app/code/core/Mage/Adminhtml/controllers/System/Email/TemplateController.php b/app/code/core/Mage/Adminhtml/controllers/System/Email/TemplateController.php index 83733c1149..c3822d0f27 100644 --- a/app/code/core/Mage/Adminhtml/controllers/System/Email/TemplateController.php +++ b/app/code/core/Mage/Adminhtml/controllers/System/Email/TemplateController.php @@ -143,7 +143,7 @@ public function defaultTemplateAction() $template->loadDefault($this->getRequest()->getParam('code'), $this->getRequest()->getParam('locale')); - $this->getResponse()->setBody(Zend_Json::encode($template->getData())); + $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($template->getData())); } protected function _isAllowed() diff --git a/app/code/core/Mage/Adminhtml/controllers/Tax/ClassController.php b/app/code/core/Mage/Adminhtml/controllers/Tax/ClassController.php index f91050ffdd..8ec767ae1e 100644 --- a/app/code/core/Mage/Adminhtml/controllers/Tax/ClassController.php +++ b/app/code/core/Mage/Adminhtml/controllers/Tax/ClassController.php @@ -66,7 +66,9 @@ public function saveAction() } $this->_redirectReferer(); + return; } + $this->getResponse()->setRedirect($this->getUrl('*/tax_class')); } /** diff --git a/app/code/core/Mage/Adminhtml/controllers/Tax/RateController.php b/app/code/core/Mage/Adminhtml/controllers/Tax/RateController.php index c3311f5a54..44d978e1bb 100644 --- a/app/code/core/Mage/Adminhtml/controllers/Tax/RateController.php +++ b/app/code/core/Mage/Adminhtml/controllers/Tax/RateController.php @@ -97,7 +97,9 @@ public function saveAction() } $this->_redirectReferer(); + return; } + $this->getResponse()->setRedirect($this->getUrl('*/tax_rate')); } /** diff --git a/app/code/core/Mage/Adminhtml/controllers/Tax/RuleController.php b/app/code/core/Mage/Adminhtml/controllers/Tax/RuleController.php index 075ce23f2b..6e641a7d03 100644 --- a/app/code/core/Mage/Adminhtml/controllers/Tax/RuleController.php +++ b/app/code/core/Mage/Adminhtml/controllers/Tax/RuleController.php @@ -95,7 +95,9 @@ public function saveAction() Mage::getSingleton('adminhtml/session')->setRuleData($postData); $this->_redirectReferer(); + return; } + $this->getResponse()->setRedirect($this->getUrl('*/tax_rule')); } public function deleteAction() diff --git a/app/code/core/Mage/Adminhtml/controllers/UrlrewriteController.php b/app/code/core/Mage/Adminhtml/controllers/UrlrewriteController.php index 3ead699a4c..90e17e0b51 100644 --- a/app/code/core/Mage/Adminhtml/controllers/UrlrewriteController.php +++ b/app/code/core/Mage/Adminhtml/controllers/UrlrewriteController.php @@ -151,7 +151,7 @@ public function saveAction() // save and redirect $model->save(); Mage::getSingleton('adminhtml/session')->addSuccess( - Mage::helper('adminhtml')->__('Urlrewrite has been successfully saved') + Mage::helper('adminhtml')->__('URL Rewrite has been successfully saved') ); $this->_redirect('*/*/'); return; @@ -179,7 +179,7 @@ public function deleteAction() try { Mage::registry('current_urlrewrite')->delete(); Mage::getSingleton('adminhtml/session')->addSuccess( - Mage::helper('adminhtml')->__('Urlrewrite has been successfully deleted') + Mage::helper('adminhtml')->__('URL Rewrite has been successfully deleted') ); } catch (Exception $e) { diff --git a/app/code/core/Mage/AmazonPayments/Block/Asp/Form.php b/app/code/core/Mage/AmazonPayments/Block/Asp/Form.php index 4f0e2badd0..c616c5b0ad 100644 --- a/app/code/core/Mage/AmazonPayments/Block/Asp/Form.php +++ b/app/code/core/Mage/AmazonPayments/Block/Asp/Form.php @@ -41,4 +41,15 @@ protected function _construct() $this->setTemplate('amazonpayments/asp/form.phtml'); parent::_construct(); } + + /** + * Return method description message + * + * @return string + */ + public function getDescriptionMessage() + { + return $this->getMethod()->getChoiceMethodDescription(); + } + } diff --git a/app/code/core/Mage/AmazonPayments/Block/Asp/Redirect.php b/app/code/core/Mage/AmazonPayments/Block/Asp/Redirect.php index 74f19f342a..c6109f714c 100644 --- a/app/code/core/Mage/AmazonPayments/Block/Asp/Redirect.php +++ b/app/code/core/Mage/AmazonPayments/Block/Asp/Redirect.php @@ -33,6 +33,17 @@ */ class Mage_AmazonPayments_Block_Asp_Redirect extends Mage_Core_Block_Template { + + /** + * Return Amazon Simple Pay payment model + * + * @return Mage_AmazonPayments_Model_Payment_Asp + */ + public function getPayment() + { + return Mage::registry('amazonpayments_payment_asp'); + } + /** * Return Amazon Simple Pay payment url * @@ -40,7 +51,7 @@ class Mage_AmazonPayments_Block_Asp_Redirect extends Mage_Core_Block_Template */ public function getRedirectUrl() { - return Mage::registry('amazonpayments_payment_asp')->getPayRedirectUrl(); + return $this->getPayment()->getPayRedirectUrl(); } /** @@ -50,6 +61,17 @@ public function getRedirectUrl() */ public function getRedirectParams() { - return Mage::registry('amazonpayments_payment_asp')->getPayRedirectParams(); + return $this->getPayment()->getPayRedirectParams(); + } + + /** + * Return redirect message + * + * @return string + */ + public function getRedirectMessage() + { + return $this->getPayment()->getRedirectMessage(); } + } diff --git a/app/code/core/Mage/AmazonPayments/Model/Payment/Asp.php b/app/code/core/Mage/AmazonPayments/Model/Payment/Asp.php index cc409cc7f4..9ab650d7c0 100644 --- a/app/code/core/Mage/AmazonPayments/Model/Payment/Asp.php +++ b/app/code/core/Mage/AmazonPayments/Model/Payment/Asp.php @@ -183,7 +183,27 @@ public function getPayRedirectUrl() { return $this->getApi()->getPayUrl(); } + + /** + * Return choice method description + * + * @return string + */ + public function getChoiceMethodDescription() + { + return $this->getConfig('choice_method_description'); + } + /** + * Return redirect message + * + * @return string + */ + public function getRedirectMessage() + { + return $this->getConfig('redirect_message'); + } + /** * Return pay params for current order * diff --git a/app/code/core/Mage/AmazonPayments/Model/Payment/Cba.php b/app/code/core/Mage/AmazonPayments/Model/Payment/Cba.php index 5a6afc39cc..c8ec4a4b61 100644 --- a/app/code/core/Mage/AmazonPayments/Model/Payment/Cba.php +++ b/app/code/core/Mage/AmazonPayments/Model/Payment/Cba.php @@ -446,6 +446,8 @@ protected function _createNewOrder(array $newOrderDetails) ->setCustomerGroupId(Mage_Customer_Model_Group::NOT_LOGGED_IN_ID); } + $order->save(); + $quote->setIsActive(false); $quote->save(); diff --git a/app/code/core/Mage/AmazonPayments/etc/config.xml b/app/code/core/Mage/AmazonPayments/etc/config.xml index f31edee80a..a92a921461 100644 --- a/app/code/core/Mage/AmazonPayments/etc/config.xml +++ b/app/code/core/Mage/AmazonPayments/etc/config.xml @@ -210,6 +210,8 @@ Something like this is to be added to resolve bug #4890 https://authorize.payments.amazon.com/pba/paypipeline https://authorize.payments-sandbox.amazon.com/pba/paypipeline + Your billing address will be ignored and you will be redirected to Amazon Simple Pay website. + You will be redirected to Amazon Simple Pay in a few seconds. MAGENTO ASP PAYMENT MAGENTO ASP REFUND MAGENTO ASP CANCEL diff --git a/app/code/core/Mage/AmazonPayments/etc/system.xml b/app/code/core/Mage/AmazonPayments/etc/system.xml index 7b3e835b67..bd91ba946b 100644 --- a/app/code/core/Mage/AmazonPayments/etc/system.xml +++ b/app/code/core/Mage/AmazonPayments/etc/system.xml @@ -36,12 +36,12 @@


Signing up with Checkout by Amazon

To configure Checkout by Amazon™ you will need to enter your Checkout by Amazon™ Merchant ID, Access Key ID, and Secret Access Key.

-

If you do not already have a Checkout by Amazon™ account, click here to create one now. Sign-Up

+

If you do not already have a Checkout by Amazon™ account, click here to create one now. Sign-Up

To locate your Merchant ID, sign in to your Seller Central Checkout by Amazon™ account and click Settings > Checkout Pipeline Settings.

To locate your Access Key ID and Secret Access Key, sign in to your Seller Central Checkout by Amazon™ account and click Integration > AWS Key. Click the link to read the Amazon Web Services Customer Agreement, and then click the check box, if you are setting up a new Access Key ID.

To enable XML Order Reports click Settings > Checkout Pipeline Settings, and then clicking Edit under the Order Report Settings section. Select Order Report Type as XML to get XML Order Reports using SOAP APIs. Configure your downloads for hourly.

For additional information on setting up your Checkout by Amazon account, Click Here - FAQ.

-


Signup for Checkout by Amazon

+


Signup for Checkout by Amazon

]]> @@ -334,10 +334,26 @@ 0 + + + text + 30 + 1 + 1 + 0 + + + + text + 31 + 1 + 1 + 0 + text - 31 + 32 1 1 0 @@ -345,7 +361,7 @@ text - 32 + 33 1 1 0 @@ -353,7 +369,7 @@ text - 31 + 34 1 1 0 @@ -361,7 +377,7 @@ text - 33 + 35 1 1 0 @@ -369,7 +385,7 @@ text - 34 + 36 1 1 0 @@ -378,7 +394,7 @@ select adminhtml/system_config_source_email_identity - 35 + 37 1 1 0 @@ -387,7 +403,7 @@ select adminhtml/system_config_source_email_template - 36 + 38 1 1 0 @@ -396,7 +412,7 @@ select adminhtml/system_config_source_yesno - 37 + 39 1 1 0 @@ -405,7 +421,7 @@ select adminhtml/system_config_source_yesno - 38 + 40 1 1 0 @@ -414,7 +430,7 @@ select adminhtml/system_config_source_yesno - 39 + 41 1 1 0 diff --git a/app/code/core/Mage/Api/Model/Server/Handler/Abstract.php b/app/code/core/Mage/Api/Model/Server/Handler/Abstract.php index ce69f229de..8d260b0648 100644 --- a/app/code/core/Mage/Api/Model/Server/Handler/Abstract.php +++ b/app/code/core/Mage/Api/Model/Server/Handler/Abstract.php @@ -37,10 +37,10 @@ abstract class Mage_Api_Model_Server_Handler_Abstract public function __construct() { - set_error_handler(array(get_class($this), 'handlePhpError'), E_ALL); + set_error_handler(array($this, 'handlePhpError'), E_ALL); } - static public function handlePhpError($errorCode, $errorMessage, $errorFile) + public function handlePhpError($errorCode, $errorMessage, $errorFile) { Mage::log($errorMessage . $errorFile); if (in_array($errorCode, array(E_ERROR, E_USER_ERROR, E_RECOVERABLE_ERROR))) { diff --git a/app/code/core/Mage/Bundle/Block/Catalog/Product/View/Type/Bundle.php b/app/code/core/Mage/Bundle/Block/Catalog/Product/View/Type/Bundle.php index bd61f04b20..e4914cd01a 100644 --- a/app/code/core/Mage/Bundle/Block/Catalog/Product/View/Type/Bundle.php +++ b/app/code/core/Mage/Bundle/Block/Catalog/Product/View/Type/Bundle.php @@ -123,7 +123,7 @@ public function getJsonConfig() 'specialPrice' => $this->getProduct()->getSpecialPrice() ); - return Zend_Json::encode($config); + return Mage::helper('core')->jsonEncode($config); } public function addRenderer($type, $block) diff --git a/app/code/core/Mage/Bundle/Model/Product/Type.php b/app/code/core/Mage/Bundle/Model/Product/Type.php index 68d584a964..eac0c050db 100644 --- a/app/code/core/Mage/Bundle/Model/Product/Type.php +++ b/app/code/core/Mage/Bundle/Model/Product/Type.php @@ -826,4 +826,33 @@ public function getSearchableData($product = null) return $searchData; } + + /** + * Check if product can be bought + * + * @param Mage_Catalog_Model_Product $product + * @return Mage_Bundle_Model_Product_Type + * @throws Mage_Core_Exception + */ + public function checkProductBuyState($product = null) + { + parent::checkProductBuyState($product); + $product = $this->getProduct($product); + $productOptionIds = $this->getOptionsIds($product); + $productSelections = $this->getSelectionsCollection($productOptionIds, $product); + + $selectionIds = $product->getCustomOption('bundle_selection_ids'); + $selectionIds = unserialize($selectionIds->getValue()); + foreach ($selectionIds as $selectionId) { + /* @var $selection Mage_Bundle_Model_Selection */ + $selection = $productSelections->getItemById($selectionId); + if (!$selection || !$selection->isSalable()) { + Mage::throwException( + Mage::helper('bundle')->__('Selected required options not available.') + ); + } + } + + return $this; + } } diff --git a/app/code/core/Mage/Bundle/Model/Sales/Order/Pdf/Items/Invoice.php b/app/code/core/Mage/Bundle/Model/Sales/Order/Pdf/Items/Invoice.php index a49b0fc468..2881f1d68d 100644 --- a/app/code/core/Mage/Bundle/Model/Sales/Order/Pdf/Items/Invoice.php +++ b/app/code/core/Mage/Bundle/Model/Sales/Order/Pdf/Items/Invoice.php @@ -109,7 +109,7 @@ public function draw() } $line[] = array( 'text' => $text, - 'feed' => 240 + 'feed' => 255 ); } diff --git a/app/code/core/Mage/Bundle/etc/config.xml b/app/code/core/Mage/Bundle/etc/config.xml index 1e5f4ae24f..61bbe2c904 100644 --- a/app/code/core/Mage/Bundle/etc/config.xml +++ b/app/code/core/Mage/Bundle/etc/config.xml @@ -28,7 +28,7 @@ - 0.1.7 + 0.1.8 diff --git a/app/code/core/Mage/Bundle/sql/bundle_setup/mysql4-install-0.1.0.php b/app/code/core/Mage/Bundle/sql/bundle_setup/mysql4-install-0.1.0.php index c5fbde2262..8e39db93f3 100644 --- a/app/code/core/Mage/Bundle/sql/bundle_setup/mysql4-install-0.1.0.php +++ b/app/code/core/Mage/Bundle/sql/bundle_setup/mysql4-install-0.1.0.php @@ -159,7 +159,7 @@ $fieldList = array('price','special_price','special_from_date','special_to_date', 'minimal_price','cost','tier_price','weight','tax_class_id'); foreach ($fieldList as $field) { - $applyTo = split(',', $installer->getAttribute('catalog_product', $field, 'apply_to')); + $applyTo = explode(',', $installer->getAttribute('catalog_product', $field, 'apply_to')); if (!in_array('bundle', $applyTo)) { $applyTo[] = 'bundle'; $installer->updateAttribute('catalog_product', $field, 'apply_to', join(',', $applyTo)); diff --git a/app/code/core/Mage/Catalog/Block/Layer/State.php b/app/code/core/Mage/Catalog/Block/Layer/State.php index 6cfe6acaf7..7cc72dcc82 100644 --- a/app/code/core/Mage/Catalog/Block/Layer/State.php +++ b/app/code/core/Mage/Catalog/Block/Layer/State.php @@ -68,9 +68,10 @@ public function getClearUrl() foreach ($this->getActiveFilters() as $item) { $filterState[$item->getFilter()->getRequestVar()] = $item->getFilter()->getCleanValue(); } - $params['_current'] = true; + $params['_current'] = true; $params['_use_rewrite'] = true; - $params['_query'] = $filterState; + $params['_query'] = $filterState; + $params['_escape'] = true; return Mage::getUrl('*/*/*', $params); } diff --git a/app/code/core/Mage/Catalog/Block/Layer/View.php b/app/code/core/Mage/Catalog/Block/Layer/View.php index 7733ae4ef5..a03966f30a 100644 --- a/app/code/core/Mage/Catalog/Block/Layer/View.php +++ b/app/code/core/Mage/Catalog/Block/Layer/View.php @@ -33,6 +33,16 @@ */ class Mage_Catalog_Block_Layer_View extends Mage_Core_Block_Template { + /** + * Get attribute filter block name + * + * @return string + */ + protected function _getAttributeFilterBlockName() + { + return 'catalog/layer_filter_attribute'; + } + /** * Prepare child blocks * @@ -52,7 +62,7 @@ protected function _prepareLayout() $filterableAttributes = $this->_getFilterableAttributes(); foreach ($filterableAttributes as $attribute) { - $filterBlockName = 'catalog/layer_filter_attribute'; + $filterBlockName = $this->_getAttributeFilterBlockName(); if ($attribute->getFrontendInput() == 'price') { $filterBlockName = 'catalog/layer_filter_price'; } diff --git a/app/code/core/Mage/Catalog/Block/Product/Abstract.php b/app/code/core/Mage/Catalog/Block/Product/Abstract.php index f537988b36..a5e6581d21 100644 --- a/app/code/core/Mage/Catalog/Block/Product/Abstract.php +++ b/app/code/core/Mage/Catalog/Block/Product/Abstract.php @@ -20,26 +20,26 @@ * * @category Mage * @package Mage_Catalog - * @copyright Copyright (c) 2008 Irubin Consulting Inc. DBA Varien (http://www.varien.com) + * @copyright Copyright (c) 2009 Irubin Consulting Inc. DBA Varien (http://www.varien.com) * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ /** - * Product abstract block + * Catalog Product Abstract Block * * @category Mage * @package Mage_Catalog - * @author Magento Core Team + * @author Magento Core Team */ abstract class Mage_Catalog_Block_Product_Abstract extends Mage_Core_Block_Template { - private $_priceBlock = array(); - private $_priceBlockDefaultTemplate = 'catalog/product/price.phtml'; - private $_tierPriceDefaultTemplate = 'catalog/product/view/tierprices.phtml'; - private $_priceBlockTypes = array(); + protected $_priceBlock = array(); + protected $_priceBlockDefaultTemplate = 'catalog/product/price.phtml'; + protected $_tierPriceDefaultTemplate = 'catalog/product/view/tierprices.phtml'; + protected $_priceBlockTypes = array(); - private $_reviewsHelperBlock; + protected $_reviewsHelperBlock; /** * Retrieve url for add product to cart @@ -52,9 +52,15 @@ abstract class Mage_Catalog_Block_Product_Abstract extends Mage_Core_Block_Templ public function getAddToCartUrl($product, $additional = array()) { if ($product->getTypeInstance(true)->hasRequiredOptions($product)) { - $url = $product->getProductUrl(); - $link = (strpos($url, '?') !== false) ? '&' : '?'; - return $url . $link . 'options=cart'; + 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->helper('checkout/cart')->getAddUrl($product, $additional); } @@ -67,11 +73,11 @@ public function getAddToCartUrl($product, $additional = array()) */ public function getAddToWishlistUrl($product) { - return $this->getUrl('wishlist/index/add',array('product'=>$product->getId())); + return $this->helper('wishlist')->getAddUrl($product); } /** - * Enter description here... + * Retrieve Add Product to Compare Products List URL * * @param Mage_Catalog_Model_Product $product * @return string @@ -299,4 +305,42 @@ public function getImageLabel($product=null, $mediaAttributeCode='image') return $label; } + /** + * Retrieve Product URL using UrlDataObject + * + * @param Mage_Catalog_Model_Product $product + * @param array $additional the route params + * @return string + */ + public function getProductUrl($product, $additional = array()) + { + if ($this->hasProductUrl($product)) { + if (!isset($additional['_escape'])) { + $additional['_escape'] = true; + } + return $product->getUrlModel()->getUrl($product, $additional); + } + + return '#'; + } + + /** + * Check Product has URL + * + * @param Mage_Catalog_Model_Product $product + * @return bool + */ + public function hasProductUrl($product) + { + if ($product->getVisibleInSiteVisibilities()) { + return true; + } + if ($product->hasUrlDataObject()) { + if (in_array($product->hasUrlDataObject()->getVisibility(), $product->getVisibleInSiteVisibilities())) { + return true; + } + } + + return false; + } } diff --git a/app/code/core/Mage/Catalog/Block/Product/Compare/List.php b/app/code/core/Mage/Catalog/Block/Product/Compare/List.php index c3fd2d63cc..bf67135156 100644 --- a/app/code/core/Mage/Catalog/Block/Product/Compare/List.php +++ b/app/code/core/Mage/Catalog/Block/Product/Compare/List.php @@ -32,7 +32,7 @@ * @package Mage_Catalog * @author Magento Core Team */ -class Mage_Catalog_Block_Product_Compare_List extends Mage_Catalog_Block_Product_Abstract +class Mage_Catalog_Block_Product_Compare_List extends Mage_Catalog_Block_Product_Compare_Abstract { /** * Product Compare items collection @@ -55,7 +55,8 @@ class Mage_Catalog_Block_Product_Compare_List extends Mage_Catalog_Block_Product */ protected function _prepareLayout() { - if ($headBlock = $this->getLayout()->getBlock('head')) { + $headBlock = $this->getLayout()->getBlock('head'); + if ($headBlock) { $headBlock->setTitle(Mage::helper('catalog')->__('Compare Products List') . ' - ' . $headBlock->getDefaultTitle()); } return parent::_prepareLayout(); @@ -70,17 +71,16 @@ public function getItems() { if (is_null($this->_items)) { Mage::helper('catalog/product_compare')->setAllowUsedFlat(false); + $this->_items = Mage::getResourceModel('catalog/product_compare_item_collection') ->useProductItem(true) ->setStoreId(Mage::app()->getStore()->getId()); if (Mage::getSingleton('customer/session')->isLoggedIn()) { - $this->_items - ->setCustomerId(Mage::getSingleton('customer/session')->getCustomerId()); + $this->_items->setCustomerId(Mage::getSingleton('customer/session')->getCustomerId()); } else { - $this->_items - ->setVisitorId(Mage::getSingleton('log/visitor')->getId()); + $this->_items->setVisitorId(Mage::getSingleton('log/visitor')->getId()); } $this->_items diff --git a/app/code/core/Mage/Catalog/Block/Product/Compare/Sidebar.php b/app/code/core/Mage/Catalog/Block/Product/Compare/Sidebar.php index 7e5b9c2c2f..8f21ad1802 100644 --- a/app/code/core/Mage/Catalog/Block/Product/Compare/Sidebar.php +++ b/app/code/core/Mage/Catalog/Block/Product/Compare/Sidebar.php @@ -20,42 +20,56 @@ * * @category Mage * @package Mage_Catalog - * @copyright Copyright (c) 2008 Irubin Consulting Inc. DBA Varien (http://www.varien.com) + * @copyright Copyright (c) 2009 Irubin Consulting Inc. DBA Varien (http://www.varien.com) * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ /** - * Catalog comapare sidebar block + * Catalog Comapare Products Sidebar Block * * @category Mage * @package Mage_Catalog - * @author Magento Core Team + * @author Magento Core Team */ - class Mage_Catalog_Block_Product_Compare_Sidebar extends Mage_Catalog_Block_Product_Abstract - { - protected function _construct() - { - $this->setId('compare'); - } - - public function getItems() - { - return $this->helper('catalog/product_compare')->getItemCollection(); - } +class Mage_Catalog_Block_Product_Compare_Sidebar extends Mage_Catalog_Block_Product_Compare_Abstract +{ + /** + * Initialize block + * + */ + protected function _construct() + { + $this->setId('compare'); + } - public function getRemoveUrl($item) + /** + * Retrieve Compare Products Collection + * + * @return Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Compare_Item_Collection + */ + public function getItems() { - return $this->helper('catalog/product_compare')->getRemoveUrl($item); + return $this->_getHelper()->getItemCollection(); } + /** + * Retrieve Clean Compared Items URL + * + * @return string + */ public function getClearUrl() { - return $this->helper('catalog/product_compare')->getClearListUrl(); + return $this->_getHelper()->getClearListUrl(); } - public function getCompareUrl() - { - return $this->helper('catalog/product_compare')->getListUrl(); - } - } + /** + * Retrieve Full Compare page URL + * + * @return string + */ + public function getCompareUrl() + { + return $this->_getHelper()->getListUrl(); + } +} diff --git a/app/code/core/Mage/Catalog/Block/Product/View.php b/app/code/core/Mage/Catalog/Block/Product/View.php index 3e3f9840ad..b4e9b8da3f 100644 --- a/app/code/core/Mage/Catalog/Block/Product/View.php +++ b/app/code/core/Mage/Catalog/Block/Product/View.php @@ -144,7 +144,7 @@ public function getJsonConfig() } } - return Zend_Json::encode($config); + return Mage::helper('core')->jsonEncode($config); } /** diff --git a/app/code/core/Mage/Catalog/Block/Product/View/Options.php b/app/code/core/Mage/Catalog/Block/Product/View/Options.php index fa985048eb..318e843ef9 100644 --- a/app/code/core/Mage/Catalog/Block/Product/View/Options.php +++ b/app/code/core/Mage/Catalog/Block/Product/View/Options.php @@ -155,7 +155,7 @@ public function getJsonConfig() $config[$option->getId()] = $priceValue; } - return Zend_Json::encode($config); + return Mage::helper('core')->jsonEncode($config); } /** diff --git a/app/code/core/Mage/Catalog/Block/Product/View/Type/Configurable.php b/app/code/core/Mage/Catalog/Block/Product/View/Type/Configurable.php index a89413d081..2e66aaf4fc 100644 --- a/app/code/core/Mage/Catalog/Block/Product/View/Type/Configurable.php +++ b/app/code/core/Mage/Catalog/Block/Product/View/Type/Configurable.php @@ -171,7 +171,7 @@ public function getJsonConfig() 'taxConfig' => $taxConfig, ); - return Zend_Json::encode($config); + return Mage::helper('core')->jsonEncode($config); } /** diff --git a/app/code/core/Mage/Catalog/Helper/Category/Flat.php b/app/code/core/Mage/Catalog/Helper/Category/Flat.php index 1995bd37b6..9feea72b27 100644 --- a/app/code/core/Mage/Catalog/Helper/Category/Flat.php +++ b/app/code/core/Mage/Catalog/Helper/Category/Flat.php @@ -61,4 +61,14 @@ public function isRebuilt() { return Mage::getResourceSingleton('catalog/category_flat')->isRebuilt(); } + + /** + * Back Flat compatibility: check is built and enabled flat + * + * @return bool + */ + public function isBuilt() + { + return $this->isEnabled(true); + } } \ No newline at end of file diff --git a/app/code/core/Mage/Catalog/Helper/Image.php b/app/code/core/Mage/Catalog/Helper/Image.php index a100b40b32..dbdcdd558c 100644 --- a/app/code/core/Mage/Catalog/Helper/Image.php +++ b/app/code/core/Mage/Catalog/Helper/Image.php @@ -39,6 +39,7 @@ class Mage_Catalog_Helper_Image extends Mage_Core_Helper_Abstract protected $_watermark; protected $_watermarkPosition; protected $_watermarkSize; + protected $_watermarkImageOpacity; protected $_product; protected $_imageFile; protected $_placeholder; @@ -233,12 +234,14 @@ public function __toString() if( $this->_scheduleWatermark ) { $this->_getModel() ->setWatermarkPosition( $this->getWatermarkPosition() ) + ->setWatermarkImageOpacity( $this->getWatermarkImageOpacity() ) ->setWatermarkSize($this->parseSize($this->getWatermarkSize())) ->setWatermark($this->getWatermark(), $this->getWatermarkPosition()); } else { if( $watermark = Mage::getStoreConfig("design/watermark/{$this->_getModel()->getDestinationSubdir()}_image") ) { $this->_getModel() ->setWatermarkPosition( $this->getWatermarkPosition() ) + ->setWatermarkImageOpacity( $this->getWatermarkImageOpacity() ) ->setWatermarkSize($this->parseSize($this->getWatermarkSize())) ->setWatermark($watermark, $this->getWatermarkPosition()); } @@ -325,6 +328,26 @@ protected function getWatermarkSize() } } + public function setWatermarkImageOpacity($imageOpacity) + { + $this->_watermarkImageOpacity = $imageOpacity; + return $this; + } + + protected function getWatermarkImageOpacity() + { + if( $this->_watermarkImageOpacity ) { + return $this->_watermarkImageOpacity; + } + + if ($imageOpacity = Mage::getStoreConfig("design/watermark/{$this->_getModel()->getDestinationSubdir()}_imageOpacity")) + { + return $imageOpacity; + } + + return $this->_getModel()->getWatermarkImageOpacity(); + } + protected function setProduct($product) { $this->_product = $product; diff --git a/app/code/core/Mage/Catalog/Helper/Product/Compare.php b/app/code/core/Mage/Catalog/Helper/Product/Compare.php index e169a66cb6..1fc5dec88d 100644 --- a/app/code/core/Mage/Catalog/Helper/Product/Compare.php +++ b/app/code/core/Mage/Catalog/Helper/Product/Compare.php @@ -55,6 +55,16 @@ class Mage_Catalog_Helper_Product_Compare extends Mage_Core_Helper_Url */ protected $_allowUsedFlat = true; + /** + * Retrieve Catalog Session instance + * + * @return Mage_Catalog_Model_Session + */ + protected function _getSession() + { + return Mage::getSingleton('catalog/session'); + } + /** * Retrieve compare list url * @@ -166,7 +176,7 @@ public function getClearListUrl() /** * Retrieve compare list items collection * - * @return + * @return Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Compare_Item_Collection */ public function getItemCollection() { @@ -182,7 +192,8 @@ public function getItemCollection() $this->_itemCollection->setVisitorId(Mage::getSingleton('log/visitor')->getId()); } - Mage::getSingleton('catalog/product_visibility')->addVisibleInSiteFilterToCollection($this->_itemCollection); + Mage::getSingleton('catalog/product_visibility') + ->addVisibleInSiteFilterToCollection($this->_itemCollection); $this->_itemCollection->addAttributeToSelect('name') ->addUrlRewrite() @@ -195,30 +206,34 @@ public function getItemCollection() /** * Calculate cache product compare collection * + * @param bool $logout * @return Mage_Catalog_Helper_Product_Compare */ - public function calculate() + public function calculate($logout = false) { - if (!Mage::getSingleton('customer/session')->isLoggedIn() - and !Mage::getSingleton('log/visitor')->hasCatalogCompareItemsCount() - ) { - Mage::getSingleton('log/visitor')->setCatalogCompareItemsCount(0); - return $this; - } - - $itemCollection = Mage::getResourceModel('catalog/product_compare_item_collection'); - /* @var $itemCollection Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Compare_Item_Collection */ - $itemCollection->setStoreId(Mage::app()->getStore()->getId()); - if (Mage::getSingleton('customer/session')->isLoggedIn()) { - $itemCollection->setCustomerId(Mage::getSingleton('customer/session')->getCustomerId()); + // first visit + if (!$this->_getSession()->hasCatalogCompareItemsCount()) { + $count = 0; } else { - $itemCollection->setVisitorId(Mage::getSingleton('log/visitor')->getId()); + /* @var $collection Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Compare_Item_Collection */ + $collection = Mage::getResourceModel('catalog/product_compare_item_collection') + ->useProductItem(true); + if (!$logout && Mage::getSingleton('customer/session')->isLoggedIn()) { + $collection->setCustomerId(Mage::getSingleton('customer/session')->getCustomerId()); + } + else { + $collection->setVisitorId(Mage::getSingleton('log/visitor')->getId()); + } + + Mage::getSingleton('catalog/product_visibility') + ->addVisibleInSiteFilterToCollection($collection); + + $count = $collection->getSize(); } - Mage::getSingleton('catalog/product_visibility') - ->addVisibleInSiteFilterToCollection($itemCollection); - Mage::getSingleton('log/visitor')->setCatalogCompareItemsCount($itemCollection->getSize()); + $this->_getSession()->setCatalogCompareItemsCount($count); + return $this; } @@ -229,10 +244,11 @@ public function calculate() */ public function getItemCount() { - if (is_null(Mage::getSingleton('log/visitor')->getCatalogCompareItemsCount())) { + if (!$this->_getSession()->hasCatalogCompareItemsCount()) { $this->calculate(); } - return Mage::getSingleton('log/visitor')->getCatalogCompareItemsCount(); + + return $this->_getSession()->getCatalogCompareItemsCount(); } /** diff --git a/app/code/core/Mage/Catalog/Model/Category.php b/app/code/core/Mage/Catalog/Model/Category.php index 1e31b2a3d3..912433ad74 100644 --- a/app/code/core/Mage/Catalog/Model/Category.php +++ b/app/code/core/Mage/Catalog/Model/Category.php @@ -262,7 +262,30 @@ public function getStoreIds() if ($storeIds = $this->getData('store_ids')) { return $storeIds; } - $storeIds = $this->getResource()->getStoreIds($this); + + if (!$this->getId()) { + return array(); + } + + $nodes = array(); + foreach ($this->getPathIds() as $id) { + $nodes[] = $id; + } + + $storeIds = array(); + $storeCollection = Mage::getModel('core/store')->getCollection()->loadByCategoryIds($nodes); + foreach ($storeCollection as $store) { + $storeIds[$store->getId()] = $store->getId(); + } + + $entityStoreId = $this->getStoreId(); + if (!in_array($entityStoreId, $storeIds)) { + array_unshift($storeIds, $entityStoreId); + } + if (!in_array(0, $storeIds)) { + array_unshift($storeIds, 0); + } + $this->setData('store_ids', $storeIds); return $storeIds; } @@ -762,7 +785,7 @@ public function getAvailableSortBy() return array(); } if ($available && !is_array($available)) { - $available = split(',', $available); + $available = explode(',', $available); } return $available; } diff --git a/app/code/core/Mage/Catalog/Model/Category/Attribute/Backend/Sortby.php b/app/code/core/Mage/Catalog/Model/Category/Attribute/Backend/Sortby.php index d453a83a5f..dbf258a42e 100644 --- a/app/code/core/Mage/Catalog/Model/Category/Attribute/Backend/Sortby.php +++ b/app/code/core/Mage/Catalog/Model/Category/Attribute/Backend/Sortby.php @@ -51,7 +51,7 @@ public function validate($object) if ($attributeCode == 'default_sort_by') { if ($available = $object->getData('available_sort_by')) { if (!is_array($available)) { - $available = split(',', $available); + $available = explode(',', $available); } if (!in_array($object->getData($attributeCode), $available)) { Mage::throwException(Mage::helper('eav')->__('Default Product Listing Sort by not exists on Available Product Listing Sort by')); @@ -85,7 +85,7 @@ public function afterLoad($object) { if ($attributeCode == 'available_sort_by') { $data = $object->getData($attributeCode); if ($data) { - $object->setData($attributeCode, split(',', $data)); + $object->setData($attributeCode, explode(',', $data)); } } return $this; diff --git a/app/code/core/Mage/Catalog/Model/Convert/Adapter/Product.php b/app/code/core/Mage/Catalog/Model/Convert/Adapter/Product.php index 16df3ceaa7..b79d1182b2 100644 --- a/app/code/core/Mage/Catalog/Model/Convert/Adapter/Product.php +++ b/app/code/core/Mage/Catalog/Model/Convert/Adapter/Product.php @@ -599,7 +599,7 @@ public function saveRow(array $importData) if (!is_array($websiteIds)) { $websiteIds = array(); } - $websiteCodes = split(',', $importData['websites']); + $websiteCodes = explode(',', $importData['websites']); foreach ($websiteCodes as $websiteCode) { try { $website = Mage::app()->getWebsite(trim($websiteCode)); @@ -630,7 +630,7 @@ public function saveRow(array $importData) $setValue = $value; if ($attribute->getFrontendInput() == 'multiselect') { - $value = split(self::MULTI_DELIMITER, $value); + $value = explode(self::MULTI_DELIMITER, $value); $isArray = true; $setValue = array(); } diff --git a/app/code/core/Mage/Catalog/Model/Convert/Parser/Product.php b/app/code/core/Mage/Catalog/Model/Convert/Parser/Product.php index bd4121057f..d4e472a2bf 100644 --- a/app/code/core/Mage/Catalog/Model/Convert/Parser/Product.php +++ b/app/code/core/Mage/Catalog/Model/Convert/Parser/Product.php @@ -403,6 +403,7 @@ public function unparse() 'websites' => '', 'attribute_set' => $this->getAttributeSetName($product->getEntityTypeId(), $product->getAttributeSetId()), 'type' => $product->getTypeId(), + 'category_ids' => join(',', $product->getCategoryIds()) ); if ($this->getStore()->getCode() == Mage_Core_Model_Store::ADMIN_CODE) { diff --git a/app/code/core/Mage/Catalog/Model/Layer/Filter/Attribute.php b/app/code/core/Mage/Catalog/Model/Layer/Filter/Attribute.php index 1f913c3a3a..0bed8286ac 100644 --- a/app/code/core/Mage/Catalog/Model/Layer/Filter/Attribute.php +++ b/app/code/core/Mage/Catalog/Model/Layer/Filter/Attribute.php @@ -82,6 +82,17 @@ public function apply(Zend_Controller_Request_Abstract $request, $filterBlock) return $this; } + /** + * Check whether specified attribute can be used in LN + * + * @param Mage_Catalog_Model_Resource_Eav_Attribute $attribute + * @return bool + */ + protected function _getIsFilterableAttribute($attribute) + { + return $attribute->getIsFilterable(); + } + /** * Get data array for building attribute filter items * @@ -109,7 +120,7 @@ protected function _getItemsData() } if (Mage::helper('core/string')->strlen($option['value'])) { // Check filter type - if ($attribute->getIsFilterable() == self::OPTIONS_ONLY_WITH_RESULTS) { + if ($this->_getIsFilterableAttribute($attribute) == self::OPTIONS_ONLY_WITH_RESULTS) { if (!empty($optionsCount[$option['value']])) { $data[] = array( 'label' => $option['label'], diff --git a/app/code/core/Mage/Catalog/Model/Layer/Filter/Item.php b/app/code/core/Mage/Catalog/Model/Layer/Filter/Item.php index cbe35ace1c..07a1cda11a 100644 --- a/app/code/core/Mage/Catalog/Model/Layer/Filter/Item.php +++ b/app/code/core/Mage/Catalog/Model/Layer/Filter/Item.php @@ -74,6 +74,7 @@ public function getRemoveUrl() $params['_current'] = true; $params['_use_rewrite'] = true; $params['_query'] = $query; + $params['_escape'] = true; return Mage::getUrl('*/*/*', $params); } diff --git a/app/code/core/Mage/Catalog/Model/Layer/Filter/Price.php b/app/code/core/Mage/Catalog/Model/Layer/Filter/Price.php index be07d989c4..9b91a8c5eb 100644 --- a/app/code/core/Mage/Catalog/Model/Layer/Filter/Price.php +++ b/app/code/core/Mage/Catalog/Model/Layer/Filter/Price.php @@ -133,10 +133,11 @@ protected function _getCacheKey() $key = $this->getLayer()->getStateKey() . '_PRICES_GRP_' . Mage::getSingleton('customer/session')->getCustomerGroupId() . '_CURR_' . Mage::app()->getStore()->getCurrentCurrencyCode() + . '_ATTR_' . $this->getAttributeModel()->getAttributeCode() . '_LOC_' ; $taxReq = Mage::getSingleton('tax/calculation')->getRateRequest(false, false, false); - $key.= $taxReq->__toString(array(), '_'); + $key.= implode('_', $taxReq->getData()); return $key; } diff --git a/app/code/core/Mage/Catalog/Model/Product.php b/app/code/core/Mage/Catalog/Model/Product.php index 8a107c438a..dabf92d06f 100644 --- a/app/code/core/Mage/Catalog/Model/Product.php +++ b/app/code/core/Mage/Catalog/Model/Product.php @@ -290,40 +290,38 @@ public function getCategory() return $category; } + /** + * Set assigned category IDs array to product + * + * @param array|string $ids + * @return Mage_Catalog_Model_Product + */ public function setCategoryIds($ids) { if (is_string($ids)) { $ids = explode(',', $ids); - } elseif (!is_array($ids)) { + } + elseif (!is_array($ids)) { Mage::throwException(Mage::helper('catalog')->__('Invalid category IDs')); } - foreach ($ids as $i=>$v) { + foreach ($ids as $i => $v) { if (empty($v)) { unset($ids[$i]); } } + $this->setData('category_ids', $ids); return $this; } + /** + * Retrieve assigned category Ids + * + * @return array + */ public function getCategoryIds() { - if ($this->hasData('category_ids')) { - $ids = $this->_getData('category_ids'); - if (!is_array($ids)) { - $wasLocked = false; - if ($this->isLockedAttribute('category_ids')) { - $this->unlockAttribute('category_ids'); - $wasLocked = true; - } - - $ids = !empty($ids) ? explode(',', $ids) : array(); - $this->setData('category_ids', $ids); - if ($wasLocked) { - $this->lockAttribute('category_ids'); - } - } - } else { + if (!$this->hasData('category_ids')) { $wasLocked = false; if ($this->isLockedAttribute('category_ids')) { $this->unlockAttribute('category_ids'); @@ -334,6 +332,7 @@ public function getCategoryIds() $this->lockAttribute('category_ids'); } } + return $this->_getData('category_ids'); } @@ -344,7 +343,7 @@ public function getCategoryIds() */ public function getCategoryCollection() { - return $this->getResource()->getCategoryCollection($this); + return $this->_getResource()->getCategoryCollection($this); } /** @@ -531,6 +530,16 @@ protected function _afterLoad() return $this; } + /** + * Retrieve resource instance wrapper + * + * @return Mage_Catalog_Model_Resource_Eav_Mysql4_Product + */ + protected function _getResource() + { + return parent::_getResource(); + } + /** * Clear cache related with product id * @@ -1060,16 +1069,41 @@ public function getVisibleInCatalogStatuses() return Mage::getSingleton('catalog/product_status')->getVisibleStatusIds(); } + /** + * Retrieve visible statuses + * + * @return array + */ + public function getVisibleStatuses() + { + return Mage::getSingleton('catalog/product_status')->getVisibleStatusIds(); + } + + /** + * Check Product visilbe in catalog + * + * @return bool + */ public function isVisibleInCatalog() { return in_array($this->getStatus(), $this->getVisibleInCatalogStatuses()); } + /** + * Retrieve visible in site visibilities + * + * @return array + */ public function getVisibleInSiteVisibilities() { return Mage::getSingleton('catalog/product_visibility')->getVisibleInSiteIds(); } + /** + * Check Product visible in site + * + * @return bool + */ public function isVisibleInSiteVisibility() { return in_array($this->getVisibility(), $this->getVisibleInSiteVisibilities()); @@ -1161,16 +1195,27 @@ public function getCustomDesignDate() } /** - * Get product url + * Retrieve Product URL * * @param bool $useSid * @return string */ - public function getProductUrl($useSid = true) + public function getProductUrl($useSid = null) { return $this->getUrlModel()->getProductUrl($this, $useSid); } + /** + * Retrieve URL in current store + * + * @param array $params the route params + * @return string + */ + public function getUrlInStore($params = array()) + { + return $this->getUrlModel()->getUrlInStore($this, $params); + } + public function formatUrlKey($str) { return $this->getUrlModel()->formatUrlKey($str); @@ -1431,26 +1476,16 @@ public function canBeShowInCategory($categoryId) return $this->_getResource()->canBeShowInCategory($this, $categoryId); } - + /** + * Retrieve category ids where product is available + * + * @return array + */ public function getAvailableInCategories() { - $allCategories = array(); - if (is_null($this->getData('_available_in_categories'))) { - $assigned = $this->getCategoryIds(); - foreach ($assigned as $one) { - $allCategories[] = $one; - $anchors = Mage::getModel('catalog/category')->load($one)->getAnchorsAbove(); - foreach ($anchors as $anchor) { - $allCategories[] = $anchor; - } - } - - $this->setData('_available_in_categories', $allCategories); - } - return $this->getData('_available_in_categories'); + return $this->_getResource()->getAvailableInCategories($this); } - /** * Retrieve default attribute set id * diff --git a/app/code/core/Mage/Catalog/Model/Product/Api.php b/app/code/core/Mage/Catalog/Model/Product/Api.php index 4b58a2a6e5..a29ab2b7e6 100644 --- a/app/code/core/Mage/Catalog/Model/Product/Api.php +++ b/app/code/core/Mage/Catalog/Model/Product/Api.php @@ -183,7 +183,7 @@ public function create($type, $set, $sku, $productData) * @param string|int $store * @return boolean */ - public function update($productId, $productData = array(), $store = null) + public function update($productId, $productData, $store = null) { $product = $this->_getProduct($productId, $store); @@ -248,6 +248,10 @@ protected function _prepareDataForSave ($product, $productData) $product->setWebsiteIds($productData['websites']); } + if (Mage::app()->isSingleStoreMode()) { + $product->setWebsiteIds(array(Mage::app()->getStore(true)->getWebsite()->getId())); + } + if (isset($productData['stock_data']) && is_array($productData['stock_data'])) { $product->setStockData($productData['stock_data']); } diff --git a/app/code/core/Mage/Catalog/Model/Product/Api/V2.php b/app/code/core/Mage/Catalog/Model/Product/Api/V2.php index 28c818f2a2..d153de5916 100644 --- a/app/code/core/Mage/Catalog/Model/Product/Api/V2.php +++ b/app/code/core/Mage/Catalog/Model/Product/Api/V2.php @@ -34,7 +34,7 @@ class Mage_Catalog_Model_Product_Api_V2 extends Mage_Catalog_Model_Product_Api { - /** + /** * Retrieve list of products with basic info (id, sku, type, set, name) * * @param array $filters @@ -79,14 +79,14 @@ public function items($filters = null, $store = null) $result = array(); foreach ($collection as $product) { -// $result[] = $product->getData(); - $result[] = array( // Basic product data + $result[] = array( 'product_id' => $product->getId(), 'sku' => $product->getSku(), 'name' => $product->getName(), 'set' => $product->getAttributeSetId(), 'type' => $product->getTypeId(), - 'category_ids' => $product->getCategoryIds() + 'category_ids' => $product->getCategoryIds(), + 'website_ids' => $product->getWebsiteIds() ); } @@ -179,6 +179,7 @@ public function create($type, $set, $sku, $productData) } unset($productData->additional_attributes); } + foreach ($product->getTypeInstance(true)->getEditableAttributes($product) as $attribute) { $_attrCode = $attribute->getAttributeCode(); if ($this->_isAllowedAttribute($attribute) @@ -287,8 +288,16 @@ protected function _prepareDataForSave ($product, $productData) $product->setWebsiteIds($productData->websites); } - if (property_exists($productData, 'stock_data') && is_array($productData->stock_data)) { - $product->setStockData($productData->stock_data); + if (Mage::app()->isSingleStoreMode()) { + $product->setWebsiteIds(array(Mage::app()->getStore(true)->getWebsite()->getId())); + } + + if (property_exists($productData, 'stock_data')) { + $_stockData = array(); + foreach ($productData->stock_data as $key => $value) { + $_stockData[$key] = $value; + } + $product->setStockData($_stockData); } } diff --git a/app/code/core/Mage/Catalog/Model/Product/Attribute/Backend/Media.php b/app/code/core/Mage/Catalog/Model/Product/Attribute/Backend/Media.php index 790253d798..08e5d41bdd 100644 --- a/app/code/core/Mage/Catalog/Model/Product/Attribute/Backend/Media.php +++ b/app/code/core/Mage/Catalog/Model/Product/Attribute/Backend/Media.php @@ -78,7 +78,7 @@ public function beforeSave($object) } if(!is_array($value['images']) && strlen($value['images']) > 0) { - $value['images'] = Zend_Json::decode($value['images']); + $value['images'] = Mage::helper('core')->jsonDecode($value['images']); } if (!is_array($value['images'])) { diff --git a/app/code/core/Mage/Catalog/Model/Product/Attribute/Backend/Tierprice.php b/app/code/core/Mage/Catalog/Model/Product/Attribute/Backend/Tierprice.php index e1274eb12e..3be9195005 100644 --- a/app/code/core/Mage/Catalog/Model/Product/Attribute/Backend/Tierprice.php +++ b/app/code/core/Mage/Catalog/Model/Product/Attribute/Backend/Tierprice.php @@ -225,6 +225,16 @@ public function afterSave($object) continue; } + if (intval($tierPrice['website_id']) > 0 && + (!is_array($object->getWebsiteIds()) || !in_array($tierPrice['website_id'], $object->getWebsiteIds()))) { + continue; + } + + if ($object->getStoreId() && + Mage::app()->getStore($object->getStoreId())->getWebsiteId() != $tierPrice['website_id']) { + continue; + } + $useForAllGroups = $tierPrice['cust_group'] == Mage_Customer_Model_Group::CUST_GROUP_ALL; $customerGroupId = !$useForAllGroups ? $tierPrice['cust_group'] : 0; $priceKey = join('-', array( diff --git a/app/code/core/Mage/Catalog/Model/Product/Attribute/Tierprice/Api.php b/app/code/core/Mage/Catalog/Model/Product/Attribute/Tierprice/Api.php index 049f3fd74e..5fd156bf21 100644 --- a/app/code/core/Mage/Catalog/Model/Product/Attribute/Tierprice/Api.php +++ b/app/code/core/Mage/Catalog/Model/Product/Attribute/Tierprice/Api.php @@ -90,6 +90,10 @@ public function update($productId, $tierPrices) } } + if (intval($tierPrice['website']) > 0 && !in_array($tierPrice['website'], $product->getWebsiteIds())) { + $this->_fault('data_invalid', Mage::helper('catalog')->__('Invalid tier prices. Product is not associated to the requested website.')); + } + if (!isset($tierPrice['customer_group_id'])) { $tierPrice['customer_group_id'] = 'all'; } @@ -104,10 +108,8 @@ public function update($productId, $tierPrices) 'price_qty' => $tierPrice['qty'], 'price' => $tierPrice['price'] ); - } - try { if (is_array($errors = $product->validate())) { $this->_fault('data_invalid', implode("\n", $errors)); diff --git a/app/code/core/Mage/Catalog/Model/Product/Attribute/Tierprice/Api/V2.php b/app/code/core/Mage/Catalog/Model/Product/Attribute/Tierprice/Api/V2.php index dd9bf3d9af..31ad005979 100644 --- a/app/code/core/Mage/Catalog/Model/Product/Attribute/Tierprice/Api/V2.php +++ b/app/code/core/Mage/Catalog/Model/Product/Attribute/Tierprice/Api/V2.php @@ -42,7 +42,6 @@ class Mage_Catalog_Model_Product_Attribute_Tierprice_Api_V2 extends Mage_Catalog */ public function update($productId, $tierPrices) { - Mage::log($tierPrices); $product = $this->_initProduct($productId); if (!is_array($tierPrices)) { $this->_fault('data_invalid', Mage::helper('catalog')->__('Invalid Tier Prices')); @@ -67,6 +66,10 @@ public function update($productId, $tierPrices) } } + if (intval($tierPrice->website) > 0 && !in_array($tierPrice->website, $product->getWebsiteIds())) { + $this->_fault('data_invalid', Mage::helper('catalog')->__('Invalid tier prices. Product is not associated to the requested website.')); + } + if (!isset($tierPrice->customer_group_id)) { $tierPrice->customer_group_id = 'all'; } diff --git a/app/code/core/Mage/Catalog/Model/Product/Compare/Item.php b/app/code/core/Mage/Catalog/Model/Product/Compare/Item.php index d059dbc47e..9be4bb2a3c 100644 --- a/app/code/core/Mage/Catalog/Model/Product/Compare/Item.php +++ b/app/code/core/Mage/Catalog/Model/Product/Compare/Item.php @@ -26,7 +26,7 @@ /** - * Catalog compare item model + * Catalog Compare Item Model * * @category Mage * @package Mage_Catalog @@ -43,6 +43,31 @@ protected function _construct() $this->_init('catalog/product_compare_item'); } + /** + * Retrieve Resource instance + * + * @return Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Compare_Item + */ + protected function _getResource() + { + return parent::_getResource(); + } + + /** + * Set current store before save + * + * @return Mage_Catalog_Model_Product_Compare_Item + */ + protected function _beforeSave() + { + parent::_beforeSave(); + if (!$this->hasStoreId()) { + $this->setStoreId(Mage::app()->getStore()->getId()); + } + + return $this; + } + /** * Add customer data from customer object * @@ -52,7 +77,6 @@ protected function _construct() public function addCustomerData(Mage_Customer_Model_Customer $customer) { $this->setCustomerId($customer->getId()); - $this->setVisitorId(0); return $this; } @@ -91,7 +115,7 @@ public function addProductData($product) if ($product instanceof Mage_Catalog_Model_Product) { $this->setProductId($product->getId()); } - elseif(intval($product)) { + else if(intval($product)) { $this->setProductId(intval($product)); } @@ -120,29 +144,7 @@ public function getDataForSave() */ public function bindCustomerLogin() { - $customer = Mage::getSingleton('customer/session')->getCustomer(); - $visitorItemCollection = Mage::getResourceModel('catalog/product_compare_item_collection') - ->setObject('catalog/product_compare_item') - ->setVisitorId(Mage::getSingleton('log/visitor')->getId()) - ->load(); - - $customerItemCollection = $this->getResourceCollection() - ->setCustomerId($customer->getId()) - ->useProductItem(true) - ->load(); - - $customerProductIds = $customerItemCollection->getProductIds(); - - foreach ($visitorItemCollection as $item) { - if (in_array($item->getProductId(), $customerProductIds)) { - $item->delete(); - } - else { - $item->setCustomerId($customer->getId()) - ->setVisitorId(0) - ->save(); - } - } + $this->_getResource()->updateCustomerFromVisitor($this); Mage::helper('catalog/product_compare')->calculate(); return $this; @@ -156,7 +158,9 @@ public function bindCustomerLogin() */ public function bindCustomerLogout(Varien_Event_Observer $observer) { - Mage::getSingleton('log/visitor')->setCatalogCompareItemsCount(0); + $this->_getResource()->purgeVisitorByCustomer($this); + + Mage::helper('catalog/product_compare')->calculate(true); return $this; } @@ -170,4 +174,32 @@ public function clean() $this->_getResource()->clean($this); return $this; } + + /** + * Retrieve Customer Id if loggined + * + * @return int + */ + public function getCustomerId() + { + if (!$this->hasData('customer_id')) { + $customerId = Mage::getSingleton('customer/session')->getCustomerId(); + $this->setData('customer_id', $customerId); + } + return $this->getData('customer_id'); + } + + /** + * Retrieve Visitor Id + * + * @return int + */ + public function getVisitorId() + { + if (!$this->hasData('visitor_id')) { + $visitorId = Mage::getSingleton('log/visitor')->getId(); + $this->setData('visitor_id', $visitorId); + } + return $this->getData('visitor_id'); + } } diff --git a/app/code/core/Mage/Catalog/Model/Product/Compare/List.php b/app/code/core/Mage/Catalog/Model/Product/Compare/List.php index 071397aaaf..63c446b5bf 100644 --- a/app/code/core/Mage/Catalog/Model/Product/Compare/List.php +++ b/app/code/core/Mage/Catalog/Model/Product/Compare/List.php @@ -20,33 +20,46 @@ * * @category Mage * @package Mage_Catalog - * @copyright Copyright (c) 2008 Irubin Consulting Inc. DBA Varien (http://www.varien.com) + * @copyright Copyright (c) 2009 Irubin Consulting Inc. DBA Varien (http://www.varien.com) * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ /** - * Product compare list + * Product Compare List Model * * @category Mage * @package Mage_Catalog - * @author Magento Core Team + * @author Magento Core Team */ class Mage_Catalog_Model_Product_Compare_List extends Varien_Object { + /** + * Add product to Compare List + * + * @param int|Mage_Catalog_Model_Product $product + * @return Mage_Catalog_Model_Product_Compare_List + */ public function addProduct($product) { + /* @var $item Mage_Catalog_Model_Product_Compare_Item */ $item = Mage::getModel('catalog/product_compare_item'); $this->_addVisitorToItem($item); - $item->loadByProduct($product); if (!$item->getId()) { $item->addProductData($product); $item->save(); } + return $this; } + /** + * Add products to compare list + * + * @param array $productIds + * @return Mage_Catalog_Model_Product_Compare_List + */ public function addProducts($productIds) { if (is_array($productIds)) { @@ -57,29 +70,62 @@ public function addProducts($productIds) return $this; } + /** + * Retrieve Compare Items Collection + * + * @return product_compare_item_collection + */ public function getItemCollection() { return Mage::getResourceModel('catalog/product_compare_item_collection'); } - public function removeProduct() + /** + * Remove product from compare list + * + * @param int|Mage_Catalog_Model_Product $product + * @return Mage_Catalog_Model_Product_Compare_List + */ + public function removeProduct($product) { + /* @var $item Mage_Catalog_Model_Product_Compare_Item */ + $item = Mage::getModel('catalog/product_compare_item'); + $this->_addVisitorToItem($item); + $item->loadByProduct($product); + if ($item->getId()) { + $item->delete(); + } + + return $this; } + /** + * Add visitor and customer data to compare item + * + * @param Mage_Catalog_Model_Product_Compare_Item $item + * @return Mage_Catalog_Model_Product_Compare_List + */ protected function _addVisitorToItem($item) { + $item->addVisitorId(Mage::getSingleton('log/visitor')->getId()); if (Mage::getSingleton('customer/session')->isLoggedIn()) { $item->addCustomerData(Mage::getSingleton('customer/session')->getCustomer()); } - else { - $item->addVisitorId(Mage::getSingleton('log/visitor')->getId()); - } + return $this; } + /** + * Check has compare items by visitor/customer + * + * @param int $customerId + * @param int $visitorId + * @return bool + */ public function hasItems($customerId, $visitorId) { - return Mage::getResourceSingleton('catalog/product_compare_item')->getCount($customerId, $visitorId); + return Mage::getResourceSingleton('catalog/product_compare_item') + ->getCount($customerId, $visitorId); } } \ No newline at end of file diff --git a/app/code/core/Mage/Catalog/Model/Product/Flat/Indexer.php b/app/code/core/Mage/Catalog/Model/Product/Flat/Indexer.php index b3328e6a0c..dee437f7b3 100644 --- a/app/code/core/Mage/Catalog/Model/Product/Flat/Indexer.php +++ b/app/code/core/Mage/Catalog/Model/Product/Flat/Indexer.php @@ -70,13 +70,14 @@ public function rebuild($store = null) * * @param string $attributeCode * @param int $store + * @param int|array $productIds * @return Mage_Catalog_Model_Product_Flat_Indexer */ - public function updateAttribute($attributeCode, $store = null) + public function updateAttribute($attributeCode, $store = null, $productIds = null) { if (is_null($store)) { foreach (Mage::app()->getStores() as $store) { - $this->updateAttribute($attributeCode, $store->getId()); + $this->updateAttribute($attributeCode, $store->getId(), $productIds); } return $this; @@ -84,8 +85,8 @@ public function updateAttribute($attributeCode, $store = null) $this->_getResource()->prepareFlatTable($store); $attribute = $this->_getResource()->getAttribute($attributeCode); - $this->_getResource()->updateAttribute($attribute, $store); - $this->_getResource()->updateChildrenDataFromParent($store); + $this->_getResource()->updateAttribute($attribute, $store, $productIds); + $this->_getResource()->updateChildrenDataFromParent($store, $productIds); return $this; } diff --git a/app/code/core/Mage/Catalog/Model/Product/Flat/Observer.php b/app/code/core/Mage/Catalog/Model/Product/Flat/Observer.php index 4659757830..c359fd32d5 100644 --- a/app/code/core/Mage/Catalog/Model/Product/Flat/Observer.php +++ b/app/code/core/Mage/Catalog/Model/Product/Flat/Observer.php @@ -289,16 +289,12 @@ public function customerGroupSaveAfter(Varien_Event_Observer $observer) /** * Update category ids in flat * + * @deprecated 1.3.2.2 * @param Varien_Event_Observer $observer * @return Mage_Catalog_Model_Product_Flat_Observer */ public function catalogCategoryChangeProducts(Varien_Event_Observer $observer) { - if (!$this->_getHelper()->isBuilt()) { - return $this; - } - $this->_getIndexer()->updateAttribute('category_ids'); - return $this; } } diff --git a/app/code/core/Mage/Catalog/Model/Product/Image.php b/app/code/core/Mage/Catalog/Model/Product/Image.php index 2db9c23f61..0cb8af56ca 100644 --- a/app/code/core/Mage/Catalog/Model/Product/Image.php +++ b/app/code/core/Mage/Catalog/Model/Product/Image.php @@ -50,6 +50,7 @@ class Mage_Catalog_Model_Product_Image extends Mage_Core_Model_Abstract protected $_watermarkPosition; protected $_watermarkWidth; protected $_watermarkHeigth; + protected $_watermarkImageOpacity = 70; /** * @return Mage_Catalog_Model_Product_Image @@ -375,7 +376,7 @@ public function setAngle($angle) /** * @return Mage_Catalog_Model_Product_Image */ - public function setWatermark($file, $position=null, $size=null, $width=null, $heigth=null) + public function setWatermark($file, $position=null, $size=null, $width=null, $heigth=null, $imageOpacity=null) { $filename = false; @@ -399,10 +400,11 @@ public function setWatermark($file, $position=null, $size=null, $width=null, $he $filename = $baseDir . $file; } } - + if( $filename ) { $this->getImageProcessor() ->setWatermarkPosition( ($position) ? $position : $this->getWatermarkPosition() ) + ->setWatermarkImageOpacity( ($imageOpacity) ? $imageOpacity : $this->getWatermarkImageOpacity() ) ->setWatermarkWidth( ($width) ? $width : $this->getWatermarkWidth() ) ->setWatermarkHeigth( ($heigth) ? $heigth : $this->getWatermarkHeigth() ) ->watermark($filename); @@ -471,6 +473,17 @@ public function getWatermarkPosition() return $this->_watermarkPosition; } + public function setWatermarkImageOpacity($imageOpacity) + { + $this->_watermarkImageOpacity = $imageOpacity; + return $this; + } + + public function getWatermarkImageOpacity() + { + return $this->_watermarkImageOpacity; + } + /** * @return Mage_Catalog_Model_Product_Image */ diff --git a/app/code/core/Mage/Catalog/Model/Product/Option/Type/File.php b/app/code/core/Mage/Catalog/Model/Product/Option/Type/File.php index 990193ee52..588eb1f7bf 100644 --- a/app/code/core/Mage/Catalog/Model/Product/Option/Type/File.php +++ b/app/code/core/Mage/Catalog/Model/Product/Option/Type/File.php @@ -176,7 +176,7 @@ public function validateUserValue($values) 'target' => $fileFullPath, 'overwrite' => true )); - if (!$upload->receive()) { + if (!$upload->receive($file)) { $this->setIsValid(false); Mage::throwException(Mage::helper('catalog')->__("File upload failed")); } @@ -216,7 +216,7 @@ public function validateUserValue($values) $option->getTitle() ); } elseif ($errorCode == Zend_Validate_File_ImageSize::WIDTH_TOO_BIG - || $errorCode == Zend_Validate_File_ImageSize::WIDTH_TOO_BIG) + || $errorCode == Zend_Validate_File_ImageSize::HEIGHT_TOO_BIG) { $errors[] = Mage::helper('catalog')->__("Maximum allowed image size for '%s' is %sx%s px.", $option->getTitle(), diff --git a/app/code/core/Mage/Catalog/Model/Product/Type.php b/app/code/core/Mage/Catalog/Model/Product/Type.php index c7a075090b..dfcd0cdf34 100644 --- a/app/code/core/Mage/Catalog/Model/Product/Type.php +++ b/app/code/core/Mage/Catalog/Model/Product/Type.php @@ -153,7 +153,16 @@ static public function getOptionText($optionId) static public function getTypes() { if (is_null(self::$_types)) { - self::$_types = Mage::getConfig()->getNode('global/catalog/product/type')->asArray(); + $productTypes = Mage::getConfig()->getNode('global/catalog/product/type')->asArray(); + foreach ($productTypes as $productKey => $productConfig) { + $moduleName = 'catalog'; + if (isset($productConfig['@']['module'])) { + $moduleName = $productConfig['@']['module']; + } + $translatedLabel = Mage::helper($moduleName)->__($productConfig['label']); + $productTypes[$productKey]['label'] = $translatedLabel; + } + self::$_types = $productTypes; } return self::$_types; diff --git a/app/code/core/Mage/Catalog/Model/Product/Type/Grouped.php b/app/code/core/Mage/Catalog/Model/Product/Type/Grouped.php index 78f70bfd76..5c5fa48e4a 100644 --- a/app/code/core/Mage/Catalog/Model/Product/Type/Grouped.php +++ b/app/code/core/Mage/Catalog/Model/Product/Type/Grouped.php @@ -265,6 +265,7 @@ public function save($product = null) */ public function prepareForCart(Varien_Object $buyRequest, $product = null) { + $product = $this->getProduct($product); $productsInfo = $buyRequest->getSuperGroup(); if (!empty($productsInfo) && is_array($productsInfo)) { $products = array(); @@ -286,12 +287,12 @@ public function prepareForCart(Varien_Object $buyRequest, $product = null) } $_result[0]->setCartQty($qty); - $_result[0]->addCustomOption('product_type', self::TYPE_CODE, $this->getProduct($product)); + $_result[0]->addCustomOption('product_type', self::TYPE_CODE, $product); $_result[0]->addCustomOption('info_buyRequest', serialize(array( 'super_product_config' => array( 'product_type' => self::TYPE_CODE, - 'product_id' => $this->getProduct($product)->getId() + 'product_id' => $product->getId() ) )) ); diff --git a/app/code/core/Mage/Catalog/Model/Product/Url.php b/app/code/core/Mage/Catalog/Model/Product/Url.php index 87824aa3cc..aa655ed568 100644 --- a/app/code/core/Mage/Catalog/Model/Product/Url.php +++ b/app/code/core/Mage/Catalog/Model/Product/Url.php @@ -20,26 +20,41 @@ * * @category Mage * @package Mage_Catalog - * @copyright Copyright (c) 2008 Irubin Consulting Inc. DBA Varien (http://www.varien.com) + * @copyright Copyright (c) 2009 Irubin Consulting Inc. DBA Varien (http://www.varien.com) * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ + /** * Product Url model * - * @author Magento Core Team + * @category Mage + * @package Mage_Catalog + * @author Magento Core Team */ - class Mage_Catalog_Model_Product_Url extends Varien_Object { + const CACHE_TAG = 'url_rewrite'; + + /** + * Static URL instance + * + * @var Mage_Core_Model_Url + */ protected static $_url; - protected static $_urlRewrite; - const CACHE_TAG = 'url_rewrite'; + /** + * Static URL Rewrite Instance + * + * @var Mage_Core_Model_Url_Rewrite + */ + protected static $_urlRewrite; /** - * @return Mage_Core_Model_Url - */ + * Retrieve URL Instance + * + * @return Mage_Core_Model_Url + */ public function getUrlInstance() { if (!self::$_url) { @@ -49,8 +64,10 @@ public function getUrlInstance() } /** - * @return Mage_Core_Model_Url_Rewrite - */ + * Retrieve URL Rewrite Instance + * + * @return Mage_Core_Model_Url_Rewrite + */ public function getUrlRewrite() { if (!self::$_urlRewrite) { @@ -61,6 +78,7 @@ public function getUrlRewrite() /** * 'no_selection' shouldn't be a valid image attribute value + * * @param string $image * @return string */ @@ -73,10 +91,23 @@ protected function _validImage($image) } /** - * Get product url + * Retrieve URL in current store + * + * @param Mage_Catalog_Model_Product $product + * @param array $params the URL route params + * @return string + */ + public function getUrlInStore(Mage_Catalog_Model_Product $product, $params = array()) + { + $params['_store_to_url'] = true; + return $this->getUrl($product, $params); + } + + /** + * Retrieve Product URL * * @param Mage_Catalog_Model_Product $product - * @param bool $useSid + * @param bool $useSid forced SID mode * @return string */ public function getProductUrl($product, $useSid = null) @@ -85,68 +116,20 @@ public function getProductUrl($product, $useSid = null) $useSid = Mage::app()->getUseSessionInUrl(); } - $categoryId = $product->getCategoryId() && !$product->getDoNotUseCategoryId() ? $product->getCategoryId() : 0; - - $cacheUrlKey = sprintf('url_%d_%d', $categoryId, $useSid); - $url = $product->getData($cacheUrlKey); - - if (is_null($url)) { - if ($product->getStoreId()) { - $this->getUrlInstance()->setStore($product->getStoreId()); - } - - // auto add SID to URL - $originalSid = $this->getUrlInstance()->getUseSession(); - if ($originalSid != $useSid) { - $this->getUrlInstance()->setUseSession($useSid); - } - - if ($product->hasData('request_path') && $product->getRequestPath() != '') { - $this->setData($cacheUrlKey, $this->getUrlInstance()->getDirectUrl($product->getRequestPath())); - $this->getUrlInstance()->setUseSession($originalSid); - return $this->getData($cacheUrlKey); - } - - Varien_Profiler::start('REWRITE: '.__METHOD__); - - $rewrite = $this->getUrlRewrite(); - if ($product->getStoreId()) { - $rewrite->setStoreId($product->getStoreId()); - } - else { - $rewrite->setStoreId(Mage::app()->getStore()->getId()); - } - - $idPath = 'product/'.$product->getId(); - if ($product->getCategoryId() && !$product->getDoNotUseCategoryId() && Mage::getStoreConfig('catalog/seo/product_use_categories')) { - $idPath .= '/'.$product->getCategoryId(); - } - - $rewrite->loadByIdPath($idPath); -//echo $this->getUrlInstance()->getBaseUrl(); - if ($rewrite->getId()) { - $this->setData($cacheUrlKey, $this->getUrlInstance()->getDirectUrl($rewrite->getRequestPath())); - Varien_Profiler::stop('REWRITE: '.__METHOD__); - $this->getUrlInstance()->setUseSession($originalSid); - return $this->getData($cacheUrlKey); - } - - Varien_Profiler::stop('REWRITE: '.__METHOD__); - Varien_Profiler::start('REGULAR: '.__METHOD__); - - $url = $this->getUrlInstance()->getUrl('catalog/product/view', array( - 'id' => $product->getId(), - 's' => $product->getUrlKey(), - 'category' => $product->getCategoryId() - )); - - $this->getUrlInstance()->setUseSession($originalSid); - - Varien_Profiler::stop('REGULAR: '.__METHOD__); + $params = array(); + if (!$useSid) { + $params['_nosid'] = true; } - return $url; + + return $this->getUrl($product, $params); } + /** + * Format Key for URL + * + * @param string $str + * @return string + */ public function formatUrlKey($str) { $urlKey = preg_replace('#[^0-9a-z]+#i', '-', Mage::helper('catalog/product_url')->format($str)); @@ -178,4 +161,70 @@ public function getUrlPath($product, $category=null) return Mage::helper('catalog/category')->getCategoryUrlPath($category->getUrlPath()) . '/' . $path; } -} \ No newline at end of file + + /** + * Retrieve Product URL using UrlDataObject + * + * @param Mage_Catalog_Model_Product $product + * @param array $params + * @return string + */ + public function getUrl(Mage_Catalog_Model_Product $product, $params = array()) + { + $routePath = ''; + $routeParams = $params; + + $storeId = $product->getStoreId(); + $categoryId = $product->getCategoryId() && !$product->getDoNotUseCategoryId() + ? $product->getCategoryId() : null; + + if ($product->hasUrlDataObject()) { + $requestPath = $product->getUrlDataObject()->getUrlRewrite(); + $routeParams['_store'] = $product->getUrlDataObject()->getStoreId(); + } + else { + $requestPath = $product->getRequestPath(); + if (empty($requestPath)) { + $idPath = sprintf('product/%d', $product->getEntityId()); + if ($categoryId) { + $idPath = sprintf('%s/%d', $idPath, $categoryId); + } + $rewrite = $this->getUrlRewrite(); + $rewrite->setStoreId($storeId) + ->loadByIdPath($idPath); + if ($rewrite->getId()) { + $requestPath = $rewrite->getRequestPath(); + $product->setRequestPath($requestPath); + } + } + } + + if (isset($routeParams['_store'])) { + $storeId = Mage::app()->getStore($routeParams['_store'])->getId(); + } + + if ($storeId != Mage::app()->getStore()->getId()) { + $routeParams['_store_to_url'] = true; + } + + if (!empty($requestPath)) { + $routeParams['_direct'] = $requestPath; + } + else { + $routePath = 'catalog/product/view'; + $routeParams['id'] = $product->getId(); + $routeParams['s'] = $product->getUrlKey(); + if ($categoryId) { + $routeParams['category'] = $categoryId; + } + } + + // reset cached URL instance GET query params + if (!isset($routeParams['_query'])) { + $routeParams['_query'] = array(); + } + + return $this->getUrlInstance()->setStore($storeId) + ->getUrl($routePath, $routeParams); + } +} diff --git a/app/code/core/Mage/Catalog/Model/Product/Visibility.php b/app/code/core/Mage/Catalog/Model/Product/Visibility.php index 1ccf4191ac..0a21ef168a 100644 --- a/app/code/core/Mage/Catalog/Model/Product/Visibility.php +++ b/app/code/core/Mage/Catalog/Model/Product/Visibility.php @@ -192,7 +192,13 @@ static public function getOptionText($optionId) */ public function getFlatColums() { - return array(); + return array($this->getAttribute()->getAttributeCode() => array( + 'type' => 'tinyint', + 'unsigned' => true, + 'is_null' => true, + 'default' => null, + 'extra' => null + )); } /** @@ -214,7 +220,8 @@ public function getFlatIndexes() */ public function getFlatUpdateSelect($store) { - return null; + return Mage::getResourceSingleton('eav/entity_attribute') + ->getFlatUpdateSelect($this->getAttribute(), $store); } /** diff --git a/app/code/core/Mage/Catalog/Model/Resource/Eav/Mysql4/Abstract.php b/app/code/core/Mage/Catalog/Model/Resource/Eav/Mysql4/Abstract.php index 8f63389d80..dabb857bcb 100644 --- a/app/code/core/Mage/Catalog/Model/Resource/Eav/Mysql4/Abstract.php +++ b/app/code/core/Mage/Catalog/Model/Resource/Eav/Mysql4/Abstract.php @@ -152,17 +152,20 @@ protected function _insertAttribute($object, $attribute, $value) 'value' => $this->_prepareValueForSave($value, $attribute), 'store_id' => $this->getDefaultStoreId() ); + $fields = array(); - $values = array(); + $bind = array(); foreach ($row as $k => $v) { - $fields[] = $this->_getWriteAdapter()->quoteIdentifier('?', $k); - $values[] = $this->_getWriteAdapter()->quoteInto('?', $v); + $fields[] = $this->_getWriteAdapter()->quoteIdentifier($k); + $bind[':' . $k] = $v; } + $sql = sprintf('INSERT IGNORE INTO %s (%s) VALUES(%s)', $this->_getWriteAdapter()->quoteIdentifier($attribute->getBackend()->getTable()), - join(',', array_keys($row)), - join(',', $values)); - $this->_getWriteAdapter()->query($sql); + implode(',', $fields), + implode(',', array_keys($bind))); + + $this->_getWriteAdapter()->query($sql, $bind); if (!$lastId = $this->_getWriteAdapter()->lastInsertId()) { $select = $this->_getReadAdapter()->select() ->from($attribute->getBackend()->getTable(), 'value_id') diff --git a/app/code/core/Mage/Catalog/Model/Resource/Eav/Mysql4/Category.php b/app/code/core/Mage/Catalog/Model/Resource/Eav/Mysql4/Category.php index 98672da76b..5d7b029516 100644 --- a/app/code/core/Mage/Catalog/Model/Resource/Eav/Mysql4/Category.php +++ b/app/code/core/Mage/Catalog/Model/Resource/Eav/Mysql4/Category.php @@ -267,10 +267,13 @@ protected function _saveCategoryProducts($category) /** * new category-product relationships + * */ $products = $category->getPostedProducts(); + /** * Example re-save category + * */ if (is_null($products)) { return $this; @@ -278,38 +281,35 @@ protected function _saveCategoryProducts($category) /** * old category-product relationships + * */ $oldProducts = $category->getProductsPosition(); $insert = array_diff_key($products, $oldProducts); $delete = array_diff_key($oldProducts, $products); + /** * Find product ids which are presented in both arrays + * */ $update = array_intersect_key($products, $oldProducts); + /** * Use for update just products with changed position + * */ $update = array_diff_assoc($update, $oldProducts); - $productTable = $this->getTable('catalog/product'); - $productUpdateSql = sprintf('UPDATE `%s` AS `e` SET `category_ids`=(SELECT - GROUP_CONCAT(`category_id`) FROM `%s` AS `cp` WHERE `cp`.`product_id`=`e`.`entity_id`) - WHERE `e`.`entity_id` IN(?)', $productTable, $this->_categoryProductTable); - /** * Delete products from category * */ if (!empty($delete)) { - $deleteIds = array_keys($delete); - $this->_getWriteAdapter()->delete($this->_categoryProductTable, - $this->_getWriteAdapter()->quoteInto('product_id in(?)', $deleteIds) . - $this->_getWriteAdapter()->quoteInto(' AND category_id=?', $category->getId()) - ); - - $sql = $this->_getWriteAdapter()->quoteInto($productUpdateSql, $deleteIds); - $this->_getWriteAdapter()->query($sql); + $cond = join(' AND ', array( + $this->_getWriteAdapter()->quoteInto('product_id IN(?)', array_keys($delete)), + $this->_getWriteAdapter()->quoteInto('category_id=?', $category->getId()) + )); + $this->_getWriteAdapter()->delete($this->_categoryProductTable, $cond); } /** @@ -317,20 +317,17 @@ protected function _saveCategoryProducts($category) * */ if (!empty($insert)) { - $insertSql = array(); - foreach ($insert as $k => $v) { - $insertSql[] = '('.(int)$category->getId().','.(int)$k.','.(int)$v.')'; + $data = array(); + foreach ($insert as $productId => $position) { + $data[] = array( + 'category_id' => $category->getId(), + 'product_id' => (int)$productId, + 'position' => (int)$position + ); } - $sql = sprintf( - 'INSERT INTO `%s` (`category_id`,`product_id`,`position`) VALUES%s', - $this->_categoryProductTable, - join(',', $insertSql) - ); - $this->_getWriteAdapter()->query($sql); - $insertIds = array_keys($insert); - $sql = $this->_getWriteAdapter()->quoteInto($productUpdateSql, $insertIds); - $this->_getWriteAdapter()->query($sql); + $this->_getWriteAdapter() + ->insertMultiple($this->_categoryProductTable, $data); } /** @@ -338,14 +335,13 @@ protected function _saveCategoryProducts($category) * */ if (!empty($update)) { - foreach ($update as $k => $v) { - $cond = array( + foreach ($update as $productId => $position) { + $where = join(' AND ', array( $this->_getWriteAdapter()->quoteInto('category_id=?', (int)$category->getId()), - $this->_getWriteAdapter()->quoteInto('product_id=?', (int)$k) - ); - $where = join(' AND ', $cond); + $this->_getWriteAdapter()->quoteInto('product_id=?', (int)$productId) + )); $bind = array( - 'position' => (int)$v + 'position' => (int)$position ); $this->_getWriteAdapter()->update($this->_categoryProductTable, $bind, $where); } @@ -371,6 +367,7 @@ protected function _saveCategoryProducts($category) /** * Get store identifiers where category is presented * + * @deprecated after 1.3.2.2 moved to model * @param Mage_Catalog_Model_Category $category * @return array */ @@ -380,13 +377,9 @@ public function getStoreIds($category) return array(); } - $nodePath = $this->_getTree() - ->getNodeById($category->getId()) - ->getPath(); - $nodes = array(); - foreach ($nodePath as $node) { - $nodes[] = $node->getId(); + foreach ($category->getPathIds() as $id) { + $nodes[] = $id; } $stores = array(); diff --git a/app/code/core/Mage/Catalog/Model/Resource/Eav/Mysql4/Category/Collection.php b/app/code/core/Mage/Catalog/Model/Resource/Eav/Mysql4/Category/Collection.php index ae6976d6c7..5a81d4fac9 100644 --- a/app/code/core/Mage/Catalog/Model/Resource/Eav/Mysql4/Category/Collection.php +++ b/app/code/core/Mage/Catalog/Model/Resource/Eav/Mysql4/Category/Collection.php @@ -168,18 +168,14 @@ public function getProductStoreId() } /** - * Load collection + * Enter description here... * - * @param bool $printQuery - * @param bool $logQuery + * @param boolean $printQuery + * @param boolean $logQuery * @return Mage_Catalog_Model_Resource_Eav_Mysql4_Category_Collection */ public function load($printQuery = false, $logQuery = false) { - if ($this->isLoaded()) { - return $this; - } - if ($this->_loadWithProductCount) { $this->addAttributeToSelect('all_children'); $this->addAttributeToSelect('is_anchor'); @@ -196,6 +192,8 @@ public function load($printQuery = false, $logQuery = false) /** * Load categories product count + * + * @return Mage_Catalog_Model_Resource_Eav_Mysql4_Category_Collection */ protected function _loadProductCount() { diff --git a/app/code/core/Mage/Catalog/Model/Resource/Eav/Mysql4/Category/Flat.php b/app/code/core/Mage/Catalog/Model/Resource/Eav/Mysql4/Category/Flat.php index d2ecb36c67..ac91194822 100644 --- a/app/code/core/Mage/Catalog/Model/Resource/Eav/Mysql4/Category/Flat.php +++ b/app/code/core/Mage/Catalog/Model/Resource/Eav/Mysql4/Category/Flat.php @@ -40,6 +40,12 @@ class Mage_Catalog_Model_Resource_Eav_Mysql4_Category_Flat extends Mage_Core_Mod protected $_nodes = array(); + protected $_columns = null; + + protected $_columnsSql = null; + + protected $_attributeCodes = null; + /** * Inactive categories ids * @@ -175,9 +181,9 @@ protected function _loadNodes($parentNode = null, $recursionLevel = 0, $storeId $startLevel = $parentNode->getLevel(); } elseif (is_numeric($parentNode)) { $selectParent = $_conn->select() - ->from($this->getMainStoreTable()) + ->from($this->getMainStoreTable($storeId)) ->where('entity_id = ?', $parentNode) - ->where('store_id = ?', '0'); + ->where('store_id = ?', $storeId); if ($parentNode = $_conn->fetchRow($selectParent)) { $parentPath = $parentNode['path']; $startLevel = $parentNode['level']; @@ -265,7 +271,7 @@ public function getNodes($parentId, $recursionLevel = 0, $storeId = 0) { if (!$this->_loaded) { $selectParent = $this->_getReadAdapter()->select() - ->from($this->getMainStoreTable()) + ->from($this->getMainStoreTable($storeId)) ->where('entity_id = ?', $parentId); if ($parentNode = $this->_getReadAdapter()->fetchRow($selectParent)) { $parentNode['id'] = $parentNode['entity_id']; @@ -307,7 +313,7 @@ public function getCategories($parent, $recursionLevel = 0, $sorted=false, $asCo { if ($asCollection) { $parentPath = $this->_getReadAdapter()->fetchOne(new Zend_Db_Expr(" - SELECT path FROM {$this->getMainStoreTable()} WHERE entity_id = {$parent} + SELECT path FROM {$this->getMainStoreTable($this->getStoreId())} WHERE entity_id = {$parent} ")); $collection = Mage::getModel('catalog/category')->getCollection() ->addNameToResult() @@ -358,7 +364,7 @@ public function isRebuilt() { if ($this->_isRebuilt === null) { $select = $this->_getReadAdapter()->select() - ->from($this->getMainStoreTable($this->getStoreId()), 'entity_id') + ->from($this->getMainStoreTable(Mage::app()->getDefaultStoreView()->getId()), 'entity_id') ->limit(1); try { $this->_isRebuilt = (bool) $this->_getReadAdapter()->fetchOne($select); @@ -399,38 +405,73 @@ protected function _getTableSqlSchema($storeId = 0) * * @return Mage_Catalog_Model_Resource_Eav_Mysql4_Category_Flat */ - public function rebuild() + public function rebuild($stores = null) { - $_conn = $this->_getWriteAdapter(); - if ($this->getUseStoreTables()) { - $stores = array(); - $selectStores = $_conn->select() - ->from($this->getTable('core/store'), 'store_id'); - $stores = array(); - foreach ($_conn->fetchAll($selectStores) as $store) { - $stores[] = $store['store_id']; - } - $this->_createTable($stores); - } else { - $this->_createTable(0); + if ($stores === null) { + $stores = Mage::app()->getStores(); } - $select = $_conn->select() - ->from($this->getTable('catalog/category'), 'entity_id'); - $_categories = $_conn->fetchAll($select); - foreach ($_categories as $_category) { - foreach ($stores as $store) { - $_tmpCategory = Mage::getModel('catalog/category') - ->setStoreId($store) - ->load($_category['entity_id']); - if ($_tmpCategory->getId()) { - $this->_synchronize($_tmpCategory, 'insert'); + + if (!is_array($stores)) { + $stores = array($stores); + } + + $rootId = Mage_Catalog_Model_Category::TREE_ROOT_ID; + $categories = array(); + $categoriesIds = array(); + /* @var $store Mage_Core_Model_Store */ + foreach ($stores as $store) { + $this->_createTable($store->getId()); + + if (!isset($categories[$store->getRootCategoryId()])) { + $select = $this->_getWriteAdapter()->select() + ->from($this->getTable('catalog/category')) + ->where('path = ?', (string)$rootId) + ->orWhere('path = ?', "{$rootId}/{$store->getRootCategoryId()}") + ->orWhere('path LIKE ?', "{$rootId}/{$store->getRootCategoryId()}/%"); + $categories[$store->getRootCategoryId()] = $this->_getWriteAdapter()->fetchAll($select); + $categoriesIds[$store->getRootCategoryId()] = array(); + foreach ($categories[$store->getRootCategoryId()] as $category) { + $categoriesIds[$store->getRootCategoryId()][] = $category['entity_id']; + } + } + $categoriesIdsChunks = array_chunk($categoriesIds[$store->getRootCategoryId()], 500); + foreach ($categoriesIdsChunks as $categoriesIdsChunk) { + $attributesData = $this->_getAttributeValues($categoriesIdsChunk, $store->getId()); + $data = array(); + foreach ($categories[$store->getRootCategoryId()] as $category) { + if (!isset($attributesData[$category['entity_id']])) { + continue; + } + $category['store_id'] = $store->getId(); + $data[] = $this->_prepareValuesToInsert( + array_merge($category, $attributesData[$category['entity_id']]) + ); } + $this->_getWriteAdapter()->insertMultiple($this->getMainStoreTable($store->getId()), $data); } } - $_tmpCategory = null; return $this; } + /** + * Prepare array of column and columnValue pairs + * + * @param array $data + * @return array + */ + protected function _prepareValuesToInsert($data) + { + $values = array(); + foreach (array_keys($this->_columns) as $key => $column) { + if (isset($data[$column])) { + $values[$column] = $data[$column]; + } else { + $values[$column] = ''; + } + } + return $values; + } + /** * Create Flate Table(s) * @@ -445,63 +486,225 @@ public function createTable($stores) /** * Creating table and adding attributes as fields to table * - * @param array|integer $stores + * @param array|integer $store * @return Mage_Catalog_Model_Resource_Eav_Mysql4_Category_Flat */ - protected function _createTable($stores) + protected function _createTable($store) { - if (!is_array($stores)) { - $stores = (int) $stores; + $this->_getWriteAdapter()->query("DROP TABLE IF EXISTS `{$this->getMainStoreTable($store)}`;"); + $_tableSql = "CREATE TABLE `{$this->getMainStoreTable($store)}` (\n"; + if ($this->_columnsSql === null || $this->_columnsSql === null) { + $this->_columns = array_merge($this->_getStaticColumns(), $this->_getEavColumns()); + foreach ($this->_columns as $columnName => $columnData) { + $this->_columnsSql .= '`' . $columnName . '` ' . $columnData['type']; + $this->_columnsSql .= $columnData['is_unsigned'] ? ' unsigned' : ''; + $this->_columnsSql .= ($columnData['is_null'] ? '' : ' not null'); + $this->_columnsSql .= ($columnData['default'] === false ? '' : ' default \'' . $columnData['default'] . '\''); + $this->_columnsSql .= ",\n"; + } } - $_conn = $this->_getWriteAdapter(); - if ($this->getUseStoreTables() && is_array($stores)) { - foreach ($stores as $store) { - $_conn->query("DROP TABLE IF EXISTS `{$this->getMainStoreTable($store)}`"); - $_conn->query($this->_getTableSqlSchema($store)); + $_tableSql .= $this->_columnsSql; + $_tableSql .= "KEY `CATEGORY_FLAT_CATEGORY_ID` (`entity_id`), + KEY `CATEGORY_FLAT_STORE_ID` (`store_id`), + KEY `path` (`path`), + KEY `IDX_LEVEL` (`level`), + CONSTRAINT `FK_CATEGORY_FLAT_CATEGORY_ID_STORE_{$store}` FOREIGN KEY (`entity_id`) + REFERENCES `{$this->getTable('catalog/category')}` (`entity_id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `FK_CATEGORY_FLAT_STORE_ID_STORE_{$store}` FOREIGN KEY (`store_id`) + REFERENCES `{$this->getTable('core/store')}` (`store_id`) ON DELETE CASCADE ON UPDATE CASCADE + ) ENGINE=InnoDB DEFAULT CHARSET=utf8"; + $this->_getWriteAdapter()->query($_tableSql); + return $this; + } + + /** + * Return array of static columns + * + * @return array + */ + protected function _getStaticColumns() + { + $columns = array(); + $columnsToSkip = array('entity_type_id', 'attribute_set_id'); + $describe = $this->_getWriteAdapter()->describeTable($this->getTable('catalog/category')); + foreach ($describe as $column) { + if (in_array($column['COLUMN_NAME'], $columnsToSkip)) { + continue; } - } else { - $_conn->query("DROP TABLE IF EXISTS `{$this->getMainStoreTable($stores)}`"); - $_conn->query($this->_getTableSqlSchema($stores)); - } - $selectAttribute = $_conn->select() - ->from($this->getTable('eav/entity_type'), array()) - ->join( - $this->getTable('eav/attribute'), - $this->getTable('eav/attribute').'.entity_type_id = '.$this->getTable('eav/entity_type').'.entity_type_id', - $this->getTable('eav/attribute').'.*' - ) - ->where($this->getTable('eav/entity_type').'.entity_type_code=?', 'catalog_category'); - $resultAttribute = $_conn->fetchAll($selectAttribute); - foreach ($resultAttribute as $attribute) { - $type = ''; + $_type = ''; + $_is_unsigned = ''; + switch ($column['DATA_TYPE']) { + case 'smallint': + case 'int': + $_type = $column['DATA_TYPE'] . '(11)'; + $_is_unsigned = (bool)$column['UNSIGNED']; + break; + case 'varchar': + $_type = $column['DATA_TYPE'] . '(' . $column['LENGTH'] . ')'; + $_is_unsigned = null; + break; + case 'datetime': + $_type = $column['DATA_TYPE']; + $_is_unsigned = null; + break; + case 'decimal': + $_type = $columns['DATA_TYPE'] . '(' . $column['PRECISION'] . ',' . $column['SCALE'] . ')'; + $_is_unsigned = null; + break; + } + $columns[$column['COLUMN_NAME']] = array( + 'type' => $_type, + 'is_unsigned' => $_is_unsigned, + 'is_null' => $column['NULLABLE'], + 'default' => ($column['DEFAULT'] === null ? false : $column['DEFAULT']) + ); + } + $columns['store_id'] = array( + 'type' => 'smallint(5)', + 'is_unsigned' => true, + 'is_null' => false, + 'default' => '0' + ); + return $columns; + } + + /** + * Return array of eav columns, skip attribute with static type + * + * @return array + */ + protected function _getEavColumns() + { + $columns = array(); + $attributes = $this->_getAttributes(); + foreach ($attributes as $attribute) { + if ($attribute['backend_type'] == 'static') { + continue; + } + $columns[$attribute['attribute_code']] = array(); switch ($attribute['backend_type']) { case 'varchar': - $type = 'varchar(255) not null default \'\''; + $columns[$attribute['attribute_code']] = array( + 'type' => 'varchar(255)', + 'is_unsigned' => null, + 'is_null' => false, + 'default' => '' + ); break; case 'int': - $type = 'int(10) not null default \'0\''; + $columns[$attribute['attribute_code']] = array( + 'type' => 'int(10)', + 'is_unsigned' => null, + 'is_null' => false, + 'default' => '0' + ); break; case 'text': - $type = 'text'; + $columns[$attribute['attribute_code']] = array( + 'type' => 'text', + 'is_unsigned' => null, + 'is_null' => true, + 'default' => null + ); break; case 'datetime': - $type = 'datetime not null default \'0000-00-00 00:00:00\''; + $columns[$attribute['attribute_code']] = array( + 'type' => 'datetime', + 'is_unsigned' => null, + 'is_null' => false, + 'default' => '0000-00-00 00:00:00' + ); break; case 'decimal': - $type = 'decimal(10,2) not null default \'0.00\''; + $columns[$attribute['attribute_code']] = array( + 'type' => 'decimal(12,4)', + 'is_unsigned' => null, + 'is_null' => false, + 'default' => '0.0000' + ); break; } - if ($type) { - if ($this->getUseStoreTables() && is_array($stores)) { - foreach ($stores as $store) { - $_conn->addColumn($this->getMainStoreTable($store), $attribute['attribute_code'], $type); - } - } else { - $_conn->addColumn($this->getMainStoreTable($stores), $attribute['attribute_code'], $type); - } + } + return $columns; + } + + /** + * Return array of attribute codes for entity type 'catalog_category' + * + * @return array + */ + protected function _getAttributes() + { + if ($this->_attributeCodes === null) { + $select = $this->_getWriteAdapter()->select() + ->from($this->getTable('eav/entity_type'), array()) + ->join( + $this->getTable('eav/attribute'), + $this->getTable('eav/attribute').'.entity_type_id = '.$this->getTable('eav/entity_type').'.entity_type_id', + $this->getTable('eav/attribute').'.*' + ) + ->where($this->getTable('eav/entity_type').'.entity_type_code=?', 'catalog_category'); + $this->_attributeCodes = array(); + foreach ($this->_getWriteAdapter()->fetchAll($select) as $attribute) { + $this->_attributeCodes[$attribute['attribute_id']] = $attribute; } } - return $this; + return $this->_attributeCodes; + } + + /** + * Return attribute values for given entities and store + * + * @param array $entityIds + * @param integer $store_id + * @return array + */ + protected function _getAttributeValues($entityIds, $store_id) + { + if (!is_array($entityIds)) { + $entityIds = array($entityIds); + } + $values = array(); + + foreach ($entityIds as $entityId) { + $values[$entityId] = array(); + } + $attributes = $this->_getAttributes(); + $attributesType = array( + 'varchar', + 'int', + 'decimal', + 'text', + 'datetime' + ); + foreach ($attributesType as $type) { + foreach ($this->_getAttributeTypeValues($type, $entityIds, $store_id) as $row) { + $values[$row['entity_id']][$attributes[$row['attribute_id']]['attribute_code']] = $row['value']; + } + } + return $values; + } + + /** + * Return attribute values for given entities and store of specific attribute type + * + * @param string $type + * @param array $entityIds + * @param integer $store_id + * @return array + */ + protected function _getAttributeTypeValues($type, $entityIds, $store_id) + { + $select = $this->_getWriteAdapter()->select() + ->from(array('default' => $this->getTable('catalog/category') . '_' . $type), array('entity_id', 'attribute_id')) + ->joinLeft( + array('store' => $this->getTable('catalog/category') . '_' . $type), + '`store`.entity_id = `default`.entity_id AND `store`.attribute_id = `default`.attribute_id AND `store`.store_id = ' . $store_id, + array('value' => new Zend_Db_Expr('IFNULL(`store`.value, `default`.value)')) + ) + ->where('`default`.entity_id IN (?)', $entityIds) + ->where('`default`.store_id = ?', 0); + return $this->_getWriteAdapter()->fetchAll($select); } /** @@ -547,7 +750,7 @@ protected function _synchronize($category, $action = null) if (is_null($action)) { $select = $this->_getWriteAdapter()->select() ->from($this->getMainStoreTable($category->getStoreId()), 'entity_id') - ->where('entity_id = ?', $category->getId()); + ->where('entity_id = ?', $category->getEntityId()); if ($result = $this->_getWriteAdapter()->fetchOne($select)) { $action = 'update'; } else { @@ -560,7 +763,7 @@ protected function _synchronize($category, $action = null) $this->_getWriteAdapter()->update( $this->getMainStoreTable($category->getStoreId()), $this->_prepareDataForAllFields($category), - $this->_getWriteAdapter()->quoteInto('entity_id = ?', $category->getId()) + $this->_getWriteAdapter()->quoteInto('entity_id = ?', $category->getEntityId()) ); } elseif ($action == 'insert') { // insert @@ -625,7 +828,7 @@ public function synchronize($category = null, $storeIds = array()) } $stores = $this->_getWriteAdapter()->fetchAll(" SELECT - s.store_id, s.website_id, c.path AS root_path + s.store_id, s.website_id, c.path AS root_path, sg.root_category_id FROM {$this->getTable('core/store')} AS s, {$this->getTable('core/store_group')} AS sg, @@ -635,36 +838,30 @@ public function synchronize($category = null, $storeIds = array()) AND c.entity_id=sg.root_category_id {$storesCondition} "); + $storesObjects = array(); foreach ($stores as $store) { - $select = $this->_getWriteAdapter()->select() - ->from($this->getTable('catalog/category'), 'entity_id') - ->where('path LIKE ?', "{$store['root_path']}/%") - ->orWhere('path = ?', $store['root_path']); - $_categories = $this->_getWriteAdapter()->fetchAll($select); - if (!$this->_getWriteAdapter()->showTableStatus($this->getMainStoreTable($store['store_id']))) { - $this->_createTable($store['store_id']); - } - $this->_getWriteAdapter()->delete( - $this->getMainStoreTable($store['store_id']), - $this->_getWriteAdapter()->quoteInto('store_id = ?', $store['store_id']) - ); - foreach ($_categories as $_category) { - $_tmpCategory = Mage::getModel('catalog/category') - ->setStoreId($store['store_id']) - ->load($_category['entity_id']); - $this->_synchronize($_tmpCategory, 'insert'); - } +// if ($this->_getWriteAdapter()->showTableStatus($this->getMainStoreTable($store['store_id']))) { +// $this->_getWriteAdapter()->truncate($this->getMainStoreTable($store['store_id'])); +// } + $_store = new Varien_Object(); + $_store->setData('id', $store['store_id']) + ->setData('root_category_id', $store['root_category_id']); + $storesObjects[] = $_store; } - $_tmpCategory = null; + $this->rebuild($storesObjects); } elseif ($category instanceof Mage_Catalog_Model_Category) { + $categoriesIds = array($category->getId()); foreach ($category->getStoreIds() as $storeId) { - $_tmpCategory = Mage::getModel('catalog/category') - ->setStoreId($storeId) - ->load($category->getId()); - $_tmpCategory->setStoreId($storeId); - $this->_synchronize($_tmpCategory); + if ($storeId == 0) { + continue; + } + $attributesData = $this->_getAttributeValues($categoriesIds, $storeId); + $data = new Varien_Object(); + $data->setData($category->getData()) + ->addData($attributesData[$category->getId()]) + ->setData('store_id', $storeId); + $this->_synchronize($data); } - $_tmpCategory = null; } return $this; } @@ -918,7 +1115,7 @@ public function getAllChildren($category) public function checkId($id) { $select = $this->_getReadAdapter()->select() - ->from($this->getMainStoreTable(), 'entity_id') + ->from($this->getMainStoreTable($this->getStoreId()), 'entity_id') ->where('entity_id=?', $id); return $this->_getReadAdapter()->fetchOne($select); } diff --git a/app/code/core/Mage/Catalog/Model/Resource/Eav/Mysql4/Category/Tree.php b/app/code/core/Mage/Catalog/Model/Resource/Eav/Mysql4/Category/Tree.php index 7c4e3a785c..dc504829cd 100644 --- a/app/code/core/Mage/Catalog/Model/Resource/Eav/Mysql4/Category/Tree.php +++ b/app/code/core/Mage/Catalog/Model/Resource/Eav/Mysql4/Category/Tree.php @@ -58,6 +58,13 @@ class Mage_Catalog_Model_Resource_Eav_Mysql4_Category_Tree extends Varien_Data_T */ protected $_inactiveCategoryIds = null; + /** + * store id + * + * @var integer + */ + protected $_storeId = null; + /** * Enter description here... * @@ -78,6 +85,31 @@ public function __construct() ); } + /** + * Set store id + * + * @param integer $storeId + * @return Mage_Catalog_Model_Resource_Eav_Mysql4_Category_Tree + */ + public function setStoreId($storeId) + { + $this->_storeId = (int) $storeId; + return $this; + } + + /** + * Return store id + * + * @return integer + */ + public function getStoreId() + { + if ($this->_storeId === null) { + $this->_storeId = Mage::app()->getStore()->getId(); + } + return $this->_storeId; + } + /** * Enter description here... * @@ -506,13 +538,21 @@ protected function _createCollectionDataSelect($sorted = true, $optionalAttribut $attribute = Mage::getResourceSingleton('catalog/category')->getAttribute($attributeCode); // join non-static attribute table if (!$attribute->getBackend()->isStatic()) { - $tableAs = "_$attributeCode"; + $defaultTableAs = "default_$attributeCode"; + $storeTableAs = "store_$attributeCode"; $select->joinLeft( - array($tableAs => $attribute->getBackend()->getTable()), + array($defaultTableAs => $attribute->getBackend()->getTable()), sprintf('`%1$s`.entity_id=e.entity_id AND `%1$s`.attribute_id=%2$d AND `%1$s`.entity_type_id=e.entity_type_id AND `%1$s`.store_id=%3$d', - $tableAs, $attribute->getData('attribute_id'), Mage_Core_Model_App::ADMIN_STORE_ID + $defaultTableAs, $attribute->getData('attribute_id'), Mage_Core_Model_App::ADMIN_STORE_ID ), array($attributeCode => 'value') + ) + ->joinLeft( + array($storeTableAs => $attribute->getBackend()->getTable()), + sprintf('`%1$s`.entity_id=e.entity_id AND `%1$s`.attribute_id=%2$d AND `%1$s`.entity_type_id=e.entity_type_id AND `%1$s`.store_id=%3$d', + $storeTableAs, $attribute->getData('attribute_id'), $this->getStoreId() + ), + array($attributeCode => new Zend_Db_Expr("IFNULL(`{$storeTableAs}`.value, `$defaultTableAs`.value)")) ); } } diff --git a/app/code/core/Mage/Catalog/Model/Resource/Eav/Mysql4/Product.php b/app/code/core/Mage/Catalog/Model/Resource/Eav/Mysql4/Product.php index 1160709652..859be61e43 100644 --- a/app/code/core/Mage/Catalog/Model/Resource/Eav/Mysql4/Product.php +++ b/app/code/core/Mage/Catalog/Model/Resource/Eav/Mysql4/Product.php @@ -80,15 +80,15 @@ public function getWebsiteIds($product) /** * Retrieve product category identifiers * - * @param $product - * @return Mage_Catalog_Model_Resource_Eav_Mysql4_Product + * @param Mage_Catalog_Model_Product $product + * @return array */ public function getCategoryIds($product) { - $select = $this->_getWriteAdapter()->select() + $select = $this->_getReadAdapter()->select() ->from($this->_productCategoryTable, 'category_id') ->where('product_id=?', $product->getId()); - return $this->_getWriteAdapter()->fetchCol($select); + return $this->_getReadAdapter()->fetchCol($select); } /** @@ -111,15 +111,15 @@ public function getIdBySku($sku) protected function _beforeSave(Varien_Object $object) { if (!$object->getId() && $object->getSku()) { - $object->setId($this->getIdBySku($object->getSku())); + $object->setId($this->getIdBySku($object->getSku())); } $categoryIds = $object->getCategoryIds(); if ($categoryIds) { $categoryIds = Mage::getModel('catalog/category')->verifyIds($categoryIds); + $object->setCategoryIds($categoryIds); } - $object->setData('category_ids', implode(',', $categoryIds)); return parent::_beforeSave($object); } @@ -191,15 +191,14 @@ protected function _saveWebsiteIds($product) /** * Save product category relations * - * @param Mage_Catalog_Model_Product $product - * @return Mage_Catalog_Model_Resource_Eav_Mysql4_Product + * @param Mage_Catalog_Model_Product $product + * @return Mage_Catalog_Model_Resource_Eav_Mysql4_Product */ protected function _saveCategories(Varien_Object $object) { $categoryIds = $object->getCategoryIds(); - $oldCategoryIds = $object->getOrigData('category_ids'); - $oldCategoryIds = !empty($oldCategoryIds) ? explode(',', $oldCategoryIds) : array(); + $oldCategoryIds = $this->getCategoryIds($object); $object->setIsChangedCategories(false); @@ -208,23 +207,28 @@ protected function _saveCategories(Varien_Object $object) $write = $this->_getWriteAdapter(); if (!empty($insert)) { - $insertSql = array(); - foreach ($insert as $v) { - if (!empty($v)) { - $insertSql[] = '('.(int)$v.','.$object->getId().',0)'; + $data = array(); + foreach ($insert as $categoryId) { + if (empty($categoryId)) { + continue; } - }; - if ($insertSql) { - $write->query("insert into {$this->_productCategoryTable} - (category_id, product_id, position) values ".join(',', $insertSql)); + $data[] = array( + 'category_id' => (int)$categoryId, + 'product_id' => $object->getId(), + 'position' => 1 + ); + } + if ($data) { + $write->insertMultiple($this->_productCategoryTable, $data); } } if (!empty($delete)) { - $write->delete($this->_productCategoryTable, - $write->quoteInto('product_id=?', $object->getId()) - .' and '.$write->quoteInto('category_id in (?)', $delete) - ); + $where = join(' AND ', array( + $write->quoteInto('product_id=?', $object->getId()), + $write->quoteInto('category_id IN(?)', $delete) + )); + $write->delete($this->_productCategoryTable, $where); } if (!empty($insert) || !empty($delete)) { @@ -411,6 +415,20 @@ public function getCategoryCollection($product) return $collection; } + /** + * Retrieve category ids where product is available + * + * @param Mage_Catalog_Model_Product $object + * @return array + */ + public function getAvailableInCategories($object) + { + $select = $this->_getReadAdapter()->select() + ->from($this->getTable('catalog/category_product_index'), array('category_id')) + ->where('product_id=?', $object->getEntityId()); + return $this->_getReadAdapter()->fetchCol($select); + } + /** * Get default attribute source model * diff --git a/app/code/core/Mage/Catalog/Model/Resource/Eav/Mysql4/Product/Collection.php b/app/code/core/Mage/Catalog/Model/Resource/Eav/Mysql4/Product/Collection.php index efdc4e91f5..74341c80eb 100644 --- a/app/code/core/Mage/Catalog/Model/Resource/Eav/Mysql4/Product/Collection.php +++ b/app/code/core/Mage/Catalog/Model/Resource/Eav/Mysql4/Product/Collection.php @@ -101,11 +101,12 @@ class Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection * Product limitation filters * * Allowed filters - * store_id - * category_id - * category_is_anchor - * visibility - * website_ids + * store_id int; + * category_id int; + * category_is_anchor int; + * visibility array|int; + * website_ids array|int; + * store_table string; * * @var array */ @@ -288,7 +289,7 @@ public function _loadAttributes($printQuery = false, $logQuery = false) * If $attribute=='*' select all attributes * * @param array|string|integer|Mage_Core_Model_Config_Element $attribute - * @return Mage_Eav_Model_Entity_Collection_Abstract + * @return Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection */ public function addAttributeToSelect($attribute, $joinType = false) { @@ -351,12 +352,51 @@ protected function _afterLoad() if ($this->_addFinalPrice) { $this->_addFinalPrice(); } + + $this->_prepareUrlDataObject(); + if (count($this) > 0) { Mage::dispatchEvent('catalog_product_collection_load_after', array('collection'=>$this)); } return $this; } + /** + * Prepare Url Data object + * + * @return Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection + */ + protected function _prepareUrlDataObject() + { + if (!$this->hasFlag('url_data_object')) { + return $this; + } + + $objects = array(); + /* @var $item Mage_Catalog_Model_Product */ + foreach ($this->_items as $item) { + if ($this->getFlag('do_not_use_category_id')) { + $item->setDoNotUseCategoryId(true); + } + if (!$item->isVisibleInSiteVisibility() && $item->getItemStoreId()) { + $objects[$item->getEntityId()] = $item->getItemStoreId(); + } + } + + if ($objects) { + $objects = Mage::getResourceSingleton('catalog/url') + ->getRewriteByProductStore($objects); + foreach ($this->_items as $item) { + if (isset($objects[$item->getEntityId()])) { + $object = new Varien_Object($objects[$item->getEntityId()]); + $item->setUrlDataObject($object); + } + } + } + + return $this; + } + /** * Add collection filters by identifiers * @@ -1176,6 +1216,9 @@ public function addAttributeToSort($attribute, $dir='asc') if ($column) { $this->getSelect()->order("e.{$column} {$dir}"); } + else if (isset($this->_joinFields[$attribute])) { + $this->getSelect()->order($this->_getAttributeFieldName($attribute).' '.$dir); + } return $this; } else { @@ -1270,6 +1313,75 @@ protected function _productLimitationJoinWebsite() return $this; } + /** + * Join additional (alternative) store visibility filter + * + * @return Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection + */ + protected function _productLimitationJoinStore() + { + $filters = $this->_productLimitationFilters; + if (!isset($filters['store_table'])) { + return $this; + } + + $hasColumn = false; + foreach ($this->getSelect()->getPart(Zend_Db_Select::COLUMNS) as $columnEntry) { + list(,,$alias) = $columnEntry; + if ($alias == 'visibility') { + $hasColumn = true; + } + } + if (!$hasColumn) { + $this->getSelect()->columns('visibility', 'cat_index'); + } + + $fromPart = $this->getSelect()->getPart(Zend_Db_Select::FROM); + if (!isset($fromPart['store_index'])) { + $this->getSelect()->joinLeft( + array('store_index' => $this->getTable('core/store')), + 'store_index.store_id='.$filters['store_table'].'.store_id', + array() + ); + } + if (!isset($fromPart['store_group_index'])) { + $this->getSelect()->joinLeft( + array('store_group_index' => $this->getTable('core/store_group')), + 'store_index.group_id=store_group_index.group_id', + array() + ); + } + if (!isset($fromPart['store_cat_index'])) { + $this->getSelect()->joinLeft( + array('store_cat_index' => $this->getTable('catalog/category_product_index')), + join(' AND ', array( + 'store_cat_index.product_id=e.entity_id', + 'store_cat_index.store_id='.$filters['store_table'].'.store_id', + 'store_cat_index.category_id=store_group_index.root_category_id' + )), + array('store_visibility' => 'visibility') + ); + } + $whereCond = join(' OR ', array( + $this->getConnection()->quoteInto('cat_index.visibility IN(?)', $filters['visibility']), + $this->getConnection()->quoteInto('store_cat_index.visibility IN(?)', $filters['visibility']) + )); + + $wherePart = $this->getSelect()->getPart(Zend_Db_Select::WHERE); + $hasCond = false; + foreach ($wherePart as $cond) { + if ($cond == '('.$whereCond.')') { + $hasCond = true; + } + } + + if (!$hasCond) { + $this->getSelect()->where($whereCond); + } + + return $this; + } + /** * Apply limitation filters to collection * @@ -1294,7 +1406,7 @@ protected function _applyProductLimitations() 'cat_index.product_id=e.entity_id', $this->getConnection()->quoteInto('cat_index.store_id=?', $filters['store_id']) ); - if (isset($filters['visibility'])) { + if (isset($filters['visibility']) && !isset($filters['store_table'])) { $conditions[] = $this->getConnection() ->quoteInto('cat_index.visibility IN(?)', $filters['visibility']); } @@ -1319,6 +1431,8 @@ protected function _applyProductLimitations() ); } + $this->_productLimitationJoinStore(); + Mage::dispatchEvent('catalog_product_collection_apply_limitations_after', array( 'collection' => $this )); diff --git a/app/code/core/Mage/Catalog/Model/Resource/Eav/Mysql4/Product/Compare/Item.php b/app/code/core/Mage/Catalog/Model/Resource/Eav/Mysql4/Product/Compare/Item.php index d591c3d767..396d5b74f5 100644 --- a/app/code/core/Mage/Catalog/Model/Resource/Eav/Mysql4/Product/Compare/Item.php +++ b/app/code/core/Mage/Catalog/Model/Resource/Eav/Mysql4/Product/Compare/Item.php @@ -57,15 +57,18 @@ public function loadByProduct(Mage_Catalog_Model_Product_Compare_Item $object, $ $productId = $product->getId(); } else { - $productId = (int) $product; + $productId = (int)$product; } $select = $read->select()->from($this->getMainTable()) - ->where('product_id=?', $productId) - ->where('visitor_id=?', $object->getVisitorId()); + ->where('product_id=?', $productId); + if ($object->getCustomerId()) { $select->where('customer_id=?', $object->getCustomerId()); } + else { + $select->where('visitor_id=?', $object->getVisitorId()); + } $data = $read->fetchRow($select); @@ -99,21 +102,20 @@ public function getCount($customerId, $visitorId) /** * Clean compare table * - * @param Mage_Catalog_Model_Product_Compare_Item $object * @return Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Compare_Item */ - public function clean(Mage_Catalog_Model_Product_Compare_Item $object) + public function clean() { while (true) { $select = $this->_getReadAdapter()->select() ->from(array('compare_table' => $this->getMainTable()), array('catalog_compare_item_id')) ->joinLeft( array('visitor_table' => $this->getTable('log/visitor')), - '`visitor_table`.`visitor_id`=`compare_table`.`visitor_id`', + '`visitor_table`.`visitor_id`=`compare_table`.`visitor_id` AND `compare_table`.`customer_id` IS NULL', array()) - ->where('compare_table.visitor_id>?',0) + ->where('compare_table.visitor_id>?', 0) ->where('`visitor_table`.`visitor_id` IS NULL') - ->limit(1000); + ->limit(100); $itemIds = $this->_getReadAdapter()->fetchCol($select); if (!$itemIds) { @@ -128,4 +130,95 @@ public function clean(Mage_Catalog_Model_Product_Compare_Item $object) return $this; } + + /** + * Purge visitor data after customer logout + * + * @param Mage_Catalog_Model_Product_Compare_Item $object + * @return Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Compare_Item + */ + public function purgeVisitorByCustomer($object) + { + if (!$object->getCustomerId()) { + return $this; + } + + $where = $this->_getWriteAdapter()->quoteInto('customer_id=?', $object->getCustomerId()); + $bind = array( + 'visitor_id' => 0, + ); + + $this->_getWriteAdapter()->update($this->getMainTable(), $bind, $where); + + return $this; + } + + /** + * Update (Merge) customer data from visitor + * + * After Login process + * + * @param Mage_Catalog_Model_Product_Compare_Item $object + * @return Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Compare_Item + */ + public function updateCustomerFromVisitor($object) + { + if (!$object->getCustomerId()) { + return $this; + } + + // collect visitor compared items + $select = $this->_getWriteAdapter()->select() + ->from($this->getMainTable()) + ->where('visitor_id=?', $object->getVisitorId()); + $visitor = $this->_getWriteAdapter()->fetchAll($select); + + // collect customer compared items + $select = $this->_getWriteAdapter()->select() + ->from($this->getMainTable()) + ->where('customer_id=?', $object->getCustomerId()) + ->where('visitor_id<>?', $object->getVisitorId()); + $customer = $this->_getWriteAdapter()->fetchAll($select); + + $products = array(); + $delete = array(); + $update = array(); + foreach ($visitor as $row) { + $products[$row['product_id']] = array( + 'store_id' => $row['store_id'], + 'customer_id' => $object->getCustomerId(), + 'visitor_id' => $object->getVisitorId(), + 'product_id' => $row['product_id'] + ); + $update[$row[$this->getIdFieldName()]] = $row['product_id']; + } + + foreach ($customer as $row) { + if (isset($products[$row['product_id']])) { + $delete[] = $row[$this->getIdFieldName()]; + } + else { + $products[$row['product_id']] = array( + 'store_id' => $row['store_id'], + 'customer_id' => $object->getCustomerId(), + 'visitor_id' => $object->getVisitorId(), + 'product_id' => $row['product_id'] + ); + } + } + + if ($delete) { + $this->_getWriteAdapter()->delete($this->getMainTable(), + $this->_getWriteAdapter()->quoteInto($this->getIdFieldName() . ' IN(?)', $delete)); + } + if ($update) { + foreach ($update as $itemId => $productId) { + $bind = $products[$productId]; + $this->_getWriteAdapter()->update($this->getMainTable(), $bind, + $this->_getWriteAdapter()->quoteInto($this->getIdFieldName() . '=?', $itemId)); + } + } + + return $this; + } } diff --git a/app/code/core/Mage/Catalog/Model/Resource/Eav/Mysql4/Product/Compare/Item/Collection.php b/app/code/core/Mage/Catalog/Model/Resource/Eav/Mysql4/Product/Compare/Item/Collection.php index 9e4f024dc8..de3f5e1b8d 100644 --- a/app/code/core/Mage/Catalog/Model/Resource/Eav/Mysql4/Product/Compare/Item/Collection.php +++ b/app/code/core/Mage/Catalog/Model/Resource/Eav/Mysql4/Product/Compare/Item/Collection.php @@ -138,18 +138,20 @@ public function getConditionForJoin() */ public function _addJoinToSelect() { - $this->joinField( - 'catalog_compare_item_id', - 'catalog/compare_item', - 'catalog_compare_item_id', + $this->joinTable( + array('t_compare' => 'catalog/compare_item'), 'product_id=entity_id', + array( + 'product_id' => 'product_id', + 'customer_id' => 'customer_id', + 'visitor_id' => 'visitor_id', + 'item_store_id' => 'store_id', + ), $this->getConditionForJoin() ); - $this->joinTable( - 'catalog/compare_item', - 'catalog_compare_item_id=catalog_compare_item_id', - array('product_id', 'customer_id', 'visitor_id')); - $this->addStoreFilter(); + + $this->_productLimitationFilters['store_table'] = 't_compare'; + return $this; } @@ -274,6 +276,10 @@ public function loadComparableAttributes() public function useProductItem() { $this->setObject('catalog/product'); + + $this->setFlag('url_data_object', true); + $this->setFlag('do_not_use_category_id', true); + return $this; } @@ -312,6 +318,8 @@ public function clear() $this->getConnection()->delete($this->getTable('catalog/compare_item'), $where); + Mage::dispatchEvent('catalog_product_compare_item_collection_clear'); + return $this; } diff --git a/app/code/core/Mage/Catalog/Model/Resource/Eav/Mysql4/Product/Flat.php b/app/code/core/Mage/Catalog/Model/Resource/Eav/Mysql4/Product/Flat.php index b90eb06955..6620eda4c2 100644 --- a/app/code/core/Mage/Catalog/Model/Resource/Eav/Mysql4/Product/Flat.php +++ b/app/code/core/Mage/Catalog/Model/Resource/Eav/Mysql4/Product/Flat.php @@ -53,7 +53,17 @@ protected function _construct() } /** - * Set store scope for resource model + * Retrieve store for resource model + * + * @return int + */ + public function getStoreId() + { + return $this->_storeId; + } + + /** + * Set store for resource model * * @param mixed $store * @return Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Flat @@ -72,8 +82,8 @@ public function setStoreId($store) */ public function getFlatTableName($store = null) { - if (!is_numeric($store)) { - $store = Mage::app()->getStore($store)->getId(); + if (is_null($store)) { + $store = $this->getStoreId(); } return $this->getTable('catalog/product_flat') . '_' . $store; } @@ -193,4 +203,14 @@ public function getAttribute($attribute) return Mage::getSingleton('catalog/config') ->getAttribute('catalog_product', $attribute); } + + /** + * Retrieve main resource table name + * + * @return string + */ + public function getMainTable() + { + return $this->getFlatTableName($this->getStoreId()); + } } diff --git a/app/code/core/Mage/Catalog/Model/Resource/Eav/Mysql4/Product/Flat/Indexer.php b/app/code/core/Mage/Catalog/Model/Resource/Eav/Mysql4/Product/Flat/Indexer.php index 1ad39934ec..075503c0fc 100644 --- a/app/code/core/Mage/Catalog/Model/Resource/Eav/Mysql4/Product/Flat/Indexer.php +++ b/app/code/core/Mage/Catalog/Model/Resource/Eav/Mysql4/Product/Flat/Indexer.php @@ -390,6 +390,109 @@ public function getFlatIndexes() return $this->_indexes; } + /** + * Compare Flat style with Describe style columns + * + * If column a different - return false + * + * @param array $column + * @param array $describe + * @return bool + */ + protected function _compareColumnProperties($column, $describe) + { + $type = $column['type']; + $length = null; + $precision = null; + $scale = null; + + $matches = array(); + if (preg_match('/^((?:var)?char)\((\d+)\)/', $type, $matches)) { + $type = $matches[1]; + $length = $matches[2]; + } else if (preg_match('/^decimal\((\d+),(\d+)\)/', $type, $matches)) { + $type = 'decimal'; + $precision = $matches[1]; + $scale = $matches[2]; + } else if (preg_match('/^float\((\d+),(\d+)\)/', $type, $matches)) { + $type = 'float'; + $precision = $matches[1]; + $scale = $matches[2]; + } else if (preg_match('/^((?:big|medium|small|tiny)?int)\((\d+)\)?/', $type, $matches)) { + $type = $matches[1]; + } + + return ($describe['DATA_TYPE'] == $type) + && ($describe['DEFAULT'] == $column['default']) + && ((bool)$describe['NULLABLE'] == (bool)$column['is_null']) + && ((bool)$describe['UNSIGNED'] == (bool)$column['unsigned']) + && ($describe['LENGTH'] == $length) + && ($describe['SCALE'] == $scale) + && ($describe['PRECISION'] == $precision); + } + + /** + * Retrieve column definition fragment + * + * Example: `field_name` smallint(5) unsigned NOT NULL default '0' + * + * @param string $fieldName + * @param array $fieldProp + * @return string + */ + protected function _sqlColunmDefinition($fieldName, $fieldProp) + { + $fieldNameQuote = $this->_getWriteAdapter()->quoteIdentifier($fieldName); + return "{$fieldNameQuote} {$fieldProp['type']}" + . ($fieldProp['unsigned'] ? ' UNSIGNED' : '') + . ($fieldProp['extra'] ? ' ' . $fieldProp['extra'] : '') + . ($fieldProp['is_null'] === false ? ' NOT NULL' : '') + . ($fieldProp['default'] === null ? ' DEFAULT NULL' : $this->_getReadAdapter() + ->quoteInto(' DEFAULT ?', $fieldProp['default'])); + } + + /** + * Retrieve index definition fragment + * + * Example: INDEX `IDX_NAME` (`field_id`) + * + * @param string $indexName + * @param array $indexProp + * @return string + */ + protected function _sqlIndexDefinition($indexName, $indexProp) + { + $fields = $indexProp['fields']; + if (is_array($fields)) { + $fieldSql = array(); + foreach ($fields as $field) { + $fieldSql[] = $this->_getReadAdapter()->quoteIdentifier($field); + } + $fieldSql = join(',', $fieldSql); + } + else { + $fieldSql = $this->_getReadAdapter()->quoteIdentifier($fields); + } + + $indexNameQuote = $this->_getReadAdapter()->quoteIdentifier($indexName); + switch (strtolower($indexProp['type'])) { + case 'primary': + $condition = 'PRIMARY KEY'; + break; + case 'unique': + $condition = 'UNIQUE ' . $indexNameQuote; + break; + case 'fulltext': + $condition = 'FULLTEXT ' . $indexNameQuote; + break; + default: + $condition = 'INDEX ' . $indexNameQuote; + break; + } + + return sprintf('%s (%s)', $condition, $fieldSql); + } + /** * Prepare flat table for store * @@ -414,45 +517,12 @@ public function prepareFlatTable($store) if (!$this->_getWriteAdapter()->fetchRow($tableExistsSql)) { $sql = "CREATE TABLE {$tableNameQuote} (\n"; foreach ($columns as $field => $fieldProp) { - $fieldNameQuote = $this->_getWriteAdapter()->quoteIdentifier($field); - $sql .= " {$fieldNameQuote} {$fieldProp['type']}"; - $sql .= ($fieldProp['unsigned'] ? ' UNSIGNED' : ''); - $sql .= ($fieldProp['extra'] ? ' ' . $fieldProp['extra'] : ''); - $sql .= ($fieldProp['is_null'] === false ? ' NOT NULL' : ''); - $sql .= ($fieldProp['default'] === null - ? ' DEFAULT NULL' - : $this->_getReadAdapter()->quoteInto(' DEFAULT ?', $fieldProp['default'])); - $sql .= ",\n"; + $sql .= sprintf(" %s,\n", + $this->_sqlColunmDefinition($field, $fieldProp)); } foreach ($indexes as $indexName => $indexProp) { - $fields = $indexProp['fields']; - if (is_array($fields)) { - $fieldSql = array(); - foreach ($fields as $field) { - $fieldSql[] = $this->_getReadAdapter()->quoteIdentifier($field); - } - $fieldSql = join(',', $fieldSql); - } - else { - $fieldSql = $this->_getReadAdapter()->quoteIdentifier($fields); - } - - switch (strtolower($indexProp['type'])) { - case 'primary': - $condition = 'PRIMARY KEY'; - break; - case 'unique': - $condition = 'UNIQUE ' . $this->_getReadAdapter()->quoteIdentifier($indexName); - break; - case 'fulltext': - $condition = 'FULLTEXT ' . $this->_getReadAdapter()->quoteIdentifier($indexName); - break; - default: - $condition = 'KEY ' . $this->_getReadAdapter()->quoteIdentifier($indexName); - break; - } - - $sql .= " {$condition} (" . $fieldSql . "),\n"; + $sql .= sprintf(" %s,\n", + $this->_sqlIndexDefinition($indexName, $indexProp)); } $sql .= " CONSTRAINT `FK_CATALOG_PRODUCT_FLAT_{$store}_ENTITY` FOREIGN KEY (`entity_id`)" @@ -470,6 +540,7 @@ public function prepareFlatTable($store) $addColumns = array_diff_key($columns, $describe); $dropColumns = array_diff_key($describe, $columns); + $modifyColumns = array(); $addIndexes = array_diff_key($indexes, $indexList); $dropIndexes = array_diff_key($indexList, $indexes); @@ -492,6 +563,13 @@ public function prepareFlatTable($store) ); } + foreach ($columns as $field => $fieldProp) { + if (isset($describe[$field]) + && !$this->_compareColumnProperties($fieldProp, $describe[$field])) { + $modifyColumns[$field] = $fieldProp; + } + } + foreach ($indexList as $indexName => $indexProp) { if (isset($indexes[$indexName]) && ($indexes[$indexName]['type'] != $indexProp['type'])) { $dropIndexes[$indexName] = $indexProp; @@ -499,13 +577,14 @@ public function prepareFlatTable($store) } } - if ($addColumns or $dropColumns or $addIndexes or $dropIndexes) { + if ($addColumns or $dropColumns or $modifyColumns or $addIndexes or $dropIndexes) { $sql = "ALTER TABLE {$tableNameQuote}"; // drop columns foreach ($dropColumns as $columnName => $columnProp) { $columnNameQuote = $this->_getWriteAdapter()->quoteIdentifier($columnName); $sql .= " DROP COLUMN {$columnNameQuote},"; } + // drop indexes foreach ($dropIndexes as $indexName => $indexProp) { if ($indexName == 'PRIMARY') { @@ -517,54 +596,26 @@ public function prepareFlatTable($store) } } + // modify colunm + foreach ($modifyColumns as $columnName => $columnProp) { + $sql .= sprintf(' MODIFY COLUMN %s,', + $this->_sqlColunmDefinition($columnName, $columnProp)); + } + // add columns foreach ($addColumns as $columnName => $columnProp) { - //var_dump($columnProp); - $columnNameQuote = $this->_getWriteAdapter()->quoteIdentifier($columnName); - $sql .= " ADD COLUMN {$columnNameQuote} {$columnProp['type']}"; - $sql .= ($columnProp['unsigned'] ? ' UNSIGNED' : ''); - $sql .= ($columnProp['extra'] ? ' ' . $columnProp['extra'] : ''); - $sql .= ($columnProp['is_null'] === false ? ' NOT NULL' : ''); - $sql .= ($columnProp['default'] === null - ? ' DEFAULT NULL' - : $this->_getReadAdapter()->quoteInto(' DEFAULT ?', $columnProp['default'])); - if ($afterField = $this->_arrayPrevKey($columns, $columnName)) { - $sql .= ' AFTER ' . $this->_getWriteAdapter()->quoteIdentifier($afterField); + $sql .= sprintf(' ADD COLUMN %s', + $this->_sqlColunmDefinition($columnName, $columnProp)); + $afterColumn = $this->_arrayPrevKey($columns, $columnName); + if ($afterColumn) { + $sql .= ' AFTER ' . $this->_getWriteAdapter()->quoteIdentifier($afterColumn); } - $sql .= ","; + $sql .= ','; } // add indexes foreach ($addIndexes as $indexName => $indexProp) { - $indexNameQuote = $this->_getWriteAdapter()->quoteIdentifier($indexName); - - switch (strtolower($indexProp['type'])) { - case 'primary': - $condition = 'PRIMARY KEY'; - break; - case 'unique': - $condition = 'UNIQUE ' . $indexNameQuote; - break; - case 'fulltext': - $condition = 'FULLTEXT ' . $indexNameQuote; - break; - default: - $condition = 'INDEX ' . $indexNameQuote; - break; - } - - $fields = $indexProp['fields']; - if (is_array($fields)) { - $fieldSql = array(); - foreach ($fields as $field) { - $fieldSql[] = $this->_getReadAdapter()->quoteIdentifier($field); - } - $fieldSql = join(',', $fieldSql); - } - else { - $fieldSql = $this->_getReadAdapter()->quoteIdentifier($fields); - } - - $sql .= " ADD {$condition} ({$fieldSql}),"; + $sql .= sprintf(' ADD %s,', + $this->_sqlIndexDefinition($indexName, $indexProp)); } $sql = rtrim($sql, ","); $this->_getWriteAdapter()->query($sql); diff --git a/app/code/core/Mage/Catalog/Model/Resource/Eav/Mysql4/Product/Type/Configurable/Attribute.php b/app/code/core/Mage/Catalog/Model/Resource/Eav/Mysql4/Product/Type/Configurable/Attribute.php index 160fe465fb..7890ec1264 100644 --- a/app/code/core/Mage/Catalog/Model/Resource/Eav/Mysql4/Product/Type/Configurable/Attribute.php +++ b/app/code/core/Mage/Catalog/Model/Resource/Eav/Mysql4/Product/Type/Configurable/Attribute.php @@ -269,4 +269,26 @@ public function savePrices($attribute) return $this; } + + /** + * Retrieve Used in Configurable Products Attributes + * + * @param int $setId The specific attribute set + * @return array + */ + public function getUsedAttributes($setId) + { + $select = $this->_getReadAdapter()->select() + ->distinct(true) + ->from(array('e' => $this->getTable('catalog/product')), null) + ->join( + array('a' => $this->getMainTable()), + 'e.entity_id=a.product_id', + array('attribute_id') + ) + ->where('e.attribute_set_id=?', $setId) + ->where('e.type_id=?', Mage_Catalog_Model_Product_Type::TYPE_CONFIGURABLE); + + return $this->_getReadAdapter()->fetchCol($select); + } } diff --git a/app/code/core/Mage/Catalog/Model/Resource/Eav/Mysql4/Url.php b/app/code/core/Mage/Catalog/Model/Resource/Eav/Mysql4/Url.php index 4581879c3f..b1b644e2c0 100644 --- a/app/code/core/Mage/Catalog/Model/Resource/Eav/Mysql4/Url.php +++ b/app/code/core/Mage/Catalog/Model/Resource/Eav/Mysql4/Url.php @@ -20,7 +20,7 @@ * * @category Mage * @package Mage_Catalog - * @copyright Copyright (c) 2008 Irubin Consulting Inc. DBA Varien (http://www.varien.com) + * @copyright Copyright (c) 2009 Irubin Consulting Inc. DBA Varien (http://www.varien.com) * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ @@ -29,7 +29,7 @@ * * @category Mage * @package Mage_Catalog - * @author Magento Core Team + * @author Magento Core Team */ class Mage_Catalog_Model_Resource_Eav_Mysql4_Url extends Mage_Core_Model_Mysql4_Abstract { @@ -151,6 +151,14 @@ public function getRewriteByRequestPath($requestPath, $storeId) return $rewrite; } + /** + * Prepare rewrites for condition + * + * @param int $storeId + * @param int|array $categoryIds + * @param int|array $productIds + * @return array + */ public function prepareRewrites($storeId, $categoryIds = null, $productIds = null) { $rewrites = array(); @@ -185,7 +193,7 @@ public function prepareRewrites($storeId, $categoryIds = null, $productIds = nul } /** - * Save rewrite url + * Save rewrite URL * * @param array $rewriteData * @param Varien_Object $rewriteObject @@ -208,7 +216,7 @@ public function saveRewrite($rewriteData, $rewrite) $this->_getWriteAdapter()->insert($this->getMainTable(), $rewriteData); } catch (Exception $e) { - Mage::throwException(Mage::helper('catalog')->__('Url rewrie save problem.')); + Mage::throwException(Mage::helper('catalog')->__('URL rewrite save problem.')); } } unset($rewriteData); @@ -499,7 +507,7 @@ public function _getProductAttribute($attributeCode, $productIds, $storeId) protected function _prepareCategoryParentId(Varien_Object $category) { if ($category->getPath() != $category->getId()) { - $split = split('/', $category->getPath()); + $split = explode('/', $category->getPath()); $category->setParentId($split[(count($split) - 2)]); } else { @@ -537,6 +545,14 @@ protected function _prepareStoreRootCategories($stores) return $stores; } + /** + * Retrieve categories objects + * + * @param int|array $categoryIds + * @param int $storeId + * @param string $path + * @return array + */ protected function _getCategories($categoryIds, $storeId = null, $path = null) { $isActiveAttribute = Mage::getModel('eav/entity_attribute')->loadByCode('catalog_category', 'is_active'); @@ -592,6 +608,13 @@ protected function _getCategories($categoryIds, $storeId = null, $path = null) return $categories; } + /** + * Retrieve category data object + * + * @param int $categoryId + * @param int $storeId + * @return Varien_Object + */ public function getCategory($categoryId, $storeId) { if (!$categoryId || !$storeId) { @@ -605,6 +628,13 @@ public function getCategory($categoryId, $storeId) return false; } + /** + * Retrieve categories data objects by ids + * + * @param int|array $categoryIds + * @param int $storeId + * @return array + */ public function getCategories($categoryIds, $storeId) { if (!$categoryIds || !$storeId) { @@ -614,6 +644,12 @@ public function getCategories($categoryIds, $storeId) return $this->_getCategories($categoryIds, $storeId); } + /** + * Retrieve category childs data objects + * + * @param Varien_Object $category + * @return Varien_Object + */ public function loadCategoryChilds(Varien_Object $category) { if (is_null($category->getId()) || is_null($category->getStoreId())) { @@ -643,6 +679,12 @@ public function loadCategoryChilds(Varien_Object $category) return $category; } + /** + * Retrieve category parent path + * + * @param Varien_Object $category + * @return string + */ public function getCategoryParentPath(Varien_Object $category) { $store = Mage::app()->getStore($category->getStoreId()); @@ -658,6 +700,12 @@ public function getCategoryParentPath(Varien_Object $category) } } + /** + * Retrieve product ids by category + * + * @param Varien_Object|int $category + * @return array + */ public function getProductIdsByCategory($category) { $productIds = array(); @@ -679,6 +727,15 @@ public function getProductIdsByCategory($category) return $productIds; } + /** + * Retrieve Product data objects + * + * @param int|array $productIds + * @param int $storeId + * @param int $entityId + * @param int $lastEntityId + * @return array + */ protected function _getProducts($productIds = null, $storeId, $entityId = 0, &$lastEntityId) { $products = array(); @@ -690,7 +747,7 @@ protected function _getProducts($productIds = null, $storeId, $entityId = 0, &$l } } $select = $this->_getWriteAdapter()->select() - ->from(array('e' => $this->getTable('catalog/product')), array('entity_id', 'category_ids')) + ->from(array('e' => $this->getTable('catalog/product')), array('entity_id')) ->join( array('w' => $this->getTable('catalog/product_website')), $this->_getWriteAdapter()->quoteInto('e.entity_id=w.product_id AND w.website_id=?', $websiteId), @@ -703,11 +760,11 @@ protected function _getProducts($productIds = null, $storeId, $entityId = 0, &$l $select->where('e.entity_id IN(?)', $productIds); } - $query = $this->_getWriteAdapter()->query((string)$select); + $query = $this->_getWriteAdapter()->query($select); while ($row = $query->fetch()) { $product = new Varien_Object($row); $product->setIdFieldName('entity_id'); - $product->setCategoryIds(split(',', $product->getCategoryIds())); + $product->setCategoryIds(array()); $products[$product->getId()] = $product; $lastEntityId = $product->getId(); } @@ -715,6 +772,18 @@ protected function _getProducts($productIds = null, $storeId, $entityId = 0, &$l unset($query); if ($products) { + $select = $this->_getReadAdapter()->select() + ->from( + $this->getTable('catalog/category_product'), + array('product_id', 'category_id')) + ->where('product_id IN(?)', array_keys($products)); + $categories = $this->_getReadAdapter()->fetchPairs($select); + foreach ($categories as $productId => $categoryId) { + $categoryIds = $products[$productId]->getCategoryIds(); + $categoryIds[] = $categoryId; + $products[$productId]->setCategoryIds($categoryIds); + } + foreach (array('name', 'url_key', 'url_path') as $attributeCode) { $attributes = $this->_getProductAttribute($attributeCode, array_keys($products), $storeId); foreach ($attributes as $productId => $attributeValue) { @@ -726,6 +795,13 @@ protected function _getProducts($productIds = null, $storeId, $entityId = 0, &$l return $products; } + /** + * Retrieve Product data object + * + * @param int $productId + * @param int $storeId + * @return Varien_Object + */ public function getProduct($productId, $storeId) { $lastId = 0; @@ -736,11 +812,25 @@ public function getProduct($productId, $storeId) return false; } + /** + * Retrieve Product data obects for store + * + * @param int $storeId + * @param int $lastEntityId + * @return array + */ public function getProductsByStore($storeId, &$lastEntityId) { return $this->_getProducts(null, $storeId, $lastEntityId, $lastEntityId); } + /** + * Retrieve Product data objects in category + * + * @param Varien_Object $category + * @param int $lastEntityId + * @return array + */ public function getProductsByCategory(Varien_Object $category, &$lastEntityId) { $productIds = $this->getProductIdsByCategory($category); @@ -750,6 +840,12 @@ public function getProductsByCategory(Varien_Object $category, &$lastEntityId) return $this->_getProducts($productIds, $category->getStoreId(), $lastEntityId, $lastEntityId); } + /** + * Remove unused rewrite URLs + * + * @param int $storeId + * @return Mage_Catalog_Model_Resource_Eav_Mysql4_Url + */ public function clearCategoryProduct($storeId) { $select = $this->_getWriteAdapter()->select() @@ -771,6 +867,8 @@ public function clearCategoryProduct($storeId) $where = $this->_getWriteAdapter()->quoteInto($this->getIdFieldName() . ' IN(?)', $rewriteIds); $this->_getWriteAdapter()->delete($this->getMainTable(), $where); } + + return $this; } /** @@ -791,100 +889,57 @@ public function deleteCategoryProductRewrites($categoryId, $productIds) return $this; } + /** + * Retrieve rewrites and visibility by store + * + * Input array format: + * product_id as key and store_id as value + * + * Output array format (product_id as key) + * store_id int; store id + * visibility int; visibility for store + * url_rewrite string; rewrite URL for store + * + * @param array $products + * @return array + */ + public function getRewriteByProductStore(array $products) + { + $result = array(); + + if (empty($products)) { + return $result; + } + + $select = $this->_getReadAdapter()->select() + ->from( + array('i' => $this->getTable('catalog/category_product_index')), + array('product_id', 'store_id', 'visibility')) + ->joinLeft( + array('r' => $this->getMainTable()), + 'i.product_id = r.product_id AND i.store_id=r.store_id AND r.category_id IS NULL', + array('request_path') + ); + foreach ($products as $productId => $storeId) { + $catId = Mage::app()->getStore($storeId)->getRootCategoryId(); + $cond = join(' AND ', array( + $this->_getReadAdapter()->quoteInto('i.product_id=?', $productId), + $this->_getReadAdapter()->quoteInto('i.store_id=?', $storeId), + $this->_getReadAdapter()->quoteInto('i.category_id=?', $catId), + )); + + $select->orWhere($cond); + } -// protected $_rewrite = array(); -// protected $_catRoots = array(); -// -// public function addCategoryToRewrite($category) -// { -// $a = array('refresh'=>true); -// if (is_object($category)) { -// $a['path'] = $category->getPath(); -// $this->_rewrite[0]['category'][$category->getId()] = $a; -// } elseif (is_numeric($category)) { -// $this->_rewrite[0]['category'][$category] = $a; -// } -// return $this; -// } -// -// public function addProductToRewrite($product) -// { -// $a = array('refresh'=>true); -// if (is_object($product)) { -// $this->_rewrite[0]['product'][$product->getId()] = $a; -// } else { -// $this->_rewrite[0]['product'][$product] = $a; -// } -// return $this; -// } -// -// protected function _getCategoryRootsByStore() -// { -// if (!$this->_catRoots) { -// $res = Mage::getSingleton('core/resource'); -// /* @var $res Mage_Core_Model_Resource */ -// $read = $res->getConnection('core_read'); -// /* @var $read Zend_Db_Adapter_Abstract */ -// $select = $read->select()->from(array( -// 's' => $res->getTableName('core/store'), -// 'g' => $res->getTableName('core/store_group'), -// 'c' => $res->getTableName('catalog/category'), -// ), array('s.store_id', 'g.category_root_id'=>'category_id', 'c.path')) -// ->where('s.group_id=g.group_id and c.entity_id=g.category_root_id'); -// $categories = $read->fetchAll($select); -// $this->_catRoots = array(); -// foreach ($categories as $c) { -// $this->_catRoots[$c['store_id']] = $c; -// } -// } -// return $this->_catRoots; -// } -// -// protected function _loadCategories() -// { -// if (empty($this->_rewrite[0]['category'])) { -// return; -// } -// $res = Mage::getSingleton('core/resource'); -// /* @var $res Mage_Core_Model_Resource */ -// $read = $res->getConnection('core_read'); -// /* @var $read Zend_Db_Adapter_Abstract */ -// -// // first load categories that don't have path -// $req1 = array(); -// foreach ($this->_rewrite[0]['category'] as $cId=>$rData) { -// if (empty($rData['path'])) { -// $req1[] = $cId; -// } -// } -// $select = $read->select()->from(array( -// 'c' => $res->getTableName('catalog/category'), -// 'url_key' => $res->getTableName('catalog/category').'_varchar', -// 'url_path' => $res->getTableName('catalog/category').'_varchar', -// ), array('c.entity_id'=>'category_id', 'c.path', 'url_path.value'=>'url_path')) -// // now load all required categories (children) -// $req2 = array(); -// foreach ($this->_rewrite[0]['category'] as $cId=>$rData) { -// $req2[] = "path like ''"; -// foreach ($this->_getCategoryRootsByStore() as $storeId=>$c) { -// $this->_rewrite[$storeId]['category'] -// } -// } -// $collection = Mage::getModel('catalog/category')->getCollection() -// ->; -// } -// -// protected function _loadProducts() -// { -// if (empty($this->_rewrite[0]['product'])) { -// return; -// } -// } -// -// public function commitRewrites() -// { -// $this->_loadCategories(); -// $this->_loadProducts(); -// -// } -} \ No newline at end of file + $query = $this->_getReadAdapter()->query($select); + while ($row = $query->fetch()) { + $result[$row['product_id']] = array( + 'store_id' => $row['store_id'], + 'visibility' => $row['visibility'], + 'url_rewrite' => $row['request_path'], + ); + } + + return $result; + } +} diff --git a/app/code/core/Mage/Catalog/etc/config.xml b/app/code/core/Mage/Catalog/etc/config.xml index bfdfaa9a0d..ca298ca945 100644 --- a/app/code/core/Mage/Catalog/etc/config.xml +++ b/app/code/core/Mage/Catalog/etc/config.xml @@ -28,7 +28,7 @@ - 0.7.69 + 0.7.72 @@ -130,7 +130,7 @@ 11 1 - 1 + 11 111 1 @@ -419,15 +419,6 @@ - - - - singleton - catalog/product_flat_observer - catalogCategoryChangeProducts - - - @@ -586,7 +577,7 @@ - Url Rewrite Management + URL Rewrite Management adminhtml/urlrewrite/index diff --git a/app/code/core/Mage/Catalog/etc/system.xml b/app/code/core/Mage/Catalog/etc/system.xml index c3fdff57b7..18b44818ca 100644 --- a/app/code/core/Mage/Catalog/etc/system.xml +++ b/app/code/core/Mage/Catalog/etc/system.xml @@ -352,7 +352,16 @@ 1 1 1 + Example format 200x300 + + + text + 150 + 1 + 1 + 1 + image @@ -363,6 +372,7 @@ 1 1 1 + Allowed file types (jpeg, gif, png). diff --git a/app/code/core/Mage/Catalog/sql/catalog_setup/mysql4-upgrade-0.7.39-0.7.40.php b/app/code/core/Mage/Catalog/sql/catalog_setup/mysql4-upgrade-0.7.39-0.7.40.php index 75642ad4cf..9c347e2441 100644 --- a/app/code/core/Mage/Catalog/sql/catalog_setup/mysql4-upgrade-0.7.39-0.7.40.php +++ b/app/code/core/Mage/Catalog/sql/catalog_setup/mysql4-upgrade-0.7.39-0.7.40.php @@ -32,7 +32,7 @@ $fieldList = array('price','special_price','special_from_date','special_to_date', 'minimal_price','cost','tier_price'); foreach ($fieldList as $field) { - $applyTo = split(',', $installer->getAttribute('catalog_product', $field, 'apply_to')); + $applyTo = explode(',', $installer->getAttribute('catalog_product', $field, 'apply_to')); if (!in_array('virtual', $applyTo)) { $applyTo[] = 'virtual'; $installer->updateAttribute('catalog_product', $field, 'apply_to', join(',', $applyTo)); diff --git a/app/code/core/Mage/CatalogIndex/Model/Aggregation.php b/app/code/core/Mage/CatalogIndex/Model/Aggregation.php index b1a03b112b..4b04cc87d7 100644 --- a/app/code/core/Mage/CatalogIndex/Model/Aggregation.php +++ b/app/code/core/Mage/CatalogIndex/Model/Aggregation.php @@ -151,11 +151,11 @@ protected function _processTags($tags) { $newTags = array(); foreach ($tags as $tag) { - $tagInfo = split(':', $tag); + $tagInfo = explode(':', $tag); if (count($tagInfo)==1) { $newTags[] = $tagInfo[0]; } else { - $tagVariants = split('/', $tagInfo[1]); + $tagVariants = explode('/', $tagInfo[1]); foreach ($tagVariants as $tagVariant) { $newTags[] = $tagInfo[0] . $tagVariant; } diff --git a/app/code/core/Mage/CatalogIndex/etc/config.xml b/app/code/core/Mage/CatalogIndex/etc/config.xml index 82f496d2f9..3a1339b63c 100644 --- a/app/code/core/Mage/CatalogIndex/etc/config.xml +++ b/app/code/core/Mage/CatalogIndex/etc/config.xml @@ -220,26 +220,6 @@ - - - - - - - - - - - - - - - singleton - catalogindex/observer - processProductsWebsitesChange - - - @@ -277,6 +257,26 @@ + + + + + + + + + + + + + + singleton + catalogindex/observer + processProductsWebsitesChange + + + + diff --git a/app/code/core/Mage/CatalogInventory/Model/Stock.php b/app/code/core/Mage/CatalogInventory/Model/Stock.php index 0d3846d9b2..6b94098e69 100644 --- a/app/code/core/Mage/CatalogInventory/Model/Stock.php +++ b/app/code/core/Mage/CatalogInventory/Model/Stock.php @@ -71,13 +71,13 @@ public function addItemsToProducts($productCollection) ->addProductsFilter($productCollection) ->joinStockStatus($productCollection->getStoreId()) ->load(); + $stockItems = array(); foreach ($items as $item) { - foreach($productCollection as $product){ - if($product->getId()==$item->getProductId()){ - if($product instanceof Mage_Catalog_Model_Product) { - $item->assignProduct($product); - } - } + $stockItems[$item->getProductId()] = $item; + } + foreach ($productCollection as $product) { + if (isset($stockItems[$product->getId()])) { + $stockItems[$product->getId()]->assignProduct($product); } } return $this; diff --git a/app/code/core/Mage/CatalogInventory/etc/wsdl.xml b/app/code/core/Mage/CatalogInventory/etc/wsdl.xml index ee4559e55b..28fa870fa2 100644 --- a/app/code/core/Mage/CatalogInventory/etc/wsdl.xml +++ b/app/code/core/Mage/CatalogInventory/etc/wsdl.xml @@ -26,6 +26,22 @@ + + + + + + + + + + + + + + + + diff --git a/app/code/core/Mage/CatalogRule/Model/Rule.php b/app/code/core/Mage/CatalogRule/Model/Rule.php index b2f4a31bd4..3c13a6aa8a 100644 --- a/app/code/core/Mage/CatalogRule/Model/Rule.php +++ b/app/code/core/Mage/CatalogRule/Model/Rule.php @@ -162,14 +162,6 @@ public function getMatchingProductIds() public function callbackValidateProduct($args) { $product = $args['product']->setData($args['row']); - if (!empty($args['attributes']['category_ids'])) { - $categoryCollection = $product->getCategoryCollection()->load(); - $categories = array(); - foreach ($categoryCollection as $category) { - $categories[] = $category->getId(); - } - $product->setCategoryIds($categories); - } if ($this->getConditions()->validate($product)) { $this->_productIds[] = $product->getId(); } diff --git a/app/code/core/Mage/CatalogRule/Model/Rule/Condition/Product.php b/app/code/core/Mage/CatalogRule/Model/Rule/Condition/Product.php index 2bf9bc91b7..ba3cad9bdd 100644 --- a/app/code/core/Mage/CatalogRule/Model/Rule/Condition/Product.php +++ b/app/code/core/Mage/CatalogRule/Model/Rule/Condition/Product.php @@ -193,9 +193,14 @@ public function getAttributeElement() */ public function collectValidatedAttributes($productCollection) { + if ($this->getAttribute() == 'category_ids') { + return $this; + } + $attributes = $this->getRule()->getCollectedAttributes(); $attributes[$this->getAttribute()] = true; $this->getRule()->setCollectedAttributes($attributes); + $productCollection->addAttributeToSelect($this->getAttribute(), 'left'); return $this; } @@ -342,6 +347,10 @@ public function loadArray($arr) */ public function validate(Varien_Object $object) { + if ($this->getAttribute() == 'category_ids') { + return $this->validateAttribute($object->getAvailableInCategories()); + } + $attr = $object->getResource()->getAttribute($this->getAttribute()); if ($attr && $attr->getBackendType()=='datetime' && !is_int($this->getValue())) { $this->setValue(strtotime($this->getValue())); @@ -349,16 +358,12 @@ public function validate(Varien_Object $object) return $this->validateAttribute($value); } - if ($this->getAttribute() == 'category_ids') { - return $this->validateAttribute($object->getAvailableInCategories()); - } - if ($attr && $attr->getFrontendInput() == 'multiselect') { $value = $object->getData($this->getAttribute()); if (!strlen($value)) { $value = array(); } else { - $value = split(',', $value); + $value = explode(',', $value); } return $this->validateAttribute($value); } diff --git a/app/code/core/Mage/CatalogRule/sql/catalogrule_setup/mysql4-upgrade-0.7.1-0.7.2.php b/app/code/core/Mage/CatalogRule/sql/catalogrule_setup/mysql4-upgrade-0.7.1-0.7.2.php index d9502f917a..7023e6f5b4 100644 --- a/app/code/core/Mage/CatalogRule/sql/catalogrule_setup/mysql4-upgrade-0.7.1-0.7.2.php +++ b/app/code/core/Mage/CatalogRule/sql/catalogrule_setup/mysql4-upgrade-0.7.1-0.7.2.php @@ -41,7 +41,7 @@ foreach ($rows as $r) { $websiteIds = array(); - foreach (split(',', $r['store_ids']) as $storeId) { + foreach (explode(',', $r['store_ids']) as $storeId) { if (($storeId!=='') && isset($websites[$storeId])) { $websiteIds[$websites[$storeId]] = true; } diff --git a/app/code/core/Mage/CatalogSearch/Block/Autocomplete.php b/app/code/core/Mage/CatalogSearch/Block/Autocomplete.php index 18ad6cc024..4f44f47fdd 100644 --- a/app/code/core/Mage/CatalogSearch/Block/Autocomplete.php +++ b/app/code/core/Mage/CatalogSearch/Block/Autocomplete.php @@ -68,8 +68,8 @@ protected function _toHtml() public function getSuggestData() { if (!$this->_suggestData) { - $collection = $this->helper('catalogSearch')->getSuggestCollection(); - $query = $this->helper('catalogSearch')->getQueryText(); + $collection = $this->helper('catalogsearch')->getSuggestCollection(); + $query = $this->helper('catalogsearch')->getQueryText(); $counter = 0; $data = array(); foreach ($collection as $item) { diff --git a/app/code/core/Mage/CatalogSearch/Block/Layer.php b/app/code/core/Mage/CatalogSearch/Block/Layer.php index a221f50713..3e550d873f 100644 --- a/app/code/core/Mage/CatalogSearch/Block/Layer.php +++ b/app/code/core/Mage/CatalogSearch/Block/Layer.php @@ -24,8 +24,22 @@ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ +/** + * Layered Navigation block for search + * + */ class Mage_CatalogSearch_Block_Layer extends Mage_Catalog_Block_Layer_View { + /** + * Get attribute filter block name + * + * @return string + */ + protected function _getAttributeFilterBlockName() + { + return 'catalogsearch/layer_filter_attribute'; + } + /** * Get layer object * diff --git a/app/code/core/Mage/CatalogSearch/Block/Result.php b/app/code/core/Mage/CatalogSearch/Block/Result.php index 9ca3315673..0ea80649a7 100644 --- a/app/code/core/Mage/CatalogSearch/Block/Result.php +++ b/app/code/core/Mage/CatalogSearch/Block/Result.php @@ -48,7 +48,7 @@ class Mage_CatalogSearch_Block_Result extends Mage_Core_Block_Template */ protected function _getQuery() { - return $this->helper('catalogSearch')->getQuery(); + return $this->helper('catalogsearch')->getQuery(); } /** @@ -58,7 +58,7 @@ protected function _getQuery() */ protected function _prepareLayout() { - $title = $this->__("Search results for: '%s'", $this->helper('catalogSearch')->getEscapedQueryText()); + $title = $this->__("Search results for: '%s'", $this->helper('catalogsearch')->getEscapedQueryText()); // add Home breadcrumb if ($breadcrumbs = $this->getLayout()->getBlock('breadcrumbs')) { @@ -180,8 +180,8 @@ public function getResultCount() */ public function getNoResultText() { - if (Mage::helper('catalogSearch')->isMinQueryLength()) { - return Mage::helper('catalogSearch')->__('Minimum Search query length is %s', $this->_getQuery()->getMinQueryLenght()); + if (Mage::helper('catalogsearch')->isMinQueryLength()) { + return Mage::helper('catalogsearch')->__('Minimum Search query length is %s', $this->_getQuery()->getMinQueryLenght()); } return $this->_getData('no_result_text'); } @@ -193,6 +193,6 @@ public function getNoResultText() */ public function getNoteMessages() { - return Mage::helper('catalogSearch')->getNoteMessages(); + return Mage::helper('catalogsearch')->getNoteMessages(); } } diff --git a/app/code/core/Mage/CatalogSearch/Model/Fulltext.php b/app/code/core/Mage/CatalogSearch/Model/Fulltext.php index 4afd2669f7..20fb78a91b 100644 --- a/app/code/core/Mage/CatalogSearch/Model/Fulltext.php +++ b/app/code/core/Mage/CatalogSearch/Model/Fulltext.php @@ -101,9 +101,9 @@ public function resetSearchResults() public function prepareResult($query = null) { if (!$query instanceof Mage_CatalogSearch_Model_Query) { - $query = Mage::helper('catalogSearch')->getQuery(); + $query = Mage::helper('catalogsearch')->getQuery(); } - $queryText = Mage::helper('catalogSearch')->getQueryText(); + $queryText = Mage::helper('catalogsearch')->getQueryText(); if ($query->getSynonimFor()) { $queryText = $query->getSynonimFor(); } diff --git a/app/code/core/Mage/CatalogSearch/Model/Layer.php b/app/code/core/Mage/CatalogSearch/Model/Layer.php index 710290b4d4..70aa2fbc1a 100644 --- a/app/code/core/Mage/CatalogSearch/Model/Layer.php +++ b/app/code/core/Mage/CatalogSearch/Model/Layer.php @@ -56,7 +56,7 @@ public function getProductCollection() public function prepareProductCollection($collection) { $collection->addAttributeToSelect(Mage::getSingleton('catalog/config')->getProductAttributes()) - ->addSearchFilter(Mage::helper('catalogSearch')->getEscapedQueryText()) + ->addSearchFilter(Mage::helper('catalogsearch')->getEscapedQueryText()) ->setStore(Mage::app()->getStore()) ->addMinimalPrice() ->addFinalPrice() @@ -77,7 +77,7 @@ public function prepareProductCollection($collection) public function getStateKey() { if ($this->_stateKey === null) { - $this->_stateKey = 'Q_'.Mage::helper('catalogSearch')->getQuery()->getId() + $this->_stateKey = 'Q_'.Mage::helper('catalogsearch')->getQuery()->getId() .'_'.parent::getStateKey(); } return $this->_stateKey; diff --git a/app/code/core/Mage/CatalogSearch/Model/Mysql4/Fulltext.php b/app/code/core/Mage/CatalogSearch/Model/Mysql4/Fulltext.php index a5f73b1891..cf2f9804ea 100644 --- a/app/code/core/Mage/CatalogSearch/Model/Mysql4/Fulltext.php +++ b/app/code/core/Mage/CatalogSearch/Model/Mysql4/Fulltext.php @@ -47,6 +47,13 @@ class Mage_CatalogSearch_Model_Mysql4_Fulltext extends Mage_Core_Model_Mysql4_Ab */ protected $_separator = ' '; + /** + * Array of Zend_Date objects per store + * + * @var array + */ + protected $_dates = array(); + /** * Product Type Instances cache * @@ -101,6 +108,8 @@ protected function _rebuildStoreIndex($storeId, $productIds = null) 'int' => array_keys($this->_getSearchableAttributes('int')), 'varchar' => array_keys($this->_getSearchableAttributes('varchar')), 'text' => array_keys($this->_getSearchableAttributes('text')), + 'decimal' => array_keys($this->_getSearchableAttributes('decimal')), + 'datetime' => array_keys($this->_getSearchableAttributes('datetime')), ); // status and visibility filter @@ -182,13 +191,13 @@ protected function _getSearchableProducts($storeId, array $staticFields, $produc $entityType = $this->getEavConfig()->getEntityType('catalog_product'); $store = Mage::app()->getStore($storeId); - $select = $this->_getReadAdapter()->select() + $select = $this->_getWriteAdapter()->select() ->from( array('e' => $this->getTable('catalog/product')), array_merge(array('entity_id', 'type_id'), $staticFields)) ->joinInner( array('website' => $this->getTable('catalog/product_website')), - $this->_getReadAdapter()->quoteInto('website.product_id=e.entity_id AND website.website_id=?', $store->getWebsiteId()), + $this->_getWriteAdapter()->quoteInto('website.product_id=e.entity_id AND website.website_id=?', $store->getWebsiteId()), array() ); @@ -199,8 +208,7 @@ protected function _getSearchableProducts($storeId, array $staticFields, $produc $select->where('e.entity_id>?', $lastProductId) ->limit($limit) ->order('e.entity_id'); - - return $this->_getReadAdapter()->fetchAll($select); + return $this->_getWriteAdapter()->fetchAll($select); } /** @@ -337,15 +345,15 @@ protected function _getSearchableAttributes($backendType = null) $entity = $entityType->getEntity(); $whereCond = array( - $this->_getReadAdapter()->quoteInto('is_searchable=?', 1), - $this->_getReadAdapter()->quoteInto('attribute_code IN(?)', array('status', 'visibility')) + $this->_getWriteAdapter()->quoteInto('is_searchable=?', 1), + $this->_getWriteAdapter()->quoteInto('attribute_code IN(?)', array('status', 'visibility')) ); - $select = $this->_getReadAdapter()->select() + $select = $this->_getWriteAdapter()->select() ->from($this->getTable('eav/attribute')) ->where('entity_type_id=?', $entityType->getEntityTypeId()) ->where(join(' OR ', $whereCond)); - $attributesData = $this->_getReadAdapter()->fetchAll($select); + $attributesData = $this->_getWriteAdapter()->fetchAll($select); $this->getEavConfig()->importAttributesData($entityType, $attributesData); foreach ($attributesData as $attributeData) { $attributeCode = $attributeData['attribute_code']; @@ -407,13 +415,13 @@ protected function _getProductAttributes($storeId, array $productIds, array $atr foreach ($atributeTypes as $backendType => $attributeIds) { if ($attributeIds) { $tableName = $this->getTable('catalog/product') . '_' . $backendType; - $selects[] = $this->_getReadAdapter()->select() + $selects[] = $this->_getWriteAdapter()->select() ->from( array('t_default' => $tableName), array('entity_id', 'attribute_id')) ->joinLeft( array('t_store' => $tableName), - $this->_getReadAdapter()->quoteInto("t_default.entity_id=t_store.entity_id AND t_default.attribute_id=t_store.attribute_id AND t_store.store_id=?", $storeId), + $this->_getWriteAdapter()->quoteInto("t_default.entity_id=t_store.entity_id AND t_default.attribute_id=t_store.attribute_id AND t_store.store_id=?", $storeId), array('value'=>'IFNULL(t_store.value, t_default.value)')) ->where('t_default.store_id=?', 0) ->where('t_default.attribute_id IN(?)', $attributeIds) @@ -423,7 +431,7 @@ protected function _getProductAttributes($storeId, array $productIds, array $atr if ($selects) { $select = '('.join(')UNION(', $selects).')'; - $query = $this->_getReadAdapter()->query($select); + $query = $this->_getWriteAdapter()->query($select); while ($row = $query->fetch()) { $result[$row['entity_id']][$row['attribute_id']] = $row['value']; } @@ -545,6 +553,12 @@ protected function _getAttributeValue($attributeId, $value, $storeId) $attribute->setStoreId($storeId); $value = $attribute->getSource()->getOptionText($value); } + if ($attribute->getBackendType() == 'datetime') { + $value = $this->_getStoreDate($storeId, $value); + } + if ($attribute->getFrontend()->getInputType() == 'price') { + $value = Mage::app()->getStore($storeId)->roundPrice($value); + } if (is_array($value)) { $value = implode($this->_separator, $value); @@ -599,4 +613,31 @@ protected function _saveProductIndexes($storeId, $productIndexes) return $this; } + + /** + * Retrieve Date value for store + * + * @param int $storeId + * @param string $date + * @return string + */ + protected function _getStoreDate($storeId, $date = null) + { + if (!isset($this->_dates[$storeId])) { + $timezone = Mage::getStoreConfig(Mage_Core_Model_Locale::XML_PATH_DEFAULT_TIMEZONE, $storeId); + $locale = Mage::getStoreConfig(Mage_Core_Model_Locale::XML_PATH_DEFAULT_LOCALE, $storeId); + $locale = new Zend_Locale($locale); + + $dateObj = new Zend_Date(null, null, $locale); + $dateObj->setTimezone($timezone); + $this->_dates[$storeId] = array($dateObj, $locale->getTranslation(null, 'date', $locale)); + } + + if (!is_empty_date($date)) { + list($dateObj, $format) = $this->_dates[$storeId]; + $dateObj->setDate($date, Varien_Date::DATETIME_INTERNAL_FORMAT); + return $dateObj->toString($format); + } + return null; + } } diff --git a/app/code/core/Mage/CatalogSearch/Model/Mysql4/Fulltext/Collection.php b/app/code/core/Mage/CatalogSearch/Model/Mysql4/Fulltext/Collection.php index 9e573ea05b..fee9c62628 100644 --- a/app/code/core/Mage/CatalogSearch/Model/Mysql4/Fulltext/Collection.php +++ b/app/code/core/Mage/CatalogSearch/Model/Mysql4/Fulltext/Collection.php @@ -35,7 +35,7 @@ class Mage_CatalogSearch_Model_Mysql4_Fulltext_Collection */ protected function _getQuery() { - return Mage::helper('catalogSearch')->getQuery(); + return Mage::helper('catalogsearch')->getQuery(); } /** diff --git a/app/code/core/Mage/CatalogSearch/controllers/ResultController.php b/app/code/core/Mage/CatalogSearch/controllers/ResultController.php index 647d07851e..0a0f50d0da 100644 --- a/app/code/core/Mage/CatalogSearch/controllers/ResultController.php +++ b/app/code/core/Mage/CatalogSearch/controllers/ResultController.php @@ -43,13 +43,13 @@ protected function _getSession() */ public function indexAction() { - $query = Mage::helper('catalogSearch')->getQuery(); + $query = Mage::helper('catalogsearch')->getQuery(); /* @var $query Mage_CatalogSearch_Model_Query */ $query->setStoreId(Mage::app()->getStore()->getId()); if ($query->getQueryText()) { - if (Mage::helper('catalogSearch')->isMinQueryLength()) { + if (Mage::helper('catalogsearch')->isMinQueryLength()) { $query->setId(0) ->setIsActive(1) ->setIsProcessed(1); @@ -72,14 +72,14 @@ public function indexAction() } } - Mage::helper('catalogSearch')->checkNotes(); + Mage::helper('catalogsearch')->checkNotes(); $this->loadLayout(); $this->_initLayoutMessages('catalog/session'); $this->_initLayoutMessages('checkout/session'); $this->renderLayout(); - if (!Mage::helper('catalogSearch')->isMinQueryLength()) { + if (!Mage::helper('catalogsearch')->isMinQueryLength()) { $query->save(); } } diff --git a/app/code/core/Mage/Checkout/Block/Cart.php b/app/code/core/Mage/Checkout/Block/Cart.php index 8726a8456e..eac84b80ce 100644 --- a/app/code/core/Mage/Checkout/Block/Cart.php +++ b/app/code/core/Mage/Checkout/Block/Cart.php @@ -33,6 +33,49 @@ */ class Mage_Checkout_Block_Cart extends Mage_Checkout_Block_Cart_Abstract { + /** + * Prepare Quote Item Product URLs + * + */ + public function __construct() + { + parent::__construct(); + + // prepare cart items URLs + $products = array(); + /* @var $item Mage_Sales_Model_Quote_Item */ + foreach ($this->getItems() as $item) { + $product = $item->getProduct(); + $option = $item->getOptionByCode('product_type'); + if ($option) { + $product = $option->getProduct(); + } + + if ($item->getStoreId() != Mage::app()->getStore()->getId() + && !$item->getRedirectUrl() + && !$product->isVisibleInSiteVisibility()) + { + $products[$product->getId()] = $item->getStoreId(); + } + } + + if ($products) { + $products = Mage::getResourceSingleton('catalog/url') + ->getRewriteByProductStore($products); + foreach ($this->getItems() as $item) { + $product = $item->getProduct(); + $option = $item->getOptionByCode('product_type'); + if ($option) { + $product = $option->getProduct(); + } + + if (isset($products[$product->getId()])) { + $object = new Varien_Object($products[$product->getId()]); + $item->setUrlDataObject($object); + } + } + } + } public function chooseTemplate() { diff --git a/app/code/core/Mage/Checkout/Block/Cart/Item/Renderer.php b/app/code/core/Mage/Checkout/Block/Cart/Item/Renderer.php index 0743423c7c..74f3b3d025 100644 --- a/app/code/core/Mage/Checkout/Block/Cart/Item/Renderer.php +++ b/app/code/core/Mage/Checkout/Block/Cart/Item/Renderer.php @@ -20,7 +20,7 @@ * * @category Mage * @package Mage_Checkout - * @copyright Copyright (c) 2008 Irubin Consulting Inc. DBA Varien (http://www.varien.com) + * @copyright Copyright (c) 2009 Irubin Consulting Inc. DBA Varien (http://www.varien.com) * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ @@ -95,7 +95,39 @@ public function overrideProductUrl($productUrl) } /** - * Get url to item product + * Check Product has URL + * + * @return this + */ + public function hasProductUrl() + { + if ($this->_productUrl || $this->getItem()->getRedirectUrl()) { + return true; + } + + $product = $this->getProduct(); + $option = $this->getItem()->getOptionByCode('product_type'); + if ($option) { + $product = $option->getProduct(); + } + + if ($product->isVisibleInSiteVisibility()) { + return true; + } + else { + if ($this->getItem()->hasUrlDataObject()) { + $data = $this->getItem()->getUrlDataObject(); + if (in_array($data->getVisibility(), $product->getVisibleInSiteVisibilities())) { + return true; + } + } + } + + return false; + } + + /** + * Retrieve URL to item Product * * @return string */ @@ -104,7 +136,17 @@ public function getProductUrl() if (!is_null($this->_productUrl)) { return $this->_productUrl; } - return $this->getProduct()->getProductUrl(); + if ($this->getItem()->getRedirectUrl()) { + return $this->getItem()->getRedirectUrl(); + } + + $product = $this->getProduct(); + $option = $this->getItem()->getOptionByCode('product_type'); + if ($option) { + $product = $option->getProduct(); + } + + return $product->getUrlModel()->getUrl($product); } /** diff --git a/app/code/core/Mage/Checkout/Block/Cart/Item/Renderer/Configurable.php b/app/code/core/Mage/Checkout/Block/Cart/Item/Renderer/Configurable.php index ce4d45b6a8..95f49e7008 100644 --- a/app/code/core/Mage/Checkout/Block/Cart/Item/Renderer/Configurable.php +++ b/app/code/core/Mage/Checkout/Block/Cart/Item/Renderer/Configurable.php @@ -1,124 +1,114 @@ - - */ -class Mage_Checkout_Block_Cart_Item_Renderer_Configurable extends Mage_Checkout_Block_Cart_Item_Renderer -{ - const CONFIGURABLE_PRODUCT_IMAGE= 'checkout/cart/configurable_product_image'; - const USE_PARENT_IMAGE = 'parent'; - - /** - * Get item configurable product - * - * @return Mage_Catalog_Model_Product - */ - public function getConfigurableProduct() - { - if ($option = $this->getItem()->getOptionByCode('product_type')) { - return $option->getProduct(); - } - return $this->getProduct(); - } - - /** - * Get item configurable child product - * - * @return Mage_Catalog_Model_Product - */ - public function getChildProduct() - { - if ($option = $this->getItem()->getOptionByCode('simple_product')) { - return $option->getProduct(); - } - return $this->getProduct(); - } - - /** - * Get product thumbnail image - * - * @return Mage_Catalog_Model_Product_Image - */ - public function getProductThumbnail() - { - $product = $this->getChildProduct(); - if (!$product || !$product->getData('thumbnail') - || ($product->getData('thumbnail') == 'no_selection') - || (Mage::getStoreConfig(self::CONFIGURABLE_PRODUCT_IMAGE) == self::USE_PARENT_IMAGE)) { - $product = $this->getProduct(); - } - return $this->helper('catalog/image')->init($product, 'thumbnail'); - } - - /** - * Get item product name - * - * @return string - */ - public function getProductName() - { - return $this->getProduct()->getName(); - } - - /** - * Get url to item product - * - * @return string - */ - public function getProductUrl() - { - return $this->getProduct()->getProductUrl(); - } - - /** - * Get selected for configurable product attributes - * - * @return array - */ - public function getProductAttributes() - { - $attributes = $this->getProduct()->getTypeInstance(true) - ->getSelectedAttributesInfo($this->getProduct()); - return $attributes; - } - - /** - * Get list of all otions for product - * - * @return array - */ - public function getOptionList() - { - $options = array_merge($this->getProductAttributes(), $this->getProductOptions()); - return $options; - } - + + */ +class Mage_Checkout_Block_Cart_Item_Renderer_Configurable extends Mage_Checkout_Block_Cart_Item_Renderer +{ + const CONFIGURABLE_PRODUCT_IMAGE= 'checkout/cart/configurable_product_image'; + const USE_PARENT_IMAGE = 'parent'; + + /** + * Get item configurable product + * + * @return Mage_Catalog_Model_Product + */ + public function getConfigurableProduct() + { + if ($option = $this->getItem()->getOptionByCode('product_type')) { + return $option->getProduct(); + } + return $this->getProduct(); + } + + /** + * Get item configurable child product + * + * @return Mage_Catalog_Model_Product + */ + public function getChildProduct() + { + if ($option = $this->getItem()->getOptionByCode('simple_product')) { + return $option->getProduct(); + } + return $this->getProduct(); + } + + /** + * Get product thumbnail image + * + * @return Mage_Catalog_Model_Product_Image + */ + public function getProductThumbnail() + { + $product = $this->getChildProduct(); + if (!$product || !$product->getData('thumbnail') + || ($product->getData('thumbnail') == 'no_selection') + || (Mage::getStoreConfig(self::CONFIGURABLE_PRODUCT_IMAGE) == self::USE_PARENT_IMAGE)) { + $product = $this->getProduct(); + } + return $this->helper('catalog/image')->init($product, 'thumbnail'); + } + + /** + * Get item product name + * + * @return string + */ + public function getProductName() + { + return $this->getProduct()->getName(); + } + + /** + * Get selected for configurable product attributes + * + * @return array + */ + public function getProductAttributes() + { + $attributes = $this->getProduct()->getTypeInstance(true) + ->getSelectedAttributesInfo($this->getProduct()); + return $attributes; + } + + /** + * Get list of all otions for product + * + * @return array + */ + public function getOptionList() + { + $options = array_merge($this->getProductAttributes(), $this->getProductOptions()); + return $options; + } + } \ No newline at end of file diff --git a/app/code/core/Mage/Checkout/Block/Cart/Item/Renderer/Grouped.php b/app/code/core/Mage/Checkout/Block/Cart/Item/Renderer/Grouped.php index 89da4dc78f..84d866ba91 100644 --- a/app/code/core/Mage/Checkout/Block/Cart/Item/Renderer/Grouped.php +++ b/app/code/core/Mage/Checkout/Block/Cart/Item/Renderer/Grouped.php @@ -43,7 +43,8 @@ class Mage_Checkout_Block_Cart_Item_Renderer_Grouped extends Mage_Checkout_Block */ public function getGroupedProduct() { - if ($option = $this->getItem()->getOptionByCode('product_type')) { + $option = $this->getItem()->getOptionByCode('product_type'); + if ($option) { return $option->getProduct(); } return $this->getProduct(); @@ -65,16 +66,6 @@ public function getProductThumbnail() return $this->helper('catalog/image')->init($product, 'thumbnail'); } - /** - * Get url to item product - * - * @return string - */ - public function getProductUrl() - { - return $this->getGroupedProduct()->getProductUrl(); - } - /** * Prepare item html * @@ -86,12 +77,11 @@ protected function _toHtml() { $renderer = $this->getRenderedBlock()->getItemRenderer($this->getItem()->getRealProductType()); $renderer->setItem($this->getItem()); - $renderer->overrideProductUrl($this->getProductUrl()); +// $renderer->overrideProductUrl($this->getProductUrl()); $renderer->overrideProductThumbnail($this->getProductThumbnail()); $rendererHtml = $renderer->toHtml(); - $renderer->overrideProductUrl(null); +// $renderer->overrideProductUrl(null); $renderer->overrideProductThumbnail(null); return $rendererHtml; } - -} \ No newline at end of file +} diff --git a/app/code/core/Mage/Checkout/Block/Cart/Totals.php b/app/code/core/Mage/Checkout/Block/Cart/Totals.php index 8701f26673..17ea3f9341 100644 --- a/app/code/core/Mage/Checkout/Block/Cart/Totals.php +++ b/app/code/core/Mage/Checkout/Block/Cart/Totals.php @@ -28,7 +28,6 @@ class Mage_Checkout_Block_Cart_Totals extends Mage_Checkout_Block_Cart_Abstract { protected $_totalRenderers; protected $_defaultRenderer = 'checkout/total_default'; - protected $_totals = null; public function getTotals() @@ -47,16 +46,22 @@ public function setTotals($value) protected function _getTotalRenderer($code) { - if (!isset($this->_totalRenderers[$code])) { - $this->_totalRenderers[$code] = $this->_defaultRenderer; + $blockName = $code.'_total_renderer'; + $block = $this->getLayout()->getBlock($blockName); + if (!$block) { + $block = $this->_defaultRenderer; $config = Mage::getConfig()->getNode("global/sales/quote/totals/{$code}/renderer"); - if ($config) - $this->_totalRenderers[$code] = (string) $config; + if ($config) { + $block = (string) $config; + } - $this->_totalRenderers[$code] = $this->getLayout()->createBlock($this->_totalRenderers[$code], "{$code}_total_renderer"); + $block = $this->getLayout()->createBlock($block, $blockName); } - - return $this->_totalRenderers[$code]; + /** + * Transfer totals to renderer + */ + $block->setTotals($this->getTotals()); + return $block; } public function renderTotal($total, $area = null, $colspan = 1) @@ -72,18 +77,51 @@ public function renderTotal($total, $area = null, $colspan = 1) ->toHtml(); } + /** + * Render totals html for specific totals area (footer, body) + * + * @param null|string $area + * @param int $colspan + * @return string + */ public function renderTotals($area = null, $colspan = 1) { $html = ''; - foreach($this->getTotals() as $total) { if ($total->getArea() != $area && $area != -1) { continue; } - $html .= $this->renderTotal($total, $area, $colspan); } - return $html; } + + /** + * Check if we have display grand total in base currency + * + * @return bool + */ + public function needDisplayBaseGrandtotal() + { + $quote = $this->getQuote(); + if ($quote->getBaseCurrencyCode() != $quote->getQuoteCurrencyCode()) { + return true; + } + return false; + } + + /** + * Get formated in base currency base grand total value + * + * @return string + */ + public function displayBaseGrandtotal() + { + $firstTotal = reset($this->_totals); + if ($firstTotal) { + $total = $firstTotal->getAddress()->getBaseGrandTotal(); + return Mage::app()->getStore()->getBaseCurrency()->format($total, array(), true); + } + return '-'; + } } \ No newline at end of file diff --git a/app/code/core/Mage/Checkout/Block/Multishipping/Overview.php b/app/code/core/Mage/Checkout/Block/Multishipping/Overview.php index 356a922c8e..a9f7d23e5b 100644 --- a/app/code/core/Mage/Checkout/Block/Multishipping/Overview.php +++ b/app/code/core/Mage/Checkout/Block/Multishipping/Overview.php @@ -215,9 +215,13 @@ public function getBillinAddressTotals() } - public function renderTotals($totals) + public function renderTotals($totals, $colspan=null) { - $colspan = $this->helper('tax')->displayCartBothPrices() ? 5 : 3; - return $this->getChild('totals')->setTotals($totals)->renderTotals(-1, $colspan); + if ($colspan === null) { + $colspan = $this->helper('tax')->displayCartBothPrices() ? 5 : 3; + } + $totals = $this->getChild('totals')->setTotals($totals)->renderTotals('', $colspan) + . $this->getChild('totals')->setTotals($totals)->renderTotals('footer', $colspan); + return $totals; } } diff --git a/app/code/core/Mage/Checkout/Block/Onepage/Login.php b/app/code/core/Mage/Checkout/Block/Onepage/Login.php index aed6b91516..8879de82b7 100644 --- a/app/code/core/Mage/Checkout/Block/Onepage/Login.php +++ b/app/code/core/Mage/Checkout/Block/Onepage/Login.php @@ -37,7 +37,7 @@ class Mage_Checkout_Block_Onepage_Login extends Mage_Checkout_Block_Onepage_Abst protected function _construct() { if (!$this->isCustomerLoggedIn()) { - $this->getCheckout()->setStepData('login', array('label'=>Mage::helper('checkout')->__('Checkout method'), 'allow'=>true)); + $this->getCheckout()->setStepData('login', array('label'=>Mage::helper('checkout')->__('Checkout Method'), 'allow'=>true)); } parent::_construct(); } @@ -64,12 +64,12 @@ public function getMethodData() public function getSuccessUrl() { - return $this->getUrl('*/*'); + return $this->getUrl('*/*'); } public function getErrorUrl() { - return $this->getUrl('*/*'); + return $this->getUrl('*/*'); } /** diff --git a/app/code/core/Mage/Checkout/Block/Total/Default.php b/app/code/core/Mage/Checkout/Block/Total/Default.php index fc72d89e79..14a1fa9b65 100644 --- a/app/code/core/Mage/Checkout/Block/Total/Default.php +++ b/app/code/core/Mage/Checkout/Block/Total/Default.php @@ -30,11 +30,38 @@ * * @author Magento Core Team */ -class Mage_Checkout_Block_Total_Default extends Mage_Core_Block_Template +class Mage_Checkout_Block_Total_Default extends Mage_Checkout_Block_Cart_Totals { protected $_template = 'checkout/total/default.phtml'; + protected $_store; - protected function _construct(){ + protected function _construct() + { $this->setTemplate($this->_template); + $this->_store = Mage::app()->getStore(); + } + + /** + * Get style assigned to total object + * + * @return string + */ + public function getStyle() + { + return $this->getTotal()->getStyle(); + } + + public function setTotal($total) + { + $this->setData('total', $total); + if ($total->getAddress()) { + $this->_store = $total->getAddress()->getQuote()->getStore(); + } + return $this; + } + + public function getStore() + { + return $this->_store; } } \ No newline at end of file diff --git a/app/code/core/Mage/Checkout/Helper/Cart.php b/app/code/core/Mage/Checkout/Helper/Cart.php index 66ef01c79a..da51cbc50f 100644 --- a/app/code/core/Mage/Checkout/Helper/Cart.php +++ b/app/code/core/Mage/Checkout/Helper/Cart.php @@ -49,42 +49,29 @@ public function getCart() */ public function getAddUrl($product, $additional = array()) { - /** - * Identify continue shopping url - */ -// if ($currentProduct = Mage::registry('current_product')) { -// /** -// * go to product view page -// */ -// $continueShoppingUrl = $currentProduct->getProductUrl(); -// } elseif ($currentCategory = Mage::registry('current_category')) { -// /** -// * go to category view page -// */ -// -// $continueShoppingUrl = $currentCategory->getUrl().(count($this->_getRequest()->getQuery())!=0?'?'.http_build_qu//ery($this->_getRequest()->getQuery(), '', '&'):''); -// -// } else { -// $continueShoppingUrl = $this->_getUrl('*/*/*', array('_current'=>true)); -// } + $continueUrl = Mage::helper('core')->urlEncode($this->getCurrentUrl()); + $urlParamName = Mage_Core_Controller_Front_Action::PARAM_NAME_URL_ENCODED; - $continueShoppingUrl = $this->getCurrentUrl(); - - $params = array( - Mage_Core_Controller_Front_Action::PARAM_NAME_URL_ENCODED => Mage::helper('core')->urlEncode($continueShoppingUrl), - 'product' => $product->getId() + $routeParams = array( + $urlParamName => $continueUrl, + 'product' => $product->getEntityId() ); - if ($this->_getRequest()->getRouteName() == 'checkout' - && $this->_getRequest()->getControllerName() == 'cart') { - $params['in_cart'] = 1; + if (!empty($additional)) { + $routeParams = array_merge($routeParams, $additional); } - if (count($additional)){ - $params = array_merge($params, $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', $params); + return $this->_getUrl('checkout/cart/add', $routeParams); } /** diff --git a/app/code/core/Mage/Checkout/Helper/Data.php b/app/code/core/Mage/Checkout/Helper/Data.php index 842b446556..e346048825 100644 --- a/app/code/core/Mage/Checkout/Helper/Data.php +++ b/app/code/core/Mage/Checkout/Helper/Data.php @@ -93,43 +93,40 @@ public function canOnepageCheckout() return true; } + /** + * Get sales item (quote item, order item etc) price including tax based on row total and tax amount + * + * @param Varien_Object $item + * @return float + */ public function getPriceInclTax($item) { - //$price = ($item->getCalculationPrice() ? $item->getCalculationPrice() : $item->getPrice()); + if ($item->getPriceInclTax()) { + return $item->getPriceInclTax(); + } $qty = ($item->getQty() ? $item->getQty() : ($item->getQtyOrdered() ? $item->getQtyOrdered() : 1)); - //$tax = ($item->getTaxBeforeDiscount() ? $item->getTaxBeforeDiscount() : $item->getTaxAmount()); - //$price = Mage::app()->getStore()->roundPrice($price+($tax/$qty)); $price = Mage::app()->getStore()->roundPrice(($item->getRowTotal()+$item->getTaxAmount())/$qty); return $price; } + /** + * Get sales item (quote item, order item etc) row total price including tax + * + * @param Varien_Object $item + * @return float + */ public function getSubtotalInclTax($item) { - if ($item instanceof Mage_Sales_Model_Order_Item) { - $store = $item->getOrder()->getStore(); - } elseif($item instanceof Mage_Sales_Model_Order_Invoice_Item) { - $store = $item->getInvoice()->getOrder()->getStore(); - } elseif($item instanceof Mage_Sales_Model_Order_Shipment_Item) { - $store = $item->getShipment()->getOrder()->getStore(); - } elseif($item instanceof Mage_Sales_Model_Order_Creditmemo_Item) { - $store = $item->getCreditmemo()->getOrder()->getStore(); - } else { - $store = $item->getQuote()->getStore(); - } - if (!Mage::helper('tax')->applyTaxAfterDiscount($store) and $item->getTaxBeforeDiscount()) { - $tax = $item->getTaxBeforeDiscount(); - } else { - $tax = $item->getTaxAmount(); + if ($item->getRowTotalInclTax()) { + return $item->getRowTotalInclTax(); } + $tax = $item->getTaxAmount(); return $item->getRowTotal() + $tax; } public function getBasePriceInclTax($item) { - //$price = ($item->getCalculationPrice() ? $item->getCalculationPrice() : $item->getPrice()); $qty = ($item->getQty() ? $item->getQty() : ($item->getQtyOrdered() ? $item->getQtyOrdered() : 1)); - //$tax = ($item->getTaxBeforeDiscount() ? $item->getTaxBeforeDiscount() : $item->getTaxAmount()); - //$price = Mage::app()->getStore()->roundPrice($price+($tax/$qty)); $price = Mage::app()->getStore()->roundPrice(($item->getBaseRowTotal()+$item->getBaseTaxAmount())/$qty); return $price; } diff --git a/app/code/core/Mage/Checkout/Model/Type/Multishipping.php b/app/code/core/Mage/Checkout/Model/Type/Multishipping.php index 3702040a1b..5f51e06c1f 100644 --- a/app/code/core/Mage/Checkout/Model/Type/Multishipping.php +++ b/app/code/core/Mage/Checkout/Model/Type/Multishipping.php @@ -307,8 +307,8 @@ public function setPaymentMethod($payment) Mage::throwException(Mage::helper('checkout')->__('Payment method is not defined')); } $this->getQuote()->getPayment() - ->importData($payment) - ->save(); + ->importData($payment); + $this->getQuote()->save(); return $this; } diff --git a/app/code/core/Mage/Checkout/Model/Type/Onepage.php b/app/code/core/Mage/Checkout/Model/Type/Onepage.php index c6a215b5d7..f0f356ee3d 100644 --- a/app/code/core/Mage/Checkout/Model/Type/Onepage.php +++ b/app/code/core/Mage/Checkout/Model/Type/Onepage.php @@ -353,7 +353,7 @@ public function savePayment($data) $payment->importData($data); $this->getQuote()->getShippingAddress()->setPaymentMethod($payment->getMethod()); - $this->getQuote()->collectTotals()->save(); + $this->getQuote()->save(); $this->getCheckout() ->setStepData('payment', 'complete', true) diff --git a/app/code/core/Mage/Checkout/controllers/OnepageController.php b/app/code/core/Mage/Checkout/controllers/OnepageController.php index b5f9a73faa..8d79e23af8 100644 --- a/app/code/core/Mage/Checkout/controllers/OnepageController.php +++ b/app/code/core/Mage/Checkout/controllers/OnepageController.php @@ -56,21 +56,27 @@ protected function _ajaxRedirectResponse() return $this; } + /** + * Validate ajax request and redirect on failure + * + * @return bool + */ protected function _expireAjax() { if (!$this->getOnepage()->getQuote()->hasItems() || $this->getOnepage()->getQuote()->getHasError() || $this->getOnepage()->getQuote()->getIsMultiShipping()) { $this->_ajaxRedirectResponse(); - exit; + return true; } $action = $this->getRequest()->getActionName(); if (Mage::getSingleton('checkout/session')->getCartWasUpdated(true) && !in_array($action, array('index', 'progress'))) { $this->_ajaxRedirectResponse(); - exit; + return true; } - Mage::getSingleton('core/translate_inline')->setIsAjaxRequest(true); + + return false; } protected function _getShippingMethodsHtml() @@ -156,21 +162,27 @@ public function indexAction() */ public function progressAction() { - $this->_expireAjax(); + if ($this->_expireAjax()) { + return; + } $this->loadLayout(false); $this->renderLayout(); } public function shippingMethodAction() { - $this->_expireAjax(); + if ($this->_expireAjax()) { + return; + } $this->loadLayout(false); $this->renderLayout(); } public function reviewAction() { - $this->_expireAjax(); + if ($this->_expireAjax()) { + return; + } $this->loadLayout(false); $this->renderLayout(); } @@ -222,7 +234,9 @@ public function getAdditionalAction() */ public function getAddressAction() { - $this->_expireAjax(); + if ($this->_expireAjax()) { + return; + } $addressId = $this->getRequest()->getParam('address', false); if ($addressId) { $address = $this->getOnepage()->getAddress($addressId); @@ -233,11 +247,13 @@ public function getAddressAction() public function saveMethodAction() { - $this->_expireAjax(); + if ($this->_expireAjax()) { + return; + } if ($this->getRequest()->isPost()) { $method = $this->getRequest()->getPost('method'); $result = $this->getOnepage()->saveCheckoutMethod($method); - $this->getResponse()->setBody(Zend_Json::encode($result)); + $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result)); } } @@ -246,7 +262,9 @@ public function saveMethodAction() */ public function saveBillingAction() { - $this->_expireAjax(); + if ($this->_expireAjax()) { + return; + } if ($this->getRequest()->isPost()) { $data = $this->getRequest()->getPost('billing', array()); $customerAddressId = $this->getRequest()->getPost('billing_address_id', false); @@ -278,13 +296,15 @@ public function saveBillingAction() } } - $this->getResponse()->setBody(Zend_Json::encode($result)); + $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result)); } } public function saveShippingAction() { - $this->_expireAjax(); + if ($this->_expireAjax()) { + return; + } if ($this->getRequest()->isPost()) { $data = $this->getRequest()->getPost('shipping', array()); $customerAddressId = $this->getRequest()->getPost('shipping_address_id', false); @@ -302,13 +322,15 @@ public function saveShippingAction() // $result['shipping_methods_html'] = $this->getLayout()->getBlock('root')->toHtml(); // $result['shipping_methods_html'] = $this->_getShippingMethodsHtml(); - $this->getResponse()->setBody(Zend_Json::encode($result)); + $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result)); } } public function saveShippingMethodAction() { - $this->_expireAjax(); + if ($this->_expireAjax()) { + return; + } if ($this->getRequest()->isPost()) { $data = $this->getRequest()->getPost('shipping_method', ''); $result = $this->getOnepage()->saveShippingMethod($data); @@ -317,7 +339,7 @@ public function saveShippingMethodAction() */ if(!$result) { Mage::dispatchEvent('checkout_controller_onepage_save_shipping_method', array('request'=>$this->getRequest(), 'quote'=>$this->getOnepage()->getQuote())); - $this->getResponse()->setBody(Zend_Json::encode($result)); + $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result)); $result['goto_section'] = 'payment'; $result['update_section'] = array( @@ -327,56 +349,64 @@ public function saveShippingMethodAction() // $result['payment_methods_html'] = $this->_getPaymentMethodsHtml(); } - $this->getResponse()->setBody(Zend_Json::encode($result)); + $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result)); } } + /** + * Save payment ajax action + * + * Sets either redirect or a JSON response + */ public function savePaymentAction() { - $this->_expireAjax(); - if ($this->getRequest()->isPost()) { + if ($this->_expireAjax()) { + return; + } + try { + if (!$this->getRequest()->isPost()) { + $this->_ajaxRedirectResponse(); + return; + } + + // set payment to quote + $result = array(); $data = $this->getRequest()->getPost('payment', array()); - /* - * first to check payment information entered is correct or not - */ + $result = $this->getOnepage()->savePayment($data); - try { - $result = $this->getOnepage()->savePayment($data); - } - catch (Mage_Payment_Exception $e) { - if ($e->getFields()) { - $result['fields'] = $e->getFields(); - } - $result['error'] = $e->getMessage(); - } - catch (Exception $e) { - $result['error'] = $e->getMessage(); - } + // get section and redirect data $redirectUrl = $this->getOnePage()->getQuote()->getPayment()->getCheckoutRedirectUrl(); if (empty($result['error']) && !$redirectUrl) { $this->loadLayout('checkout_onepage_review'); - $result['goto_section'] = 'review'; $result['update_section'] = array( 'name' => 'review', 'html' => $this->_getReviewHtml() ); - -// $result['review_html'] = $this->getLayout()->getBlock('root')->toHtml(); } - if ($redirectUrl) { $result['redirect'] = $redirectUrl; } - - $this->getResponse()->setBody(Zend_Json::encode($result)); + } catch (Mage_Payment_Exception $e) { + if ($e->getFields()) { + $result['fields'] = $e->getFields(); + } + $result['error'] = $e->getMessage(); + } catch (Mage_Core_Exception $e) { + $result['error'] = $e->getMessage(); + } catch (Exception $e) { + Mage::logException($e); + $result['error'] = $this->__('Unable to set Payment Method.'); } + $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result)); } public function saveOrderAction() { - $this->_expireAjax(); + if ($this->_expireAjax()) { + return; + } $result = array(); try { @@ -386,7 +416,7 @@ public function saveOrderAction() $result['success'] = false; $result['error'] = true; $result['error_messages'] = $this->__('Please agree to all Terms and Conditions before placing the order.'); - $this->getResponse()->setBody(Zend_Json::encode($result)); + $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result)); return; } } @@ -440,7 +470,7 @@ public function saveOrderAction() $result['redirect'] = $redirectUrl; } - $this->getResponse()->setBody(Zend_Json::encode($result)); + $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result)); } } diff --git a/app/code/core/Mage/Cms/Controller/Router.php b/app/code/core/Mage/Cms/Controller/Router.php index 595c7065ef..04a9b53fd5 100644 --- a/app/code/core/Mage/Cms/Controller/Router.php +++ b/app/code/core/Mage/Cms/Controller/Router.php @@ -18,22 +18,40 @@ * versions in the future. If you wish to customize Magento for your * needs please refer to http://www.magentocommerce.com for more information. * - * @category Mage - * @package Mage_Cms - * @copyright Copyright (c) 2008 Irubin Consulting Inc. DBA Varien (http://www.varien.com) - * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @category Mage + * @package Mage_Cms + * @copyright Copyright (c) 2009 Irubin Consulting Inc. DBA Varien (http://www.varien.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ + +/** + * Cms Controller Router + * + * @category Mage + * @package Mage_Cms + * @author Magento Core Team + */ class Mage_Cms_Controller_Router extends Mage_Core_Controller_Varien_Router_Abstract { + /** + * Initialize Controller Router + * + * @param Varien_Event_Observer $observer + */ public function initControllerRouters($observer) { $front = $observer->getEvent()->getFront(); - $cms = new Mage_Cms_Controller_Router(); - $front->addRouter('cms', $cms); + $front->addRouter('cms', $this); } + /** + * Validate and Match Cms Page and modify request + * + * @param Zend_Controller_Request_Http $request + * @return bool + */ public function match(Zend_Controller_Request_Http $request) { if (!Mage::isInstalled()) { @@ -45,20 +63,21 @@ public function match(Zend_Controller_Request_Http $request) $identifier = trim($request->getPathInfo(), '/'); - $page = Mage::getModel('cms/page'); + $page = Mage::getModel('cms/page'); $pageId = $page->checkIdentifier($identifier, Mage::app()->getStore()->getId()); if (!$pageId) { return false; } - $request->setModuleName(isset($d[0]) ? $d[0] : 'cms') - ->setControllerName(isset($d[1]) ? $d[1] : 'page') - ->setActionName(isset($d[2]) ? $d[2] : 'view') + $request->setModuleName('cms') + ->setControllerName('page') + ->setActionName('view') ->setParam('page_id', $pageId); - $request->setAlias( - Mage_Core_Model_Url_Rewrite::REWRITE_REQUEST_PATH_ALIAS, - $identifier - ); + $request->setAlias( + Mage_Core_Model_Url_Rewrite::REWRITE_REQUEST_PATH_ALIAS, + $identifier + ); + return true; } -} \ No newline at end of file +} diff --git a/app/code/core/Mage/Cms/Model/Page.php b/app/code/core/Mage/Cms/Model/Page.php index a0c1765246..3d5def7b47 100644 --- a/app/code/core/Mage/Cms/Model/Page.php +++ b/app/code/core/Mage/Cms/Model/Page.php @@ -18,32 +18,47 @@ * versions in the future. If you wish to customize Magento for your * needs please refer to http://www.magentocommerce.com for more information. * - * @category Mage - * @package Mage_Cms - * @copyright Copyright (c) 2008 Irubin Consulting Inc. DBA Varien (http://www.varien.com) - * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @category Mage + * @package Mage_Cms + * @copyright Copyright (c) 2009 Irubin Consulting Inc. DBA Varien (http://www.varien.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ + /** - * CMS page model + * Cms Page Model * - * @category Mage - * @package Mage_Cms + * @category Mage + * @package Mage_Cms * @author Magento Core Team */ - class Mage_Cms_Model_Page extends Mage_Core_Model_Abstract { - const NOROUTE_PAGE_ID = 'no-route'; + /** + * Prefix of model events names + * + * @var string + */ protected $_eventPrefix = 'cms_page'; + /** + * Initialize resource model + * + */ protected function _construct() { $this->_init('cms/page'); } + /** + * Load object data + * + * @param mixed $id + * @param string $field + * @return Mage_Cms_Model_Page + */ public function load($id, $field=null) { if (is_null($id)) { @@ -52,19 +67,23 @@ public function load($id, $field=null) return parent::load($id, $field); } + /** + * Load No-Route Page + * + * @return Mage_Cms_Model_Page + */ public function noRoutePage() { - $this->setData($this->load(self::NOROUTE_PAGE_ID, $this->getIdFieldName())); - return $this; + return $this->load(self::NOROUTE_PAGE_ID, $this->getIdFieldName()); } /** * Check if page identifier exist for specific store * return page id if page exists * - * @param string $identifier - * @param int $storeId - * @return int + * @param string $identifier + * @param int $storeId + * @return int */ public function checkIdentifier($identifier, $storeId) { diff --git a/app/code/core/Mage/Compiler/controllers/ProcessController.php b/app/code/core/Mage/Compiler/controllers/ProcessController.php index 480737aef9..073d2245b8 100644 --- a/app/code/core/Mage/Compiler/controllers/ProcessController.php +++ b/app/code/core/Mage/Compiler/controllers/ProcessController.php @@ -81,8 +81,11 @@ public function runAction() public function recompileAction() { - $this->_getCompiler()->clear(); + /** + * Add redirect heades before clear compiled sources + */ $this->_redirect('*/*/run'); + $this->_getCompiler()->clear(); } public function disableAction() diff --git a/app/code/core/Mage/Core/Block/Html/Calendar.php b/app/code/core/Mage/Core/Block/Html/Calendar.php index 265867fe85..5dfc225fec 100644 --- a/app/code/core/Mage/Core/Block/Html/Calendar.php +++ b/app/code/core/Mage/Core/Block/Html/Calendar.php @@ -41,32 +41,32 @@ protected function _toHtml() // get days names $days = Zend_Locale_Data::getList($localeCode, 'days'); $this->assign('days', array( - 'wide' => Zend_Json::encode(array_values($days['format']['wide'])), - 'abbreviated' => Zend_Json::encode(array_values($days['format']['abbreviated'])) + 'wide' => Mage::helper('core')->jsonEncode(array_values($days['format']['wide'])), + 'abbreviated' => Mage::helper('core')->jsonEncode(array_values($days['format']['abbreviated'])) )); // get months names $months = Zend_Locale_Data::getList($localeCode, 'months'); $this->assign('months', array( - 'wide' => Zend_Json::encode(array_values($months['format']['wide'])), - 'abbreviated' => Zend_Json::encode(array_values($months['format']['abbreviated'])) + 'wide' => Mage::helper('core')->jsonEncode(array_values($months['format']['wide'])), + 'abbreviated' => Mage::helper('core')->jsonEncode(array_values($months['format']['abbreviated'])) )); // get "today" and "week" words - $this->assign('today', Zend_Json::encode(Zend_Locale_Data::getContent($localeCode, 'relative', 0))); - $this->assign('week', Zend_Json::encode(Zend_Locale_Data::getContent($localeCode, 'field', 'week'))); + $this->assign('today', Mage::helper('core')->jsonEncode(Zend_Locale_Data::getContent($localeCode, 'relative', 0))); + $this->assign('week', Mage::helper('core')->jsonEncode(Zend_Locale_Data::getContent($localeCode, 'field', 'week'))); // get "am" & "pm" words - $this->assign('am', Zend_Json::encode(Zend_Locale_Data::getContent($localeCode, 'am'))); - $this->assign('pm', Zend_Json::encode(Zend_Locale_Data::getContent($localeCode, 'pm'))); + $this->assign('am', Mage::helper('core')->jsonEncode(Zend_Locale_Data::getContent($localeCode, 'am'))); + $this->assign('pm', Mage::helper('core')->jsonEncode(Zend_Locale_Data::getContent($localeCode, 'pm'))); // get first day of week and weekend days $this->assign('firstDay', (int)Mage::getStoreConfig('general/locale/firstday')); - $this->assign('weekendDays', Zend_Json::encode((string)Mage::getStoreConfig('general/locale/weekend'))); + $this->assign('weekendDays', Mage::helper('core')->jsonEncode((string)Mage::getStoreConfig('general/locale/weekend'))); // define default format and tooltip format - $this->assign('defaultFormat', Zend_Json::encode(Mage::app()->getLocale()->getDateStrFormat(Mage_Core_Model_Locale::FORMAT_TYPE_MEDIUM))); - $this->assign('toolTipFormat', Zend_Json::encode(Mage::app()->getLocale()->getDateStrFormat(Mage_Core_Model_Locale::FORMAT_TYPE_LONG))); + $this->assign('defaultFormat', Mage::helper('core')->jsonEncode(Mage::app()->getLocale()->getDateStrFormat(Mage_Core_Model_Locale::FORMAT_TYPE_MEDIUM))); + $this->assign('toolTipFormat', Mage::helper('core')->jsonEncode(Mage::app()->getLocale()->getDateStrFormat(Mage_Core_Model_Locale::FORMAT_TYPE_LONG))); // get days and months for en_US locale - calendar will parse exactly in this locale $days = Zend_Locale_Data::getList('en_US', 'days'); @@ -75,7 +75,7 @@ protected function _toHtml() $enUS->m = new stdClass(); $enUS->m->wide = array_values($months['format']['wide']); $enUS->m->abbr = array_values($months['format']['abbreviated']); - $this->assign('enUS', Zend_Json::encode($enUS)); + $this->assign('enUS', Mage::helper('core')->jsonEncode($enUS)); return parent::_toHtml(); } diff --git a/app/code/core/Mage/Core/Block/Messages.php b/app/code/core/Mage/Core/Block/Messages.php index 51657b7be0..732fd6020f 100644 --- a/app/code/core/Mage/Core/Block/Messages.php +++ b/app/code/core/Mage/Core/Block/Messages.php @@ -40,28 +40,11 @@ class Mage_Core_Block_Messages extends Mage_Core_Block_Template */ protected $_messages; - /** - * Flag which require message text escape - * - * @var bool - */ - protected $_escapeMessageFlag = false; - public function _prepareLayout() { $this->addMessages(Mage::getSingleton('core/session')->getMessages(true)); - parent::_prepareLayout(); - } - /** - * Set message escape flag - * @param bool $flag - * @return Mage_Core_Block_Messages - */ - public function setEscapeMessageFlag($flag) - { - $this->_escapeMessageFlag = $flag; - return $this; + parent::_prepareLayout(); } /** @@ -76,12 +59,6 @@ public function setMessages(Mage_Core_Model_Message_Collection $messages) return $this; } - /** - * Add messages to display - * - * @param Mage_Core_Model_Message_Collection $messages - * @return Mage_Core_Block_Messages - */ public function addMessages(Mage_Core_Model_Message_Collection $messages) { foreach ($messages->getItems() as $message) { @@ -184,9 +161,7 @@ public function getHtml($type=null) { $html = '
    '; foreach ($this->getMessages($type) as $message) { - $html.= '
  • ' - . ($this->_escapeMessageFlag) ? $this->htmlEscape($message->getText()) : $message->getText() - . '
  • '; + $html.= '
  • '.$message->getText().'
  • '; } $html .= '
'; return $html; @@ -217,7 +192,7 @@ public function getGroupedHtml() foreach ( $messages as $message ) { $html.= '
  • '; - $html.= ($this->_escapeMessageFlag) ? $this->htmlEscape($message->getText()) : $message->getText(); + $html.= $message->getText(); $html.= '
  • '; } $html .= ''; diff --git a/app/code/core/Mage/Core/Controller/Request/Http.php b/app/code/core/Mage/Core/Controller/Request/Http.php index 72f3e3e7ad..269151b7cf 100644 --- a/app/code/core/Mage/Core/Controller/Request/Http.php +++ b/app/code/core/Mage/Core/Controller/Request/Http.php @@ -271,7 +271,7 @@ public function getHttpHost($trimPort = true) return false; } if ($trimPort) { - $host = split(':', $_SERVER['HTTP_HOST']); + $host = explode(':', $_SERVER['HTTP_HOST']); return $host[0]; } return $_SERVER['HTTP_HOST']; diff --git a/app/code/core/Mage/Core/Controller/Varien/Action.php b/app/code/core/Mage/Core/Controller/Varien/Action.php index b8becf7573..e3ec66df0d 100644 --- a/app/code/core/Mage/Core/Controller/Varien/Action.php +++ b/app/code/core/Mage/Core/Controller/Varien/Action.php @@ -434,7 +434,9 @@ public function preDispatch() if (!$this->getFlag('', self::FLAG_NO_START_SESSION)) { $namespace = $this->getLayout()->getArea(); $checkCookie = in_array($this->getRequest()->getActionName(), $this->_cookieCheckActions); - if ($checkCookie && !Mage::getSingleton('core/cookie')->get($namespace)) { + $checkCookie = $checkCookie && !$this->getRequest()->getParam('nocookie', false); + $cookies = Mage::getSingleton('core/cookie')->get(); + if ($checkCookie && empty($cookies)) { $this->setFlag('', self::FLAG_NO_COOKIES_REDIRECT, true); } Mage::getSingleton('core/session', array('name' => $namespace))->start(); @@ -553,9 +555,6 @@ protected function _initLayoutMessages($messagesStorage) { if ($storage = Mage::getSingleton($messagesStorage)) { $this->getLayout()->getMessagesBlock()->addMessages($storage->getMessages(true)); - $this->getLayout()->getMessagesBlock()->setEscapeMessageFlag( - $storage->getEscapeMessages(true) - ); } else { Mage::throwException( diff --git a/app/code/core/Mage/Core/Controller/Varien/Front.php b/app/code/core/Mage/Core/Controller/Varien/Front.php index 54ecdf72af..6731ddc95d 100644 --- a/app/code/core/Mage/Core/Controller/Varien/Front.php +++ b/app/code/core/Mage/Core/Controller/Varien/Front.php @@ -108,6 +108,21 @@ public function getRouter($name) return false; } + /** + * Retrieve routers collection + * + * @return array + */ + public function getRouters() + { + return $this->_routers; + } + + /** + * Init Fron Controller + * + * @return Mage_Core_Controller_Varien_Front + */ public function init() { Mage::dispatchEvent('controller_front_init_before', array('front'=>$this)); @@ -117,14 +132,14 @@ public function init() Varien_Profiler::start('mage::app::init_front_controller::collect_routers'); foreach ($routersInfo as $routerCode => $routerInfo) { if (isset($routerInfo['disabled']) && $routerInfo['disabled']) { - continue; + continue; } if (isset($routerInfo['class'])) { - $router = new $routerInfo['class']; - if (isset($routerInfo['area'])) { - $router->collectRoutes($routerInfo['area'], $routerCode); - } - $this->addRouter($routerCode, $router); + $router = new $routerInfo['class']; + if (isset($routerInfo['area'])) { + $router->collectRoutes($routerInfo['area'], $routerCode); + } + $this->addRouter($routerCode, $router); } } Varien_Profiler::stop('mage::app::init_front_controller::collect_routers'); @@ -236,7 +251,7 @@ public function rewrite() $to = $this->_processRewriteUrl($to); $pathInfo = preg_replace($from, $to, $request->getPathInfo()); - + if (isset($rewrite->complete)) { $request->setPathInfo($pathInfo); } else { diff --git a/app/code/core/Mage/Core/Controller/Varien/Router/Standard.php b/app/code/core/Mage/Core/Controller/Varien/Router/Standard.php index 8ac8de684c..917dd09225 100644 --- a/app/code/core/Mage/Core/Controller/Varien/Router/Standard.php +++ b/app/code/core/Mage/Core/Controller/Varien/Router/Standard.php @@ -222,7 +222,7 @@ public function match(Zend_Controller_Request_Http $request) } // instantiate controller class - $controllerInstance = new $controllerClassName($request, $front->getResponse()); + $controllerInstance = Mage::getControllerInstance($request, $front->getResponse()); if (!$controllerInstance->hasAction($action)) { return false; diff --git a/app/code/core/Mage/Core/Helper/Abstract.php b/app/code/core/Mage/Core/Helper/Abstract.php index 18f5a704af..a64b2b76b9 100644 --- a/app/code/core/Mage/Core/Helper/Abstract.php +++ b/app/code/core/Mage/Core/Helper/Abstract.php @@ -128,6 +128,24 @@ protected function _getModuleName() return $this->_moduleName; } + /** + * Check whether or not the module output is enabled in Configuration + * TODO: add checking if module exists + * + * @param string $moduleName Full module name + * @return boolean + */ + public function isModuleOutputEnabled($moduleName = null) + { + if ($moduleName === null) { + $moduleName = $this->_getModuleName(); + } + if (Mage::getStoreConfigFlag('advanced/modules_disable_output/' . $moduleName)) { + return false; + } + return true; + } + /** * Translate * diff --git a/app/code/core/Mage/Core/Helper/Data.php b/app/code/core/Mage/Core/Helper/Data.php index 60945b8c35..8f2b56869f 100644 --- a/app/code/core/Mage/Core/Helper/Data.php +++ b/app/code/core/Mage/Core/Helper/Data.php @@ -554,4 +554,38 @@ public function xmlToAssoc(SimpleXMLElement $xml) } return $array; } -} \ No newline at end of file + + /** + * Encode the mixed $valueToEncode into the JSON format + * + * @param mixed $valueToEncode + * @param boolean $cycleCheck Optional; whether or not to check for object recursion; off by default + * @param array $options Additional options used during encoding + * @return string + */ + public function jsonEncode($valueToEncode, $cycleCheck = false, $options = array()) + { + $json = Zend_Json::encode($valueToEncode, $cycleCheck, $options); + /* @var $inline Mage_Core_Model_Translate_Inline */ + $inline = Mage::getSingleton('core/translate_inline'); + if ($inline->isAllowed()) { + $inline->setIsJson(true); + $inline->processResponseBody($json); + $inline->setIsJson(false); + } + + return $json; + } + + /** + * Decodes the given $encodedValue string which is + * encoded in the JSON format + * + * @param string $encodedValue + * @return mixed + */ + public function jsonDecode($encodedValue, $objectDecodeType = Zend_Json::TYPE_ARRAY) + { + return Zend_Json::decode($encodedValue, $objectDecodeType); + } +} diff --git a/app/code/core/Mage/Core/Helper/Js.php b/app/code/core/Mage/Core/Helper/Js.php index 9650c41d68..01253e18ad 100644 --- a/app/code/core/Mage/Core/Helper/Js.php +++ b/app/code/core/Mage/Core/Helper/Js.php @@ -45,7 +45,7 @@ class Mage_Core_Helper_Js extends Mage_Core_Helper_Abstract */ public function getTranslateJson() { - return Zend_Json::encode($this->_getTranslateData()); + return Mage::helper('core')->jsonEncode($this->_getTranslateData()); } /** @@ -174,16 +174,24 @@ protected function _getTranslateData() 'Your order can not be completed at this time as there is no payment methods available for it.' => $this->__('Your order can not be completed at this time as there is no payment methods available for it.'), 'Please specify payment method.' => $this->__('Please specify payment method.'), - + 'Credit card number doesn\'t match credit card type' => $this->__('Credit card number doesn\'t match credit card type'), + 'Card type doesn\'t match credit card number' => $this->__('Card type doesn\'t match credit card number'), + 'Please enter a valid credit card verification number.' => $this->__('Please enter a valid credit card verification number.'), + 'Please use only letters (a-z or A-Z), numbers (0-9) or underscore(_) in this field, first character should be a letter.' => + $this->__('Please use only letters (a-z or A-Z), numbers (0-9) or underscore(_) in this field, first character should be a letter.'), + 'Please input a valid CSS-length. For example 100px or 77pt or 20em or .5ex or 50%' => $this->__('Please input a valid CSS-length. For example 100px or 77pt or 20em or .5ex or 50%'), + 'Maximum length exceeded.' => $this->__('Maximum length exceeded.'), + + //Mage_Rule - + 'Your session has been expired, you will be relogged in now.' => $this->__('Your session has been expired, you will be relogged in now.'), 'Incorrect credit card expiration date' => $this->__('Incorrect credit card expiration date'), ); foreach ($this->_translateData as $key=>$value) { if ($key == $value) { unset($this->_translateData[$key]); - } + } } } return $this->_translateData; diff --git a/app/code/core/Mage/Core/Model/App.php b/app/code/core/Mage/Core/Model/App.php index eb9b35c0de..a4f9c4004e 100644 --- a/app/code/core/Mage/Core/Model/App.php +++ b/app/code/core/Mage/Core/Model/App.php @@ -135,13 +135,6 @@ class Mage_Core_Model_App */ protected $_cache; - /** - * Helpers array - * - * @var array - */ - protected $_helpers = array(); - /** * Use Cache * @@ -843,19 +836,12 @@ public function getTranslator() /** * Retrieve helper object * - * @param helper name $name - * @return Mage_Core_Helper_Abstract + * @param string $name + * @return Mage_Core_Helper_Abstract */ public function getHelper($name) { - if (strpos($name, '/') === false) { - $name .= '/data'; - } - if (!isset($this->_helpers[$name])) { - $class = Mage::getConfig()->getHelperClassName($name); - $this->_helpers[$name] = new $class(); - } - return $this->_helpers[$name]; + return Mage::helper($name); } /** diff --git a/app/code/core/Mage/Core/Model/Email/Template/Filter.php b/app/code/core/Mage/Core/Model/Email/Template/Filter.php index 3618caa056..952a929856 100644 --- a/app/code/core/Mage/Core/Model/Email/Template/Filter.php +++ b/app/code/core/Mage/Core/Model/Email/Template/Filter.php @@ -169,10 +169,18 @@ public function layoutDirective($construction) } $block->setDataUsingMethod($k, $v); - $layout->addOutputBlock($blockName); } } + /** + * Add output method for first block + */ + $allBlocks = $layout->getAllBlocks(); + $firstBlock = reset($allBlocks); + if ($firstBlock) { + $layout->addOutputBlock($firstBlock->getNameInLayout()); + } + $layout->setDirectOutput(false); return $layout->getOutput(); } @@ -373,4 +381,38 @@ public function modifierEscape($value, $type = 'html') } return $value; } + + /** + * HTTP Protocol directive + * + * Using: + * {{protocol}} - current protocol http or https + * {{protocol url="www.domain.com/"}} domain URL with current protocol + * {{protocol http="http://url" https="https://url"} + * also allow additional parameter "store" + * + * @param array $construction + * @return string + */ + public function protocolDirective($construction) + { + $params = $this->_getIncludeParameters($construction[2]); + $store = null; + if (isset($params['store'])) { + $store = Mage::app()->getSafeStore($params['store']); + } + $isSecure = Mage::app()->getStore($store)->isCurrentlySecure(); + $protocol = $isSecure ? 'https' : 'http'; + if (isset($params['url'])) { + return $protocol . '://' . $params['url']; + } + elseif (isset($params['http']) && isset($params['https'])) { + if ($isSecure) { + return $params['https']; + } + return $params['http']; + } + + return $protocol; + } } diff --git a/app/code/core/Mage/Core/Model/Layout.php b/app/code/core/Mage/Core/Model/Layout.php index fb2156ee5a..2f38aa4af6 100644 --- a/app/code/core/Mage/Core/Model/Layout.php +++ b/app/code/core/Mage/Core/Model/Layout.php @@ -154,19 +154,29 @@ public function generateXml() { $xml = $this->getUpdate()->asSimplexml(); $removeInstructions = $xml->xpath("//remove"); - foreach ($removeInstructions as $infoNode) { - $attributes = $infoNode->attributes(); - if ($acl = (string)$attributes->acl && !Mage::getSingleton('admin/session')->isAllowed($acl)) { - $block->addAttribute('ignore', true); - } - if ($blockName = (string)$attributes->name) { - $ignoreNodes = $xml->xpath("//block[@name='".$blockName."']"); - foreach ($ignoreNodes as $block) { - $block->addAttribute('ignore', true); - } - $ignoreNodes = $xml->xpath("//reference[@name='".$blockName."']"); - foreach ($ignoreNodes as $block) { - $block->addAttribute('ignore', true); + + if (is_array($removeInstructions)) { + foreach ($removeInstructions as $infoNode) { + $attributes = $infoNode->attributes(); + if ($blockName = (string)$attributes->name) { + $ignoreNodes = $xml->xpath("//block[@name='".$blockName."']"); + if (!is_array($ignoreNodes)) { + continue; + } + $ignoreReferences = $xml->xpath("//reference[@name='".$blockName."']"); + if (is_array($ignoreReferences)) { + $ignoreNodes = array_merge($ignoreNodes, $ignoreReferences); + } + + foreach ($ignoreNodes as $block) { + if ($block->getAttribute('ignore') !== null) { + continue; + } + if (($acl = (string)$attributes->acl) && Mage::getSingleton('admin/session')->isAllowed($acl)) { + continue; + } + $block->addAttribute('ignore', true); + } } } } @@ -330,7 +340,7 @@ protected function _generateAction($node, $parent) if (isset($node['json'])) { $json = explode(' ', (string)$node['json']); foreach ($json as $arg) { - $args[$arg] = Zend_Json::decode($args[$arg]); + $args[$arg] = Mage::helper('core')->jsonDecode($args[$arg]); } } @@ -456,9 +466,7 @@ protected function _getBlockInstance($block, array $attributes=array()) Mage::throwException(Mage::helper('core')->__('Invalid block type: %s', $block)); } } - $fileName = mageFindClassFile($block); - if ($fileName!==false) { - //include_once ($fileName); + if (class_exists($block, false) || mageFindClassFile($block)) { $block = new $block($attributes); } } @@ -575,7 +583,7 @@ public function getBlockSingleton($type) */ public function helper($name) { - $helper = Mage::app()->getHelper($name); + $helper = Mage::helper($name); if (!$helper) { return false; } diff --git a/app/code/core/Mage/Core/Model/Mysql4/Abstract.php b/app/code/core/Mage/Core/Model/Mysql4/Abstract.php index 3c21ad0c55..c2ed5e936c 100644 --- a/app/code/core/Mage/Core/Model/Mysql4/Abstract.php +++ b/app/code/core/Mage/Core/Model/Mysql4/Abstract.php @@ -93,6 +93,13 @@ abstract class Mage_Core_Model_Mysql4_Abstract extends Mage_Core_Model_Resource_ */ protected $_isPkAutoIncrement = true; + /** + * Fields List for update in forsedSave + * + * @var array + */ + protected $_fieldsForUpdate = array(); + protected $_mainTableFields; /** @@ -375,6 +382,32 @@ public function save(Mage_Core_Model_Abstract $object) return $this; } + /** + * Forsed save object data + * forsed update If duplicate unique key data + * + * @param Mage_Core_Model_Abstract $object + * @return Mage_Core_Model_Mysql4_Abstract + */ + public function forsedSave(Mage_Core_Model_Abstract $object) + { + $this->_beforeSave($object); + + // update + if (!is_null($object->getId()) && $this->_isPkAutoIncrement) { + $condition = $this->_getWriteAdapter()->quoteInto($this->getIdFieldName().'=?', $object->getId()); + $this->_getWriteAdapter()->update($this->getMainTable(), $this->_prepareDataForSave($object), $condition); + } + else { + $this->_getWriteAdapter()->insertOnDuplicate($this->getMainTable(), $this->_prepareDataForSave($object), $this->_fieldsForUpdate); + $object->setId($this->_getWriteAdapter()->lastInsertId($this->getMainTable())); + } + + $this->_afterSave($object); + + return $this; + } + /** * Delete the object * diff --git a/app/code/core/Mage/Core/Model/Store.php b/app/code/core/Mage/Core/Model/Store.php index 667640c26c..709bab5655 100644 --- a/app/code/core/Mage/Core/Model/Store.php +++ b/app/code/core/Mage/Core/Model/Store.php @@ -385,10 +385,15 @@ public function getDefaultBasePath() * @param array $params * @return string */ - public function getUrl($route='', $params=array()) + public function getUrl($route = '', $params = array()) { + /* @var $url Mage_Core_Model_Url */ $url = Mage::getModel('core/url') ->setStore($this); + if (Mage::app()->getStore()->getId() != $this->getId()) { + $params['_store_to_url'] = true; + } + return $url->getUrl($route, $params); } diff --git a/app/code/core/Mage/Core/Model/Translate/Inline.php b/app/code/core/Mage/Core/Model/Translate/Inline.php index ccaeef7033..52cd96b891 100644 --- a/app/code/core/Mage/Core/Model/Translate/Inline.php +++ b/app/code/core/Mage/Core/Model/Translate/Inline.php @@ -34,22 +34,64 @@ */ class Mage_Core_Model_Translate_Inline { + /** + * Regular Expression for detected and replace translate + * + * @var string + */ protected $_tokenRegex = '\{\{\{(.*?)\}\}\{\{(.*?)\}\}\{\{(.*?)\}\}\{\{(.*?)\}\}\}'; + + /** + * Response body or JSON content string + * + * @var string + */ protected $_content; + + /** + * Is enabled and allowed inline translates flags + * + * @var bool + */ protected $_isAllowed; - protected $_isScriptInserted = false; - protected $_isAjaxRequest = null; - public function isAllowed($storeId=null) + /** + * Flag about inserted styles and scripts for inline translates + * + * @var bool + */ + protected $_isScriptInserted = false; + + /** + * Current content is JSON or Response body + * + * @var bool + */ + protected $_isJson = false; + + /** + * Is enabled and allowed Inline Translates + * + * @param mixed $store + * @return bool + */ + public function isAllowed($store = null) { + if (is_null($store)) { + $store = Mage::app()->getStore(); + } + if (!$store instanceof Mage_Core_Model_Store) { + $store = Mage::app()->getStore($store); + } + if (is_null($this->_isAllowed)) { - if (Mage::getDesign()->getArea()==='adminhtml') { - $active = Mage::getStoreConfigFlag('dev/translate_inline/active_admin', $storeId); + if (Mage::getDesign()->getArea() == 'adminhtml') { + $active = Mage::getStoreConfigFlag('dev/translate_inline/active_admin', $store); } else { - $active = Mage::getStoreConfigFlag('dev/translate_inline/active', $storeId); + $active = Mage::getStoreConfigFlag('dev/translate_inline/active', $store); } - $this->_isAllowed = $active && Mage::helper('core')->isDevAllowed($storeId); + $this->_isAllowed = $active && Mage::helper('core')->isDevAllowed($store); } $translate = Mage::getSingleton('core/translate'); @@ -58,64 +100,86 @@ public function isAllowed($storeId=null) return $translate->getTranslateInline() && $this->_isAllowed; } + /** + * Parse and save edited translate + * + * @param array $translate + * @return Mage_Core_Model_Translate_Inline + */ public function processAjaxPost($translate) { if (!$this->isAllowed()) { - return; + return $this; } - $resource = Mage::getResourceModel('core/translate_string'); /* @var $resource Mage_Core_Model_Mysql4_Translate_String */ + $resource = Mage::getResourceModel('core/translate_string'); foreach ($translate as $t) { if (Mage::getDesign()->getArea() == 'adminhtml') { $storeId = 0; - } - elseif (empty($t['perstore'])) { + } else if (empty($t['perstore'])) { $resource->deleteTranslate($t['original'], null, false); $storeId = 0; - } - else { + } else { $storeId = Mage::app()->getStore()->getId(); } $resource->saveTranslate($t['original'], $t['custom'], null, $storeId); } + + return $this; } + /** + * Strip inline translations from text + * + * @param array|string $body + * @return Mage_Core_Model_Translate_Inline + */ public function stripInlineTranslations(&$body) { if (is_array($body)) { - foreach ($body as $i=>&$part) { - if (strpos($part,'{{{')!==false) { - $part = preg_replace('#'.$this->_tokenRegex.'#', '$1', $part); - } + foreach ($body as &$part) { + $this->stripInlineTranslations($part); } - } elseif (is_string($body)) { + } else if (is_string($body)) { $body = preg_replace('#'.$this->_tokenRegex.'#', '$1', $body); } return $this; } - public function processResponseBody(&$bodyArray) + /** + * Replace translate templates to HTML fragments + * + * @param array|string $body + * @return Mage_Core_Model_Translate_Inline + */ + public function processResponseBody(&$body) { if (!$this->isAllowed()) { - // TODO: move translations from exceptions and errors to output - if (Mage::getDesign()->getArea()==='adminhtml') { - $this->stripInlineTranslations($bodyArray); + if (Mage::getDesign()->getArea() == 'adminhtml') { + $this->stripInlineTranslations($body); } - return; + return $this; } - foreach ($bodyArray as $i=>$content) { - $this->_content = $content; + if (is_array($body)) { + foreach ($body as &$part) { + $this->processResponseBody($part); + } + } else if (is_string($body)) { + Mage::log($body); + $this->_content = $body; $this->_tagAttributes(); $this->_specialTags(); $this->_otherText(); $this->_insertInlineScriptsHtml(); - $bodyArray[$i] = $this->_content; + $body = $this->_content; } + + return $this; } protected function _insertInlineScriptsHtml() @@ -150,104 +214,106 @@ protected function _insertInlineScriptsHtml() $this->_isScriptInserted = true; } + /** + * Escape Translate data + * + * @param string $string + * @return string + */ protected function _escape($string) { return str_replace("'", "\\'", htmlspecialchars($string)); } + /** + * Prepare tags inline translates + * + */ protected function _tagAttributes() { -#echo __METHOD__; - - if ($this->getIsAjaxRequest()) { - $quoteHtml = '\"'; + if ($this->getIsJson()) { $quotePatern = '\\\\"'; + $quoteHtml = '\"'; } else { - $quoteHtml = '"'; $quotePatern = '"'; + $quoteHtml = '"'; } - $nextTag = 0; $i=0; - while (preg_match('#<([a-z]+)\s*?[^>]+?(('.$this->_tokenRegex.')[^/>]*?)+(/?(>))#i', - $this->_content, $tagMatch, PREG_OFFSET_CAPTURE, $nextTag)) { -#echo ''.print_r($tagMatch[0][0],1).'
    '; - - $next = 0; - $tagHtml = $tagMatch[0][0]; - $trArr = array(); - - while (preg_match('#'.$this->_tokenRegex.'#i', - $tagHtml, $m, PREG_OFFSET_CAPTURE, $next)) { - + $tagMatch = array(); + $nextTag = 0; + $tagRegExp = '#<([a-z]+)\s*?[^>]+?(('.$this->_tokenRegex.')[^/>]*?)+(/?(>))#i'; + while (preg_match($tagRegExp, $this->_content, $tagMatch, PREG_OFFSET_CAPTURE, $nextTag)) { + $next = 0; + $tagHtml = $tagMatch[0][0]; + $trArr = array(); + $m = array(); + $attrRegExp = '#'.$this->_tokenRegex.'#'; + + while (preg_match($attrRegExp, $tagHtml, $m, PREG_OFFSET_CAPTURE, $next)) { $trArr[] = '{shown:\''.$this->_escape($m[1][0]).'\',' - .'translated:\''.$this->_escape($m[2][0]).'\',' - .'original:\''.$this->_escape($m[3][0]).'\',' - .'location:\'Tag attribute (ALT, TITLE, etc.)\',' - .'scope:\''.$this->_escape($m[4][0]).'\'}'; + . 'translated:\''.$this->_escape($m[2][0]).'\',' + . 'original:\''.$this->_escape($m[3][0]).'\',' + . 'location:\'Tag attribute (ALT, TITLE, etc.)\',' + . 'scope:\''.$this->_escape($m[4][0]).'\'}'; $tagHtml = substr_replace($tagHtml, $m[1][0], $m[0][1], strlen($m[0][0])); $next = $m[0][1]; } - if (preg_match('# translate='.$quotePatern.'\[(.+?)\]'.$quotePatern.'#i', $tagMatch[0][0], $m, PREG_OFFSET_CAPTURE)) { - foreach ($trArr as $i=>$tr) { - if (strpos($m[1][0], $tr)!==false) { + $transRegExp = '# translate='.$quotePatern.'\[(.+?)\]'.$quotePatern.'#i'; + if (preg_match($transRegExp, $tagHtml, $m, PREG_OFFSET_CAPTURE)) { + foreach ($trArr as $i => $tr) { + if (strpos($m[1][0], $tr) !== false) { unset($trArr[$i]); } } array_unshift($trArr, $m[1][0]); - $start = $tagMatch[0][1]+$m[0][1]; - $len = strlen($m[0][0]); - } else { - $start = $tagMatch[8][1]; - $len = 0; + $tagHtml = substr_replace($tagHtml, '', $m[0][1], strlen($m[0][0])); } - $trAttr = ' translate="['.join(',', $trArr).']"'; - $tagHtml = preg_replace('#/?>$#', $trAttr.'$0', $tagHtml); + $trAttr = ' translate='.$quoteHtml.'['.join(',', $trArr).']'.$quoteHtml; + $tagHtml = preg_replace('#/?>$#', $trAttr . '$0', $tagHtml); - - $this->_content = substr_replace($this->_content, $tagHtml, - $tagMatch[0][1], $tagMatch[9][1]+1-$tagMatch[0][1]); + $this->_content = substr_replace($this->_content, $tagHtml, $tagMatch[0][1], + $tagMatch[9][1]+1-$tagMatch[0][1]); $nextTag = $tagMatch[0][1]; } } + /** + * Prepare special tags + * + */ protected function _specialTags() { -#echo __METHOD__; - - if ($this->getIsAjaxRequest()) { - $quoteHtml = '\"'; + if ($this->getIsJson()) { $quotePatern = '\\\\"'; + $quoteHtml = '\"'; } else { - $quoteHtml = '"'; $quotePatern = '"'; + $quoteHtml = '"'; } $nextTag = 0; $location = array( 'script' => 'String in Javascript', - 'title' => 'Page title', + 'title' => 'Page title', 'select' => 'Dropdown option', 'button' => 'Button label', - 'a' => 'Link label', + 'a' => 'Link label', ); - while (preg_match('#<(script|title|select|button|a)(\s+[^>]*|)(>)#i', - $this->_content, $tagMatch, PREG_OFFSET_CAPTURE, $nextTag)) { -#echo ''.print_r($tagMatch[0][0],1).'
    '; - + $tagRegExp = '#<(script|title|select|button|a)(\s+[^>]*|)(>)#i'; + $tagMatch = array(); + while (preg_match($tagRegExp, $this->_content, $tagMatch, PREG_OFFSET_CAPTURE, $nextTag)) { $tagClosure = ''; $tagLength = stripos($this->_content, $tagClosure, $tagMatch[0][1])-$tagMatch[0][1]+strlen($tagClosure); - $next = 0; - $tagHtml = substr($this->_content, $tagMatch[0][1], $tagLength); - $trArr = array(); - - while (preg_match('#'.$this->_tokenRegex.'#i', - $tagHtml, $m, PREG_OFFSET_CAPTURE, $next)) { - + $next = 0; + $tagHtml = substr($this->_content, $tagMatch[0][1], $tagLength); + $trArr = array(); + $m = array(); + while (preg_match('#'.$this->_tokenRegex.'#i', $tagHtml, $m, PREG_OFFSET_CAPTURE, $next)) { $trArr[] = '{shown:\''.$this->_escape($m[1][0]).'\',' .'translated:\''.$this->_escape($m[2][0]).'\',' .'original:\''.$this->_escape($m[3][0]).'\',' @@ -255,18 +321,16 @@ protected function _specialTags() .'scope:\''.$this->_escape($m[4][0]).'\'}'; $tagHtml = substr_replace($tagHtml, $m[1][0], $m[0][1], strlen($m[0][0])); - - $next = $m[0][1]; + $next = $m[0][1]; } if (!empty($trArr)) { $trArr = array_unique($trArr); - - $tag = strtolower($tagMatch[1][0]); + $tag = strtolower($tagMatch[1][0]); switch ($tag) { case 'script': case 'title': $tagHtml .= ''.strtoupper($tag).''; + .'" translate='.$quoteHtml.'['.join(',', $trArr).']'.$quoteHtml.'>'.strtoupper($tag).''; break; } $this->_content = substr_replace($this->_content, $tagHtml, $tagMatch[0][1], $tagLength); @@ -288,7 +352,7 @@ protected function _specialTags() } $this->_content = substr_replace($this->_content, - ' translate='.$quoteHtml.'['.join(',',$trArr).']'.$quoteHtml, $start, $len); + ' translate='.$quoteHtml.'['.join(',', $trArr).']'.$quoteHtml, $start, $len); break; } } @@ -298,24 +362,21 @@ protected function _specialTags() } + /** + * Prepare other text inline translates + * + */ protected function _otherText() { -#return; -#echo __METHOD__; -#echo "".$this->_content."
    "; -#exit; - - if ($this->getIsAjaxRequest()) { + if ($this->getIsJson()) { $quoteHtml = '\"'; } else { $quoteHtml = '"'; } $next = 0; - while (preg_match('#('.$this->_tokenRegex.')#', - $this->_content, $m, PREG_OFFSET_CAPTURE, $next)) { -#echo ''.print_r($m[0][0],1).'
    '; - + $m = array(); + while (preg_match('#('.$this->_tokenRegex.')#', $this->_content, $m, PREG_OFFSET_CAPTURE, $next)) { $tr = '{shown:\''.$this->_escape($m[2][0]).'\',' .'translated:\''.$this->_escape($m[3][0]).'\',' .'original:\''.$this->_escape($m[4][0]).'\',' @@ -330,17 +391,50 @@ protected function _otherText() } + /** + * Check is a Request contain Json flag + * + * @deprecated 1.3.2.2 + * @return bool + */ public function getIsAjaxRequest() { - if (!is_null($this->_isAjaxRequest)) { - return $this->_isAjaxRequest; - } else { - return Mage::app()->getRequest()->getQuery('isAjax'); - } + return (bool)Mage::app()->getRequest()->getQuery('isAjax'); } - public function setIsAjaxRequest($status) + /** + * Set is a Request contain Json flag + * + * @param bool $flag + * @deprecated 1.3.2.2 + * @return Mage_Core_Model_Translate_Inline + */ + public function setIsAjaxRequest($flag) { - $this->_isAjaxRequest = $status; + Mage::app()->getRequest()->setQuery('isAjax', intval((bool)$flag)); + return $this; + } + + /** + * Retrieve flag about parsed content is Json + * + * @return bool + */ + public function getIsJson() + { + return $this->_isJson; + } + + /** + * Set flag about parsed content is Json + * + * @param bool $flag + * @return Mage_Core_Model_Translate_Inline + */ + public function setIsJson($flag) + { + $this->_isJson = (bool)$flag; + return $this; } } + diff --git a/app/code/core/Mage/Core/Model/Url.php b/app/code/core/Mage/Core/Model/Url.php index 97c3065685..a60389d962 100644 --- a/app/code/core/Mage/Core/Model/Url.php +++ b/app/code/core/Mage/Core/Model/Url.php @@ -606,6 +606,9 @@ public function getRouteUrl($routePath=null, $routeParams=null) $this->unsetData('route_params'); if (isset($routeParams['_direct'])) { + if (is_array($routeParams)) { + $this->setRouteParams($routeParams, false); + } return $this->getBaseUrl().$routeParams['_direct']; } @@ -692,24 +695,48 @@ public function getQuery($escape = false) return $this->_getData('query'); } - public function setQueryParams(array $data, $useCurrent = false) + /** + * Set query Params as array + * + * @param array $data + * @return Mage_Core_Model_Url + */ + public function setQueryParams(array $data) { $this->unsetData('query'); - if ($useCurrent) { - $params = $this->_getData('query_params'); - foreach ($data as $param => $value) { - $params[$param] = $value; - } - $this->setData('query_params', $params); + + if ($this->_getData('query_params') == $data) { return $this; } - if ($this->_getData('query_params')==$data) { - return $this; + $params = $this->_getData('query_params'); + if (!is_array($params)) { + $params = array(); + } + foreach ($data as $param => $value) { + $params[$param] = $value; } - return $this->setData('query_params', $data); + $this->setData('query_params', $params); + + return $this; + } + + /** + * Purge Query params array + * + * @return Mage_Core_Model_Url + */ + public function purgeQueryParams() + { + $this->setData('query_params', array()); + return $this; } + /** + * Retrurn Query Params + * + * @return array + */ public function getQueryParams() { if (!$this->hasData('query_params')) { @@ -788,6 +815,7 @@ public function getUrl($routePath=null, $routeParams=null) $query = null; if (isset($routeParams['_query'])) { + $this->purgeQueryParams(); $query = $routeParams['_query']; unset($routeParams['_query']); } diff --git a/app/code/core/Mage/Core/Model/Url/Rewrite.php b/app/code/core/Mage/Core/Model/Url/Rewrite.php index 1e0d437b4a..ea48def69e 100644 --- a/app/code/core/Mage/Core/Model/Url/Rewrite.php +++ b/app/code/core/Mage/Core/Model/Url/Rewrite.php @@ -196,7 +196,7 @@ public function rewrite(Zend_Controller_Request_Http $request=null, Zend_Control */ if (!$this->getId() && isset($_GET['___from_store'])) { try { - $fromStoreId = Mage::app()->getStore($_GET['___from_store']); + $fromStoreId = Mage::app()->getStore($_GET['___from_store'])->getId(); } catch (Exception $e) { return false; diff --git a/app/code/core/Mage/Core/etc/system.xml b/app/code/core/Mage/Core/etc/system.xml index 1eb83fca63..0843279ab2 100644 --- a/app/code/core/Mage/Core/etc/system.xml +++ b/app/code/core/Mage/Core/etc/system.xml @@ -586,15 +586,15 @@ 1 1 - - - select + + + multiselect + 3 adminhtml/system_config_source_country - 1 1 1 - 1 - + 0 + diff --git a/app/code/core/Mage/Core/functions.php b/app/code/core/Mage/Core/functions.php index b945db58ce..9541627c7a 100644 --- a/app/code/core/Mage/Core/functions.php +++ b/app/code/core/Mage/Core/functions.php @@ -174,6 +174,9 @@ function mageCoreErrorHandler($errno, $errstr, $errfile, $errline){ if (!defined('E_RECOVERABLE_ERROR')) { define('E_RECOVERABLE_ERROR', 4096); } + if (!defined('E_DEPRECATED')) { + define('E_DEPRECATED', 8192); + } // PEAR specific message handling if (stripos($errfile.$errstr, 'pear') !== false) { @@ -229,6 +232,9 @@ function mageCoreErrorHandler($errno, $errstr, $errfile, $errline){ case E_RECOVERABLE_ERROR: $errorMessage .= "Recoverable Error"; break; + case E_DEPRECATED: + $errorMessage .= "Deprecated functionality"; + break; default: $errorMessage .= "Unknown error ($errno)"; break; diff --git a/app/code/core/Mage/Customer/Model/Address/Abstract.php b/app/code/core/Mage/Customer/Model/Address/Abstract.php index 8c1996d868..1ac0d4c662 100644 --- a/app/code/core/Mage/Customer/Model/Address/Abstract.php +++ b/app/code/core/Mage/Customer/Model/Address/Abstract.php @@ -347,7 +347,8 @@ public function validate() $errors[] = $helper->__('Please enter telephone.'); } - if (!Zend_Validate::is($this->getPostcode(), 'NotEmpty')) { + $_havingOptionalZip = Mage::helper('directory')->getCountriesWithOptionalZip(); + if (!in_array($this->getCountryId(), $_havingOptionalZip) && !Zend_Validate::is($this->getPostcode(), 'NotEmpty')) { $errors[] = $helper->__('Please enter zip/postal code.'); } diff --git a/app/code/core/Mage/Customer/Model/Address/Api.php b/app/code/core/Mage/Customer/Model/Address/Api.php index 2e3c8044dc..7136142749 100644 --- a/app/code/core/Mage/Customer/Model/Address/Api.php +++ b/app/code/core/Mage/Customer/Model/Address/Api.php @@ -34,7 +34,7 @@ class Mage_Customer_Model_Address_Api extends Mage_Customer_Model_Api_Resource { protected $_mapAttributes = array( - 'customer_id' => 'entity_id' + 'customer_address_id' => 'entity_id' ); public function __construct() @@ -73,8 +73,8 @@ public function items($customerId) } } - $row['is_default_billing'] = $customer->getDefaultBillingAddress() == $address->getId(); - $row['is_default_shipping'] = $customer->getDefaultShippingAddress() == $address->getId(); + $row['is_default_billing'] = $customer->getDefaultBilling() == $address->getId(); + $row['is_default_shipping'] = $customer->getDefaultShipping() == $address->getId(); $result[] = $row; @@ -160,8 +160,8 @@ public function info($addressId) if ($customer = $address->getCustomer()) { - $result['is_default_billing'] = $customer->getDefaultBillingAddress() == $address->getId(); - $result['is_default_shipping'] = $customer->getDefaultShippingAddress() == $address->getId(); + $result['is_default_billing'] = $customer->getDefaultBilling() == $address->getId(); + $result['is_default_shipping'] = $customer->getDefaultShipping() == $address->getId(); } return $result; diff --git a/app/code/core/Mage/Customer/Model/Address/Api/V2.php b/app/code/core/Mage/Customer/Model/Address/Api/V2.php index c3416caa40..6b35df5187 100644 --- a/app/code/core/Mage/Customer/Model/Address/Api/V2.php +++ b/app/code/core/Mage/Customer/Model/Address/Api/V2.php @@ -110,8 +110,8 @@ public function info($addressId) if ($customer = $address->getCustomer()) { - $result['is_default_billing'] = $customer->getDefaultBillingAddress() == $address->getId(); - $result['is_default_shipping'] = $customer->getDefaultShippingAddress() == $address->getId(); + $result['is_default_billing'] = $customer->getDefaultBilling() == $address->getId(); + $result['is_default_shipping'] = $customer->getDefaultShipping() == $address->getId(); } return $result; diff --git a/app/code/core/Mage/Customer/Model/Convert/Adapter/Customer.php b/app/code/core/Mage/Customer/Model/Convert/Adapter/Customer.php index c9f5561842..e5280238fa 100644 --- a/app/code/core/Mage/Customer/Model/Convert/Adapter/Customer.php +++ b/app/code/core/Mage/Customer/Model/Convert/Adapter/Customer.php @@ -497,7 +497,7 @@ public function saveRow($importData) $setValue = $value; if ($attribute->getFrontendInput() == 'multiselect') { - $value = split(self::MULTI_DELIMITER, $value); + $value = explode(self::MULTI_DELIMITER, $value); $isArray = true; $setValue = array(); } diff --git a/app/code/core/Mage/Customer/Model/Customer.php b/app/code/core/Mage/Customer/Model/Customer.php index a35571d60a..f02b3f45e5 100644 --- a/app/code/core/Mage/Customer/Model/Customer.php +++ b/app/code/core/Mage/Customer/Model/Customer.php @@ -450,7 +450,7 @@ public function isAddressPrimary(Mage_Customer_Model_Address $address) * * @return Mage_Customer_Model_Customer */ - public function sendNewAccountEmail($type = 'registered', $backUrl = '') + public function sendNewAccountEmail($type = 'registered', $backUrl = '', $store_id = '0') { $types = array( 'registered' => self::XML_PATH_REGISTER_EMAIL_TEMPLATE, // welcome email, when confirmation is disabled @@ -465,7 +465,7 @@ public function sendNewAccountEmail($type = 'registered', $backUrl = '') /* @var $translate Mage_Core_Model_Translate */ $translate->setTranslateInline(false); - $storeId = $this->getStoreId(); + $storeId = ($store_id == '0')?$this->getStoreId():$store_id; if ($this->getWebsiteId() != '0' && $storeId == '0') { $storeIds = Mage::app()->getWebsite($this->getWebsiteId())->getStoreIds(); reset($storeIds); @@ -475,8 +475,8 @@ public function sendNewAccountEmail($type = 'registered', $backUrl = '') Mage::getModel('core/email_template') ->setDesignConfig(array('area'=>'frontend', 'store'=>$storeId)) ->sendTransactional( - Mage::getStoreConfig($types[$type]), - Mage::getStoreConfig(self::XML_PATH_REGISTER_EMAIL_IDENTITY), + Mage::getStoreConfig($types[$type], $storeId), + Mage::getStoreConfig(self::XML_PATH_REGISTER_EMAIL_IDENTITY, $storeId), $this->getEmail(), $this->getName(), array('customer' => $this, 'back_url' => $backUrl)); @@ -1042,7 +1042,7 @@ public function canSkipConfirmation() return $this->getId() && $this->hasSkipConfirmationIfEmail() && strtolower($this->getSkipConfirmationIfEmail()) === strtolower($this->getEmail()); } - + public function __clone() { $newAddressCollection = $this->getPrimaryAddresses(); diff --git a/app/code/core/Mage/Customer/controllers/AccountController.php b/app/code/core/Mage/Customer/controllers/AccountController.php index ae24d2a5d2..dc98ca5f8a 100644 --- a/app/code/core/Mage/Customer/controllers/AccountController.php +++ b/app/code/core/Mage/Customer/controllers/AccountController.php @@ -318,10 +318,7 @@ public function createPostAction() ->addException($e, $this->__('Can\'t save customer')); } } - /** - * Protect XSS injection in user input - */ - $this->_getSession()->setEscapeMessages(true); + $this->_redirectError(Mage::getUrl('*/*/create', array('_secure'=>true))); } diff --git a/app/code/core/Mage/Customer/etc/wsdl.xml b/app/code/core/Mage/Customer/etc/wsdl.xml index 623ff749ec..58c4564da9 100644 --- a/app/code/core/Mage/Customer/etc/wsdl.xml +++ b/app/code/core/Mage/Customer/etc/wsdl.xml @@ -72,9 +72,9 @@ - + - + @@ -99,7 +99,7 @@ - + @@ -168,7 +168,7 @@ - + diff --git a/app/code/core/Mage/Directory/Block/Data.php b/app/code/core/Mage/Directory/Block/Data.php index 25daddb237..cc70d18c70 100644 --- a/app/code/core/Mage/Directory/Block/Data.php +++ b/app/code/core/Mage/Directory/Block/Data.php @@ -147,7 +147,7 @@ public function getRegionsJs() 'name'=>$region->getName() ); } - $regionsJs = Zend_Json::encode($regions); + $regionsJs = Mage::helper('core')->jsonEncode($regions); } Varien_Profiler::stop('TEST: '.__METHOD__); return $regionsJs; diff --git a/app/code/core/Mage/Directory/Helper/Data.php b/app/code/core/Mage/Directory/Helper/Data.php index 93948dfc28..8c5601f75c 100644 --- a/app/code/core/Mage/Directory/Helper/Data.php +++ b/app/code/core/Mage/Directory/Helper/Data.php @@ -87,7 +87,7 @@ public function getRegionJson() 'name'=>$region->getName() ); } - $json = Zend_Json::encode($regions); + $json = Mage::helper('core')->jsonEncode($regions); if (Mage::app()->useCache('config')) { Mage::app()->saveCache($json, $cacheKey, array('config')); @@ -111,4 +111,28 @@ public function currencyConvert($amount, $from, $to=null) $converted = $this->_currencyCache[$from]->convert($amount, $to); return $converted; } + + /** + * Return ISO2 country codes, which have optional Zip/Postal pre-configured + * + * @param mixed $storeId Store + * @return array + */ + public function getCountriesWithOptionalZip($storeId = null) + { + $value = Mage::getStoreConfig('general/country/optional_zip_countries', $storeId); + return preg_split('/\,/', $value, 0, PREG_SPLIT_NO_EMPTY); + } + + /** + * Same as getCountriesWithOptionalZip() but result is json-encoded + * + * @see getCountriesWithOptionalZip + * @param mixed $storeId Store + * @return string + */ + public function getCountriesWithOptionalZipJson($storeId = null) + { + return Mage::helper('core')->jsonEncode($this->getCountriesWithOptionalZip($storeId)); + } } diff --git a/app/code/core/Mage/Directory/Model/Currency.php b/app/code/core/Mage/Directory/Model/Currency.php index 5e8f3e0f0d..cb8714f201 100644 --- a/app/code/core/Mage/Directory/Model/Currency.php +++ b/app/code/core/Mage/Directory/Model/Currency.php @@ -194,6 +194,24 @@ public function getFilter() */ public function format($price, $options=array(), $includeContainer = true, $addBrackets = false) { + return $this->formatPrecision($price, 2, $options, $includeContainer, $addBrackets); + } + + /** + * Apply currency format to number with specific rounding precision + * + * @param float $price + * @param int $precision + * @param array $options + * @param bool $includeContainer + * @param bool $addBrackets + * @return string + */ + public function formatPrecision($price, $precision, $options=array(), $includeContainer = true, $addBrackets = false) + { + if (!isset($options['precision'])) { + $options['precision'] = $precision; + } if ($includeContainer) { return '' . ($addBrackets ? '[' : '') . $this->formatTxt($price, $options) . ($addBrackets ? ']' : '') . ''; } diff --git a/app/code/core/Mage/Downloadable/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable/Links.php b/app/code/core/Mage/Downloadable/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable/Links.php index e703cc6821..a015e936d7 100644 --- a/app/code/core/Mage/Downloadable/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable/Links.php +++ b/app/code/core/Mage/Downloadable/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable/Links.php @@ -276,7 +276,7 @@ public function getConfigJson($type='links') $this->getConfig()->setReplaceBrowseWithRemove(true); $this->getConfig()->setWidth('32'); $this->getConfig()->setHideUploadButton(true); - return Zend_Json::encode($this->getConfig()->getData()); + return Mage::helper('core')->jsonEncode($this->getConfig()->getData()); } /** diff --git a/app/code/core/Mage/Downloadable/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable/Samples.php b/app/code/core/Mage/Downloadable/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable/Samples.php index a8c3da3497..d990998445 100644 --- a/app/code/core/Mage/Downloadable/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable/Samples.php +++ b/app/code/core/Mage/Downloadable/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable/Samples.php @@ -185,7 +185,7 @@ public function getConfigJson() $this->getConfig()->setReplaceBrowseWithRemove(true); $this->getConfig()->setWidth('32'); $this->getConfig()->setHideUploadButton(true); - return Zend_Json::encode($this->getConfig()->getData()); + return Mage::helper('core')->jsonEncode($this->getConfig()->getData()); } /** diff --git a/app/code/core/Mage/Downloadable/Block/Catalog/Product/Links.php b/app/code/core/Mage/Downloadable/Block/Catalog/Product/Links.php index 4b81214cf4..6a095f8763 100644 --- a/app/code/core/Mage/Downloadable/Block/Catalog/Product/Links.php +++ b/app/code/core/Mage/Downloadable/Block/Catalog/Product/Links.php @@ -123,7 +123,7 @@ public function getJsonConfig() $config[$link->getId()] = Mage::helper('core')->currency($link->getPrice(), false, false); } - return Zend_Json::encode($config); + return Mage::helper('core')->jsonEncode($config); } public function getLinkSamlpeUrl($link) diff --git a/app/code/core/Mage/Downloadable/Helper/Download.php b/app/code/core/Mage/Downloadable/Helper/Download.php index eedc1c0f05..e1082334e2 100644 --- a/app/code/core/Mage/Downloadable/Helper/Download.php +++ b/app/code/core/Mage/Downloadable/Helper/Download.php @@ -207,7 +207,7 @@ public function getContentType() } elseif ($this->_linkType == self::LINK_TYPE_URL) { if (isset($this->_urlHeaders['content-type'])) { - $contentType = split('; ', $this->_urlHeaders['content-type']); + $contentType = explode('; ', $this->_urlHeaders['content-type']); return $contentType[0]; } } @@ -222,7 +222,7 @@ public function getFilename() } elseif ($this->_linkType == self::LINK_TYPE_URL) { if (isset($this->_urlHeaders['content-disposition'])) { - $contentDisposition = split('; ', $this->_urlHeaders['content-disposition']); + $contentDisposition = explode('; ', $this->_urlHeaders['content-disposition']); if (!empty($contentDisposition[1]) && strpos($contentDisposition[1], 'filename=') !== false) { return substr($contentDisposition[1], 9); } diff --git a/app/code/core/Mage/Downloadable/Model/Mysql4/Link.php b/app/code/core/Mage/Downloadable/Model/Mysql4/Link.php index e3bb63b603..551ab26cb7 100644 --- a/app/code/core/Mage/Downloadable/Model/Mysql4/Link.php +++ b/app/code/core/Mage/Downloadable/Model/Mysql4/Link.php @@ -94,13 +94,35 @@ public function saveItemTitleAndPrice($linkObject) } } else { if (!$linkObject->getUseDefaultPrice()) { - $this->_getWriteAdapter()->insert( - $this->getTable('downloadable/link_price'), - array( - 'link_id' => $linkObject->getId(), - 'website_id' => $linkObject->getWebsiteId(), - 'price' => $linkObject->getPrice() - )); + $dataToInsert[] = array( + 'link_id' => $linkObject->getId(), + 'website_id' => $linkObject->getWebsiteId(), + 'price' => $linkObject->getPrice() + ); + $_isNew = $linkObject->getOrigData('link_id') != $linkObject->getLinkId(); + if ($linkObject->getWebsiteId() == 0 && $_isNew && !Mage::helper('catalog')->isPriceGlobal()) { + $websiteIds = $linkObject->getProductWebsiteIds(); + foreach ($websiteIds as $websiteId) { + $baseCurrency = Mage::app()->getBaseCurrencyCode(); + $websiteCurrency = Mage::app()->getWebsite($websiteId)->getBaseCurrencyCode(); + if ($websiteCurrency == $baseCurrency) { + continue; + } + $rate = Mage::getModel('directory/currency')->load($baseCurrency)->getRate($websiteCurrency); + if (!$rate) { + $rate = 1; + } + $newPrice = $linkObject->getPrice() * $rate; + $dataToInsert[] = array( + 'link_id' => $linkObject->getId(), + 'website_id' => $websiteId, + 'price' => $newPrice + ); + } + } + foreach ($dataToInsert as $_data) { + $this->_getWriteAdapter()->insert($this->getTable('downloadable/link_price'), $_data); + } } } return $this; diff --git a/app/code/core/Mage/Downloadable/Model/Observer.php b/app/code/core/Mage/Downloadable/Model/Observer.php index d62f69ec29..9d11ce4e02 100644 --- a/app/code/core/Mage/Downloadable/Model/Observer.php +++ b/app/code/core/Mage/Downloadable/Model/Observer.php @@ -164,11 +164,12 @@ public function setLinkStatus($observer) } elseif ($order->getState() == Mage_Sales_Model_Order::STATE_PENDING_PAYMENT) { $status = Mage_Downloadable_Model_Link_Purchased_Item::LINK_STATUS_PENDING_PAYMENT; } else { + $availableStatuses = array($orderItemStatusToEnable, Mage_Sales_Model_Order_Item::STATUS_INVOICED); foreach ($order->getAllItems() as $item) { if ($item->getProductType() == Mage_Downloadable_Model_Product_Type::TYPE_DOWNLOADABLE || $item->getRealProductType() == Mage_Downloadable_Model_Product_Type::TYPE_DOWNLOADABLE) { - if ($item->getStatusId() == $orderItemStatusToEnable) { + if (in_array($item->getStatusId(), $availableStatuses)) { $orderItemsIds[] = $item->getId(); } } diff --git a/app/code/core/Mage/Downloadable/Model/Product/Type.php b/app/code/core/Mage/Downloadable/Model/Product/Type.php index c0a5fcf12f..3dac7c132c 100644 --- a/app/code/core/Mage/Downloadable/Model/Product/Type.php +++ b/app/code/core/Mage/Downloadable/Model/Product/Type.php @@ -171,7 +171,7 @@ public function save($product = null) $sampleModel = Mage::getModel('downloadable/sample'); $files = array(); if (isset($sampleItem['file'])) { - $files = Zend_Json::decode($sampleItem['file']); + $files = Mage::helper('core')->jsonDecode($sampleItem['file']); unset($sampleItem['file']); } @@ -209,7 +209,7 @@ public function save($product = null) } $files = array(); if (isset($linkItem['file'])) { - $files = Zend_Json::decode($linkItem['file']); + $files = Mage::helper('core')->jsonDecode($linkItem['file']); unset($linkItem['file']); } $sample = array(); @@ -222,7 +222,8 @@ public function save($product = null) ->setLinkType($linkItem['type']) ->setProductId($product->getId()) ->setStoreId($product->getStoreId()) - ->setWebsiteId($product->getStore()->getWebsiteId()); + ->setWebsiteId($product->getStore()->getWebsiteId()) + ->setProductWebsiteIds($product->getWebsiteIds()); if (null === $linkModel->getPrice()) { $linkModel->setPrice(0); } @@ -235,7 +236,7 @@ public function save($product = null) $linkModel->setSampleUrl($sample['url']); } $linkModel->setSampleType($sample['type']); - $sampleFile = Zend_Json::decode($sample['file']); + $sampleFile = Mage::helper('core')->jsonDecode($sample['file']); } if ($linkModel->getLinkType() == Mage_Downloadable_Helper_Download::LINK_TYPE_FILE) { $linkFileName = Mage::helper('downloadable/file')->moveFileFromTmp( diff --git a/app/code/core/Mage/Downloadable/controllers/FileController.php b/app/code/core/Mage/Downloadable/controllers/FileController.php index 30464a1f81..faf0a6085d 100644 --- a/app/code/core/Mage/Downloadable/controllers/FileController.php +++ b/app/code/core/Mage/Downloadable/controllers/FileController.php @@ -65,7 +65,7 @@ public function uploadAction() $result = array('error'=>$e->getMessage(), 'errorcode'=>$e->getCode()); } - $this->getResponse()->setBody(Zend_Json::encode($result)); + $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result)); } /** diff --git a/app/code/core/Mage/Downloadable/etc/config.xml b/app/code/core/Mage/Downloadable/etc/config.xml index 3ed7b20b9a..62bf6b870d 100644 --- a/app/code/core/Mage/Downloadable/etc/config.xml +++ b/app/code/core/Mage/Downloadable/etc/config.xml @@ -28,7 +28,7 @@ - 0.1.14 + 0.1.15 diff --git a/app/code/core/Mage/Downloadable/sql/downloadable_setup/mysql4-install-0.1.0.php b/app/code/core/Mage/Downloadable/sql/downloadable_setup/mysql4-install-0.1.0.php index f925f7ee52..586a691c90 100644 --- a/app/code/core/Mage/Downloadable/sql/downloadable_setup/mysql4-install-0.1.0.php +++ b/app/code/core/Mage/Downloadable/sql/downloadable_setup/mysql4-install-0.1.0.php @@ -43,7 +43,7 @@ // make these attributes applicable to downloadable products foreach ($fieldList as $field) { - $applyTo = split(',', $installer->getAttribute('catalog_product', $field, 'apply_to')); + $applyTo = explode(',', $installer->getAttribute('catalog_product', $field, 'apply_to')); if (!in_array('downloadable', $applyTo)) { $applyTo[] = 'downloadable'; $installer->updateAttribute('catalog_product', $field, 'apply_to', join(',', $applyTo)); diff --git a/app/code/core/Mage/Downloadable/sql/downloadable_setup/mysql4-upgrade-0.1.0-0.1.1.php b/app/code/core/Mage/Downloadable/sql/downloadable_setup/mysql4-upgrade-0.1.0-0.1.1.php index d89ea5fd76..4105ff3b9f 100644 --- a/app/code/core/Mage/Downloadable/sql/downloadable_setup/mysql4-upgrade-0.1.0-0.1.1.php +++ b/app/code/core/Mage/Downloadable/sql/downloadable_setup/mysql4-upgrade-0.1.0-0.1.1.php @@ -29,7 +29,7 @@ $installer->startSetup(); // make attribute 'weight' not applicable to downloadable products -$applyTo = split(',', $installer->getAttribute('catalog_product', 'weight', 'apply_to')); +$applyTo = explode(',', $installer->getAttribute('catalog_product', 'weight', 'apply_to')); if (in_array('downloadable', $applyTo)) { $newApplyTo = array(); foreach ($applyTo as $key=>$value) { diff --git a/app/code/core/Mage/Eav/Model/Convert/Adapter/Entity.php b/app/code/core/Mage/Eav/Model/Convert/Adapter/Entity.php index 7fc9312017..82c0614f5b 100644 --- a/app/code/core/Mage/Eav/Model/Convert/Adapter/Entity.php +++ b/app/code/core/Mage/Eav/Model/Convert/Adapter/Entity.php @@ -104,7 +104,7 @@ public function setFilter($attrFilterArray, $attrToDb = null, $bind = null, $joi if ($type == 'dateFromTo' || $type == 'datetimeFromTo') { foreach ($filters as $k => $v) { if (strpos($k, $key . '/') === 0) { - $split = split('/', $k); + $split = explode('/', $k); $filters[$key][$split[1]] = $v; } } diff --git a/app/code/core/Mage/Eav/Model/Entity/Attribute.php b/app/code/core/Mage/Eav/Model/Entity/Attribute.php index 276c44c963..16768b743f 100644 --- a/app/code/core/Mage/Eav/Model/Entity/Attribute.php +++ b/app/code/core/Mage/Eav/Model/Entity/Attribute.php @@ -124,7 +124,12 @@ protected function _beforeSave() // save default date value as timestamp if ($defaultValue = $this->getDefaultValue()) { $format = Mage::app()->getLocale()->getDateFormat(Mage_Core_Model_Locale::FORMAT_TYPE_SHORT); - $this->setDefaultValue(Mage::app()->getLocale()->date($defaultValue, $format, null, false)->toValue()); + try { + $defaultValue = Mage::app()->getLocale()->date($defaultValue, $format, null, false)->toValue(); + $this->setDefaultValue($defaultValue); + } catch (Exception $e) { + throw new Exception("Invalid default date."); + } } } diff --git a/app/code/core/Mage/Eav/Model/Entity/Attribute/Source/Abstract.php b/app/code/core/Mage/Eav/Model/Entity/Attribute/Source/Abstract.php index c9e04e535d..366e9540ef 100644 --- a/app/code/core/Mage/Eav/Model/Entity/Attribute/Source/Abstract.php +++ b/app/code/core/Mage/Eav/Model/Entity/Attribute/Source/Abstract.php @@ -82,7 +82,7 @@ public function getOptionText($value) // Fixed for tax_class_id and custom_design if (sizeof($options) > 0) foreach($options as $option) { if (isset($option['value']) && $option['value'] == $value) { - return $option; + return isset($option['label']) ? $option['label'] : $option['value']; } } // End if (isset($options[$value])) { diff --git a/app/code/core/Mage/Eav/Model/Entity/Attribute/Source/Table.php b/app/code/core/Mage/Eav/Model/Entity/Attribute/Source/Table.php index 1468ce692a..a7f7f19c1d 100644 --- a/app/code/core/Mage/Eav/Model/Entity/Attribute/Source/Table.php +++ b/app/code/core/Mage/Eav/Model/Entity/Attribute/Source/Table.php @@ -146,14 +146,16 @@ public function addValueSortToCollection($collection, $dir = 'asc') public function getFlatColums() { $columns = array(); + $isMulti = $this->getAttribute()->getFrontend()->getInputType() == 'multiselect'; $columns[$this->getAttribute()->getAttributeCode()] = array( - 'type' => 'int', + 'type' => $isMulti ? 'varchar(255)' : 'int', 'unsigned' => false, 'is_null' => true, 'default' => null, 'extra' => null ); - if ($this->getAttribute()->getFrontend()->getInputType() != 'multiselect') { + + if (!$isMulti) { $columns[$this->getAttribute()->getAttributeCode() . '_value'] = array( 'type' => 'varchar(255)', 'unsigned' => false, diff --git a/app/code/core/Mage/Eav/Model/Entity/Collection/Abstract.php b/app/code/core/Mage/Eav/Model/Entity/Collection/Abstract.php index 3409eb60b8..d07c367406 100644 --- a/app/code/core/Mage/Eav/Model/Entity/Collection/Abstract.php +++ b/app/code/core/Mage/Eav/Model/Entity/Collection/Abstract.php @@ -673,7 +673,7 @@ public function joinField($alias, $table, $field, $bind, $cond=null, $joinType=' /** * Join a table * - * @param string $table + * @param string|array $table * @param string $bind * @param string|array $fields * @param null|array $cond @@ -682,11 +682,21 @@ public function joinField($alias, $table, $field, $bind, $cond=null, $joinType=' */ public function joinTable($table, $bind, $fields=null, $cond=null, $joinType='inner') { + $tableAlias = null; + if (is_array($table)) { + list($tableAlias, $tableName) = each($table); + } + else { + $tableName = $table; + } + // validate table - if (strpos($table, '/')!==false) { - $table = Mage::getSingleton('core/resource')->getTableName($table); + if (strpos($tableName, '/') !== false) { + $tableName = Mage::getSingleton('core/resource')->getTableName($tableName); + } + if (empty($tableAlias)) { + $tableAlias = $tableName; } - $tableAlias = $table; // validate fields and aliases if (!$fields) { @@ -697,14 +707,14 @@ public function joinTable($table, $bind, $fields=null, $cond=null, $joinType='in throw Mage::exception('Mage_Eav', Mage::helper('eav')->__('Joined field with this alias (%s) is already declared', $alias)); } $this->_joinFields[$alias] = array( - 'table'=>$tableAlias, - 'field'=>$field, + 'table' => $tableAlias, + 'field' => $field, ); } // validate bind list($pk, $fk) = explode('=', $bind); - $bindCond = $tableAlias.'.'.$pk.'='.$this->_getAttributeFieldName($fk); + $bindCond = $tableAlias . '.' . $pk . '=' . $this->_getAttributeFieldName($fk); // process join type switch ($joinType) { @@ -730,7 +740,7 @@ public function joinTable($table, $bind, $fields=null, $cond=null, $joinType='in $cond = '('.join(') AND (', $condArr).')'; // join table - $this->getSelect()->$joinMethod(array($tableAlias=>$table), $cond, $fields); + $this->getSelect()->$joinMethod(array($tableAlias => $tableName), $cond, $fields); return $this; } diff --git a/app/code/core/Mage/Eav/Model/Mysql4/Entity/Attribute.php b/app/code/core/Mage/Eav/Model/Mysql4/Entity/Attribute.php index 29411a72e5..2c54c658a8 100644 --- a/app/code/core/Mage/Eav/Model/Mysql4/Entity/Attribute.php +++ b/app/code/core/Mage/Eav/Model/Mysql4/Entity/Attribute.php @@ -428,5 +428,4 @@ public function getFlatUpdateSelect(Mage_Eav_Model_Entity_Attribute_Abstract $at public function describeTable($table) { return $this->_getReadAdapter()->describeTable($table); } - } diff --git a/app/code/core/Mage/Eav/Model/Mysql4/Entity/Attribute/Collection.php b/app/code/core/Mage/Eav/Model/Mysql4/Entity/Attribute/Collection.php index 7c5e887991..064c1ab469 100644 --- a/app/code/core/Mage/Eav/Model/Mysql4/Entity/Attribute/Collection.php +++ b/app/code/core/Mage/Eav/Model/Mysql4/Entity/Attribute/Collection.php @@ -370,32 +370,18 @@ protected function _addSetInfo() protected function _afterLoadData() { $this->_addSetInfo(); + return parent::_afterLoadData(); } /** - * TODO: issue #5126 + * Load is used in configurable products flag * - * @return unknown + * @deprecated + * @return Mage_Eav_Model_Mysql4_Entity_Attribute_Collection */ public function checkConfigurableProducts() { -// was: -/* -SELECT `main_table`.*, `entity_attribute`.* -FROM `eav_attribute` AS `main_table` - INNER JOIN `eav_entity_attribute` AS `entity_attribute` ON entity_attribute.attribute_id=main_table.attribute_id -WHERE (entity_attribute.attribute_group_id='46') AND (main_table.is_visible=1) -*/ -// to be done: left join catalog_product_super_attribute and count appropriate lines -/* -SELECT `main_table`.*, `entity_attribute`.*, COUNT(`super`.attribute_id) AS `is_used_in_configurable` -FROM `eav_attribute` AS `main_table` - INNER JOIN `eav_entity_attribute` AS `entity_attribute` ON entity_attribute.attribute_id=main_table.attribute_id - LEFT JOIN `catalog_product_super_attribute` AS `super` ON `main_table`.attribute_id=`super`.attribute_id -WHERE (entity_attribute.attribute_group_id='46') AND (main_table.is_visible=1) -GROUP BY `main_table`.attribute_id -*/ return $this; } diff --git a/app/code/core/Mage/Giftcert/Helper/Data.php b/app/code/core/Mage/Giftcert/Helper/Data.php deleted file mode 100644 index 3dd65199c4..0000000000 --- a/app/code/core/Mage/Giftcert/Helper/Data.php +++ /dev/null @@ -1,33 +0,0 @@ -getGiftcertByCode($address->getGiftcertCode()); - if ($gift) { - $address->setGiftcertAmount(min($address->getGrandTotal(), $gift['balance_amount'])); - } else { - $address->setGiftcertAmount(0); - } - - $address->setGrandTotal($address->getGrandTotal() - $address->getGiftcertAmount()); - - return $this; - } - -} diff --git a/app/code/core/Mage/Giftcert/Model/Entity/Quote/Address/Attribute/Frontend/Giftcert.php b/app/code/core/Mage/Giftcert/Model/Entity/Quote/Address/Attribute/Frontend/Giftcert.php deleted file mode 100644 index 2202a70f72..0000000000 --- a/app/code/core/Mage/Giftcert/Model/Entity/Quote/Address/Attribute/Frontend/Giftcert.php +++ /dev/null @@ -1,39 +0,0 @@ -getGiftcertAmount(); - if ($amount) { - $address->addTotal(array('code'=>'giftcert', 'title'=>Mage::helper('giftcert')->__('Gift Certificate').' ('.$address->getGiftcertCode().')', 'value'=>-$amount, 'output'=>true)); - } - return $this; - } -} diff --git a/app/code/core/Mage/Giftcert/Model/Mysql4/Giftcert.php b/app/code/core/Mage/Giftcert/Model/Mysql4/Giftcert.php deleted file mode 100644 index 57431357f8..0000000000 --- a/app/code/core/Mage/Giftcert/Model/Mysql4/Giftcert.php +++ /dev/null @@ -1,45 +0,0 @@ -_read = Mage::getSingleton('core/resource')->getConnection('sales_read'); - $this->_write = Mage::getSingleton('core/resource')->getConnection('sales_write'); - } - - public function getGiftcertByCode($giftCode) - { - $giftTable = Mage::getSingleton('core/resource')->getTableName('sales/giftcert'); - $result = $this->_read->fetchRow("select * from ".$giftTable." where giftcert_code=?", $giftCode); - return $result; - } -} \ No newline at end of file diff --git a/app/code/core/Mage/Giftcert/etc/config.xml b/app/code/core/Mage/Giftcert/etc/config.xml deleted file mode 100644 index 2af7bc11d3..0000000000 --- a/app/code/core/Mage/Giftcert/etc/config.xml +++ /dev/null @@ -1,94 +0,0 @@ - - - - - - 0.7.0 - - - - - - Mage_Giftcert_Model - giftcert_mysql4 - - - Mage_Giftcert_Model_Mysql4 - - - giftcert_code
    -
    -
    -
    -
    - - - - Mage_Giftcert - - - core_setup - - - - - core_write - - - - - core_read - - - -
    - - - - - - - Mage_Giftcert.csv - - - - - - - - - - - - Mage_Giftcert.csv - - - - - -
    \ No newline at end of file diff --git a/app/code/core/Mage/Giftcert/sql/giftcert_setup/mysql4-install-0.7.0.php b/app/code/core/Mage/Giftcert/sql/giftcert_setup/mysql4-install-0.7.0.php deleted file mode 100644 index 008888af89..0000000000 --- a/app/code/core/Mage/Giftcert/sql/giftcert_setup/mysql4-install-0.7.0.php +++ /dev/null @@ -1,51 +0,0 @@ -startSetup(); - -$installer->run(" - --- drop table if exists {$this->getTable('sales_counter')}; --- drop table if exists {$this->getTable('sales_discount_coupon')}; --- DROP TABLE IF EXISTS {$this->getTable('sales_giftcert')}; - --- DROP TABLE IF EXISTS {$this->getTable('giftcert_code')}; -CREATE TABLE {$this->getTable('giftcert_code')} ( - `giftcert_id` int(10) unsigned NOT NULL auto_increment, - `giftcert_code` varchar(50) NOT NULL default '', - `balance_amount` decimal(12,4) NOT NULL default '0.0000', - PRIMARY KEY (`giftcert_id`), - UNIQUE KEY `gift_code` (`giftcert_code`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -insert into {$this->getTable('giftcert_code')} (`giftcert_id`,`giftcert_code`,`balance_amount`) values (1,'test',20.0000); - - "); - -$installer->endSetup(); diff --git a/app/code/core/Mage/GoogleBase/Block/Adminhtml/Types/Edit/Attributes.php b/app/code/core/Mage/GoogleBase/Block/Adminhtml/Types/Edit/Attributes.php index be3c861ff9..501edcfea4 100644 --- a/app/code/core/Mage/GoogleBase/Block/Adminhtml/Types/Edit/Attributes.php +++ b/app/code/core/Mage/GoogleBase/Block/Adminhtml/Types/Edit/Attributes.php @@ -135,6 +135,6 @@ public function _getAttributes($setId, $escapeJsQuotes = false) protected function _toJson($data) { - return Zend_Json::encode($data); + return Mage::helper('core')->jsonEncode($data); } } \ No newline at end of file diff --git a/app/code/core/Mage/GoogleCheckout/Model/Api/Xml/Abstract.php b/app/code/core/Mage/GoogleCheckout/Model/Api/Xml/Abstract.php index 04760fb402..f48e322303 100644 --- a/app/code/core/Mage/GoogleCheckout/Model/Api/Xml/Abstract.php +++ b/app/code/core/Mage/GoogleCheckout/Model/Api/Xml/Abstract.php @@ -200,4 +200,19 @@ protected function _getCallbackUrl() { return Mage::getUrl('googlecheckout/api', array('_forced_secure'=>Mage::getStoreConfig('google/checkout/use_secure_callback_url', $this->getStoreId()))); } + + /** + * Recalculate amount to store currency + * + * @param float $amount + * @param Mage_Sales_Model_Quote $quote + * @return float + */ + protected function _reCalculateToStoreCurrency($amount, $quote) + { + if ($quote->getQuoteCurrencyCode() != $quote->getBaseCurrencyCode()) { + $amount = $amount * $quote->getStoreToQuoteRate(); + } + return $amount; + } } diff --git a/app/code/core/Mage/GoogleCheckout/Model/Api/Xml/Callback.php b/app/code/core/Mage/GoogleCheckout/Model/Api/Xml/Callback.php index ab1432e718..042f85d94b 100644 --- a/app/code/core/Mage/GoogleCheckout/Model/Api/Xml/Callback.php +++ b/app/code/core/Mage/GoogleCheckout/Model/Api/Xml/Callback.php @@ -234,8 +234,8 @@ protected function _responseMerchantCalculationCallback() $address->setCollectShippingRates(true)->collectTotals(); $billingAddress->setCollectShippingRates(true)->collectTotals(); - $taxAmount = $address->getTaxAmount(); - $taxAmount += $billingAddress->getTaxAmount(); + $taxAmount = $address->getBaseTaxAmount(); + $taxAmount += $billingAddress->getBaseTaxAmount(); $result->setTaxDetails($taxAmount); } @@ -250,8 +250,8 @@ protected function _responseMerchantCalculationCallback() $address->setCollectShippingRates(true)->collectTotals(); $billingAddress->setCollectShippingRates(true)->collectTotals(); - $taxAmount = $address->getTaxAmount(); - $taxAmount += $billingAddress->getTaxAmount(); + $taxAmount = $address->getBaseTaxAmount(); + $taxAmount += $billingAddress->getBaseTaxAmount(); $result = new GoogleResult($addressId); $result->setTaxDetails($taxAmount); @@ -278,7 +278,7 @@ protected function _responseNewOrderNotification() // IMPORT GOOGLE ORDER DATA INTO QUOTE $quoteId = $this->getData('root/shopping-cart/merchant-private-data/quote-id/VALUE'); - $quote = Mage::getModel('sales/quote')->load($quoteId); + $quote = Mage::getModel('sales/quote')->load($quoteId)->setIsActive(true); // // $quoteItems = $quote->getItemsCollection(); // foreach ($this->getData('root/shopping-cart/items') as $item) { @@ -373,6 +373,8 @@ protected function _responseNewOrderNotification() ->setLastSuccessQuoteId($quote->getId()) ->setLastRealOrderId($order->getIncrementId()); + $quote->setIsActive(false)->save(); + if ($emailAllowed) { Mage::getModel('newsletter/subscriber')->subscribe($order->getCustomerEmail()); } @@ -427,7 +429,11 @@ protected function _importGoogleAddress($gAddress, Varien_Object $qAddress=null) protected function _importGoogleTotals($qAddress) { - $qAddress->setTaxAmount($this->getData('root/order-adjustment/total-tax/VALUE')); + $qAddress->setTaxAmount( + $this->_reCalculateToStoreCurrency( + $this->getData('root/order-adjustment/total-tax/VALUE'), $qAddress->getQuote() + ) + ); $qAddress->setBaseTaxAmount($this->getData('root/order-adjustment/total-tax/VALUE')); $prefix = 'root/order-adjustment/shipping/'; @@ -444,13 +450,18 @@ protected function _importGoogleTotals($qAddress) $excludingTax = $shipping['shipping-cost']['VALUE']; $qAddress->setShippingMethod($method) ->setShippingDescription($shipping['shipping-name']['VALUE']) - ->setShippingAmount($excludingTax, true) + ->setShippingAmount( + $this->_reCalculateToStoreCurrency($excludingTax, $qAddress->getQuote()), + true + ) ->setBaseShippingAmount($excludingTax, true); if (!Mage::helper('tax')->shippingPriceIncludesTax()) { $includingTax = Mage::helper('tax')->getShippingPrice($excludingTax, true, $qAddress, $qAddress->getQuote()->getCustomerTaxClassId()); $shippingTax = $includingTax - $excludingTax; - $qAddress->setShippingTaxAmount($shippingTax) + $qAddress->setShippingTaxAmount( + $this->_reCalculateToStoreCurrency($shippingTax, $qAddress->getQuote()) + ) ->setBaseShippingTaxAmount($shippingTax); } else { if ($method == 'googlecheckout_carrier') { @@ -463,7 +474,11 @@ protected function _importGoogleTotals($qAddress) } - $qAddress->setGrandTotal($this->getData('root/order-total/VALUE')); + $qAddress->setGrandTotal( + $this->_reCalculateToStoreCurrency( + $this->getData('root/order-total/VALUE'), $qAddress->getQuote() + ) + ); $qAddress->setBaseGrandTotal($this->getData('root/order-total/VALUE')); } diff --git a/app/code/core/Mage/GoogleCheckout/controllers/RedirectController.php b/app/code/core/Mage/GoogleCheckout/controllers/RedirectController.php index 2bef1fdc70..8c38ef5a6d 100644 --- a/app/code/core/Mage/GoogleCheckout/controllers/RedirectController.php +++ b/app/code/core/Mage/GoogleCheckout/controllers/RedirectController.php @@ -31,7 +31,6 @@ */ class Mage_GoogleCheckout_RedirectController extends Mage_Core_Controller_Front_Action { - /** * Send request to Google Checkout and return Responce Api * @@ -59,7 +58,6 @@ protected function _getApi () $baseCurrency = $session->getQuote()->getBaseCurrencyCode(); $currency = Mage::app()->getStore($session->getQuote()->getStoreId())->getBaseCurrency(); $session->getQuote() - ->setForcedCurrency($currency) ->collectTotals() ->save(); @@ -71,6 +69,8 @@ protected function _getApi () if ($api->getError()) { Mage::getSingleton('checkout/session')->addError($api->getError()); } else { + $oldQuote = $session->getQuote(); + $oldQuote->setIsActive(false)->save(); $session->replaceQuote($storeQuote); Mage::getModel('checkout/cart')->init()->save(); if (Mage::getStoreConfigFlag('google/checkout/hide_cart_contents')) { @@ -134,12 +134,12 @@ public function continueAction() if ($quoteId = $session->getGoogleCheckoutQuoteId()) { $quote = Mage::getModel('sales/quote')->load($quoteId) ->setIsActive(false)->save(); - $session->unsQuoteId(); + $session->clear(); } -// if (Mage::getStoreConfigFlag('google/checkout/hide_cart_contents')) { -// $session->unsGoogleCheckoutQuoteId(); -// } + if (Mage::getStoreConfigFlag('google/checkout/hide_cart_contents')) { + $session->setGoogleCheckoutQuoteId(null); + } $url = Mage::getStoreConfig('google/checkout/continue_shopping_url'); if (empty($url)) { diff --git a/app/code/core/Mage/GoogleOptimizer/controllers/IndexController.php b/app/code/core/Mage/GoogleOptimizer/controllers/IndexController.php index 33ad40df3a..9db3cc4fa0 100644 --- a/app/code/core/Mage/GoogleOptimizer/controllers/IndexController.php +++ b/app/code/core/Mage/GoogleOptimizer/controllers/IndexController.php @@ -51,7 +51,7 @@ public function codesAction() $result[$id] = $code; } } - $this->getResponse()->setBody( Zend_Json::encode($result) ); + $this->getResponse()->setBody( Mage::helper('core')->jsonEncode($result) ); } } } \ No newline at end of file diff --git a/app/code/core/Mage/Install/Model/Installer.php b/app/code/core/Mage/Install/Model/Installer.php index 306a2d2563..15aa7b8485 100644 --- a/app/code/core/Mage/Install/Model/Installer.php +++ b/app/code/core/Mage/Install/Model/Installer.php @@ -205,10 +205,35 @@ public function installDb() } /** - * Create admin user + * Prepare admin user data in model and validate it. + * Returns TRUE or array of error messages. * * @param array $data - * @return Mage_Install_Model_Installer + * @return mixed + */ + public function validateAndPrepareAdministrator($data) + { + $user = Mage::getModel('admin/user') + ->load($data['username'], 'username'); + $user->addData($data); + + $result = $user->validate(); + if (is_array($result)) { + foreach ($result as $error) { + $this->getDataModel()->addError($error); + } + return $result; + } + return $user; + } + + /** + * Create admin user. + * Paramater can be prepared user model or array of data. + * Returns TRUE or throws exception. + * + * @param mixed $data + * @return bool */ public function createAdministrator($data) { @@ -218,17 +243,53 @@ public function createAdministrator($data) $user->delete(); } - $user = Mage::getModel('admin/user') - ->load($data['username'], 'username'); - $user->addData($data)->save(); - $user->setRoleIds(array(1))->saveRelations(); + //to support old logic checking if real data was passed + if (is_array($data)) { + $data = $this->validateAndPrepareAdministrator($data); + if (is_array(data)) { + throw new Exception(Mage::helper('install')->__('Please correct user data and try again.')); + } + } + + //run time flag to force saving entered password + $data->setForceNewPassword(true); + + $data->save(); + $data->setRoleIds(array(1))->saveRelations(); /*Mage::getModel("permissions/user")->setRoleId(1) ->setUserId($user->getId()) ->setFirstname($user->getFirstname()) ->add();*/ - return $this; + return true; + } + + /** + * Validating encryption key. + * Returns TRUE or array of error messages. + * + * @param $key + * @return unknown_type + */ + public function validateEncryptionKey($key) + { + $errors = array(); + + try { + if ($key) { + Mage::helper('core')->validateKey($key); + } + } catch (Exception $e) { + $errors[] = $e->getMessage(); + $this->getDataModel()->addError($e->getMessage()); + } + + if (!empty($errors)) { + return $errors; + } + + return true; } /** diff --git a/app/code/core/Mage/Install/Model/Installer/Console.php b/app/code/core/Mage/Install/Model/Installer/Console.php index 05c313d788..c5218d8ac7 100644 --- a/app/code/core/Mage/Install/Model/Installer/Console.php +++ b/app/code/core/Mage/Install/Model/Installer/Console.php @@ -308,7 +308,7 @@ protected function _prepareData() 'lastname' => $this->_args['admin_lastname'], 'email' => $this->_args['admin_email'], 'username' => $this->_args['admin_username'], - 'password' => $this->_args['admin_password'], + 'new_password' => $this->_args['admin_password'], )); return $this; @@ -374,19 +374,37 @@ public function install() } /** - * Create primary administrator user + * Validate entered data for administrator user */ - $installer->createAdministrator($this->_getDataModel()->getAdminData()); + $user = $installer->validateAndPrepareAdministrator($this->_getDataModel()->getAdminData()); if ($this->hasErrors()) { return false; } /** - * Save encryption key or create if empty + * Prepare encryption key and validate it */ $encryptionKey = empty($this->_args['encryption_key']) ? md5(time()) : $this->_args['encryption_key']; $this->_getDataModel()->setEncryptionKey($encryptionKey); + $installer->validateEncryptionKey($encryptionKey); + + if ($this->hasErrors()) { + return false; + } + + /** + * Create primary administrator user + */ + $installer->createAdministrator($user); + + if ($this->hasErrors()) { + return false; + } + + /** + * Save encryption key or create if empty + */ $installer->installEnryptionKey($encryptionKey); if ($this->hasErrors()) { diff --git a/app/code/core/Mage/Install/controllers/WizardController.php b/app/code/core/Mage/Install/controllers/WizardController.php index 1472dbc661..6ee51b91e1 100644 --- a/app/code/core/Mage/Install/controllers/WizardController.php +++ b/app/code/core/Mage/Install/controllers/WizardController.php @@ -384,11 +384,30 @@ public function administratorPostAction() $adminData = $this->getRequest()->getPost('admin'); $encryptionKey = $this->getRequest()->getPost('encryption_key'); - try { - $this->_getInstaller()->createAdministrator($adminData) - ->installEnryptionKey($encryptionKey); + $errors = array(); + + //preparing admin user model with data and validate it + $user = $this->_getInstaller()->validateAndPrepareAdministrator($adminData); + if (is_array($user)) { + $errors = $user; } - catch (Exception $e){ + + //checking if valid encryption key was entered + $result = $this->_getInstaller()->validateEncryptionKey($encryptionKey); + if (is_array($result)) { + $errors = array_merge($errors, $result); + } + + if (!empty($errors)) { + Mage::getSingleton('install/session')->setAdminData($adminData); + $this->getResponse()->setRedirect($step->getUrl()); + return false; + } + + try { + $this->_getInstaller()->createAdministrator($user); + $this->_getInstaller()->installEnryptionKey($encryptionKey); + } catch (Exception $e){ Mage::getSingleton('install/session') ->setAdminData($adminData) ->addError($e->getMessage()); diff --git a/app/code/core/Mage/Paygate/Model/Authorizenet.php b/app/code/core/Mage/Paygate/Model/Authorizenet.php index ea1298c895..361c78afe8 100644 --- a/app/code/core/Mage/Paygate/Model/Authorizenet.php +++ b/app/code/core/Mage/Paygate/Model/Authorizenet.php @@ -102,53 +102,49 @@ public function canUseForCurrency($currencyCode) /** * Send authorize request to gateway * - * @param Varien_Object $payment - * @param decimal $amount - * @return Mage_Paygate_Model_Authorizenet + * @param Varien_Object $payment + * @param decimal $amount + * @return Mage_Paygate_Model_Authorizenet + * @throws Mage_Core_Exception */ public function authorize(Varien_Object $payment, $amount) { - $error = false; - - if($amount>0){ - $payment->setAnetTransType(self::REQUEST_TYPE_AUTH_ONLY); - $payment->setAmount($amount); - - $request= $this->_buildRequest($payment); - $result = $this->_postRequest($request); - - $payment->setCcApproval($result->getApprovalCode()) - ->setLastTransId($result->getTransactionId()) - ->setCcTransId($result->getTransactionId()) - ->setCcAvsStatus($result->getAvsResultCode()) - ->setCcCidStatus($result->getCardCodeResponseCode()); - - switch ($result->getResponseCode()) { - case self::RESPONSE_CODE_APPROVED: - $payment->setStatus(self::STATUS_APPROVED); - break; - case self::RESPONSE_CODE_DECLINED: - $error = Mage::helper('paygate')->__('Payment authorization transaction has been declined.'); - break; - default: - $error = Mage::helper('paygate')->__('Payment authorization error.'); - break; - } - }else{ - $error = Mage::helper('paygate')->__('Invalid amount for authorization.'); + if ($amount <= 0) { + Mage::throwException(Mage::helper('paygate')->__('Invalid amount for authorization.')); } + $payment->setAnetTransType(self::REQUEST_TYPE_AUTH_ONLY); + $payment->setAmount($amount); + + $request= $this->_buildRequest($payment); + $result = $this->_postRequest($request); - if ($error !== false) { - Mage::throwException($error); + $payment->setCcApproval($result->getApprovalCode()) + ->setLastTransId($result->getTransactionId()) + ->setCcTransId($result->getTransactionId()) + ->setCcAvsStatus($result->getAvsResultCode()) + ->setCcCidStatus($result->getCardCodeResponseCode()); + + switch ($result->getResponseCode()) { + case self::RESPONSE_CODE_APPROVED: + $payment->setStatus(self::STATUS_APPROVED); + return $this; + case self::RESPONSE_CODE_DECLINED: + Mage::throwException(Mage::helper('paygate')->__('Payment authorization transaction has been declined.')); + default: + Mage::throwException(Mage::helper('paygate')->__('Payment authorization error.')); } - return $this; } - + /** + * Send capture request to gateway + * + * @param Varien_Object $payment + * @param decimal $amount + * @return Mage_Paygate_Model_Authorizenet + * @throws Mage_Core_Exception + */ public function capture(Varien_Object $payment, $amount) { - $error = false; - if ($payment->getCcTransId()) { $payment->setAnetTransType(self::REQUEST_TYPE_PRIOR_AUTH_CAPTURE); } else { @@ -164,68 +160,50 @@ public function capture(Varien_Object $payment, $amount) $payment->setStatus(self::STATUS_APPROVED); //$payment->setCcTransId($result->getTransactionId()); $payment->setLastTransId($result->getTransactionId()); + return $this; } - else { - if ($result->getResponseReasonText()) { - $error = $result->getResponseReasonText(); - } - else { - $error = Mage::helper('paygate')->__('Error in capturing the payment'); - } - } - - if ($error !== false) { - Mage::throwException($error); + if ($result->getResponseReasonText()) { + Mage::throwException($this->_wrapGatewayError($result->getResponseReasonText())); } - - return $this; + Mage::throwException(Mage::helper('paygate')->__('Error in capturing the payment')); } /** - * void + * Void the payment through gateway * - * @author Magento Core Team - * @access public - * @param string $payment Varien_Object object - * @return Mage_Payment_Model_Abstract + * @param Varien_Object $payment + * @return Mage_Paygate_Model_Authorizenet + * @throws Mage_Core_Exception */ public function void(Varien_Object $payment) { - $error = false; - if($payment->getVoidTransactionId()){ + if ($payment->getVoidTransactionId()) { $payment->setAnetTransType(self::REQUEST_TYPE_VOID); $request = $this->_buildRequest($payment); $request->setXTransId($payment->getVoidTransactionId()); $result = $this->_postRequest($request); - if($result->getResponseCode()==self::RESPONSE_CODE_APPROVED){ + if ($result->getResponseCode()==self::RESPONSE_CODE_APPROVED) { $payment->setStatus(self::STATUS_SUCCESS ); + return $this; } - else{ - $payment->setStatus(self::STATUS_ERROR); - $error = $result->getResponseReasonText(); - } - }else{ $payment->setStatus(self::STATUS_ERROR); - $error = Mage::helper('paygate')->__('Invalid transaction id'); + Mage::throwException($this->_wrapGatewayError($result->getResponseReasonText())); } - if ($error !== false) { - Mage::throwException($error); - } - return $this; + $payment->setStatus(self::STATUS_ERROR); + Mage::throwException(Mage::helper('paygate')->__('Invalid transaction id')); } /** * refund the amount with transaction id * - * @access public * @param string $payment Varien_Object object - * @return Mage_Payment_Model_Abstract + * @return Mage_Paygate_Model_Authorizenet + * @throws Mage_Core_Exception */ public function refund(Varien_Object $payment, $amount) { - $error = false; - if ($payment->getRefundTransactionId() && $amount>0) { + if ($payment->getRefundTransactionId() && $amount > 0) { $payment->setAnetTransType(self::REQUEST_TYPE_CREDIT); $request = $this->_buildRequest($payment); $request->setXTransId($payment->getRefundTransactionId()); @@ -233,18 +211,11 @@ public function refund(Varien_Object $payment, $amount) if ($result->getResponseCode()==self::RESPONSE_CODE_APPROVED) { $payment->setStatus(self::STATUS_SUCCESS); - } else { - $error = $result->getResponseReasonText(); + return $this; } - - } else { - $error = Mage::helper('paygate')->__('Error in refunding the payment'); + Mage::throwException($this->_wrapGatewayError($result->getResponseReasonText())); } - - if ($error !== false) { - Mage::throwException($error); - } - return $this; + Mage::throwException(Mage::helper('paygate')->__('Error in refunding the payment')); } /** @@ -408,9 +379,7 @@ protected function _postRequest(Varien_Object $request) ->setResultDump(print_r($result->getData(),1)) ->save(); } - Mage::throwException( - Mage::helper('paygate')->__('Gateway request error: %s', $e->getMessage()) - ); + Mage::throwException($this->_wrapGatewayError($e->getMessage())); } $responseBody = $response->getBody(); @@ -450,4 +419,15 @@ protected function _postRequest(Varien_Object $request) return $result; } + + /** + * Gateway response wrapper + * + * @param string $text + * @return string + */ + protected function _wrapGatewayError($text) + { + return Mage::helper('paygate')->__('Gateway error: %s', $text); + } } diff --git a/app/code/core/Mage/Paygate/Model/Payflow/Pro.php b/app/code/core/Mage/Paygate/Model/Payflow/Pro.php index 1aaca5cc14..d31aec6a02 100644 --- a/app/code/core/Mage/Paygate/Model/Payflow/Pro.php +++ b/app/code/core/Mage/Paygate/Model/Payflow/Pro.php @@ -129,6 +129,21 @@ public function authorize(Varien_Object $payment, $amount) return $this; } + /** + * Check capture availability + * To avoid capture already voided transactions, allow only one capture thus the method + * cannot make capture partially + * + * @return bool + */ + public function canCapture() + { + if ($this->getInfoInstance()->getOrder()->getBaseSubtotalInvoiced() > 0) { + return false; + } + return true; + } + public function capture(Varien_Object $payment, $amount) { $error = false; diff --git a/app/code/core/Mage/Payment/Model/Info.php b/app/code/core/Mage/Payment/Model/Info.php index d3c01caf95..709ae496cd 100644 --- a/app/code/core/Mage/Payment/Model/Info.php +++ b/app/code/core/Mage/Payment/Model/Info.php @@ -73,7 +73,7 @@ public function getMethodInstance() } else { return $this->_getData('method_instance'); } - Mage::throwException(Mage::helper('payment')->__('Can not retrieve payment method instance')); + Mage::throwException(Mage::helper('payment')->__('Cannot retrieve payment method instance')); } /** diff --git a/app/code/core/Mage/Payment/Model/Method/Cc.php b/app/code/core/Mage/Payment/Model/Method/Cc.php index a7b6c0f822..0311ccbf2d 100644 --- a/app/code/core/Mage/Payment/Model/Method/Cc.php +++ b/app/code/core/Mage/Payment/Model/Method/Cc.php @@ -144,7 +144,7 @@ public function validate() if (!$info->getCcCid() || !$regExp || !preg_match($regExp ,$info->getCcCid())){ $errorMsg = $this->_getHelper()->__('Please enter a valid credit card verification number.'); } - } + } if($errorMsg){ Mage::throwException($errorMsg); @@ -170,7 +170,7 @@ public function getVerificationRegEx() 'MC' => '/^[0-9]{3}$/', // Master Card 'AE' => '/^[0-9]{4}$/', // American Express 'DI' => '/^[0-9]{3}$/', // Discovery - 'SS' => '/^[0-9]{4}$/', + 'SS' => '/^[0-9]{3,4}$/', 'OT' => '/^[0-9]{3,4}$/' ); return $verificationExpList; @@ -184,7 +184,7 @@ protected function _validateExpDate($expYear, $expMonth) } return true; } - + public function OtherCcType($type) { return $type=='OT'; diff --git a/app/code/core/Mage/Paypal/Model/Standard.php b/app/code/core/Mage/Paypal/Model/Standard.php index e77e3d8453..a5c7e2e50a 100644 --- a/app/code/core/Mage/Paypal/Model/Standard.php +++ b/app/code/core/Mage/Paypal/Model/Standard.php @@ -389,12 +389,6 @@ public function ipnPostSubmit() } */ - // get from config order status to be set - $newOrderStatus = $this->getConfigData('order_status', $order->getStoreId()); - if (empty($newOrderStatus)) { - $newOrderStatus = $order->getStatus(); - } - /* if payer_status=verified ==> transaction in sale mode if transactin in sale mode, we need to create an invoice @@ -426,6 +420,10 @@ public function ipnPostSubmit() ); } } else { + $newOrderStatus = $this->getConfigData('order_status', $order->getStoreId()); + if (empty($newOrderStatus)) { + $newOrderStatus = true; + } $order->setState( Mage_Sales_Model_Order::STATE_PROCESSING, $newOrderStatus, Mage::helper('paypal')->__('Received IPN verification'), diff --git a/app/code/core/Mage/PaypalUk/Block/Direct/Form.php b/app/code/core/Mage/PaypalUk/Block/Direct/Form.php index 499054d453..a5c0d36d70 100644 --- a/app/code/core/Mage/PaypalUk/Block/Direct/Form.php +++ b/app/code/core/Mage/PaypalUk/Block/Direct/Form.php @@ -19,26 +19,21 @@ * needs please refer to http://www.magentocommerce.com for more information. * * @category Mage - * @package Mage_Paypal + * @package Mage_PaypalUk * @copyright Copyright (c) 2008 Irubin Consulting Inc. DBA Varien (http://www.varien.com) * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ - +/** + * UK domestic cards specific information block + */ class Mage_PaypalUk_Block_Direct_Form extends Mage_Payment_Block_Form_Cc { - protected function _construct() - { - parent::_construct(); - $this->setTemplate('paypaluk/direct/form.phtml'); - } - protected function _getDirect() { return Mage::getSingleton('paypaluk/direct'); } - /** * Retrieve availables credit card types * @@ -93,4 +88,19 @@ public function hasSsCardType() return false; } + /** + * Add UK domestic cards additional fields as child block + * + * Forks a clone, but with a different form + * + * @return Mage_PaypalUk_Block_Direct_Form + */ + public function _beforeToHtml() + { + $child = clone $this; + $this->setChild('uk_domestic', + $child->setTemplate('paypaluk/direct/form.phtml') + ); + return parent::_beforeToHtml(); + } } \ No newline at end of file diff --git a/app/code/core/Mage/PaypalUk/controllers/ExpressController.php b/app/code/core/Mage/PaypalUk/controllers/ExpressController.php index caff3eacda..858b27d311 100644 --- a/app/code/core/Mage/PaypalUk/controllers/ExpressController.php +++ b/app/code/core/Mage/PaypalUk/controllers/ExpressController.php @@ -71,6 +71,11 @@ public function shortcutAction() $this->getResponse()->setRedirect($this->getExpress()->getRedirectUrl()); } + public function editAction() + { + $this->getResponse()->setRedirect($this->getExpress()->getApi()->getPaypalUrl()); + } + /* * when a user click on cancel on paypal need to redirect them to shopping cart */ diff --git a/app/code/core/Mage/PaypalUk/etc/config.xml b/app/code/core/Mage/PaypalUk/etc/config.xml index 917a58142a..8199705649 100644 --- a/app/code/core/Mage/PaypalUk/etc/config.xml +++ b/app/code/core/Mage/PaypalUk/etc/config.xml @@ -78,7 +78,7 @@ SS - Switch/Solo + Maestro/Solo 40 diff --git a/app/code/core/Mage/Reports/Block/Product/Abstract.php b/app/code/core/Mage/Reports/Block/Product/Abstract.php index 2ab0387f3e..561f956bf8 100644 --- a/app/code/core/Mage/Reports/Block/Product/Abstract.php +++ b/app/code/core/Mage/Reports/Block/Product/Abstract.php @@ -20,20 +20,47 @@ * * @category Mage * @package Mage_Reports - * @copyright Copyright (c) 2008 Irubin Consulting Inc. DBA Varien (http://www.varien.com) + * @copyright Copyright (c) 2009 Irubin Consulting Inc. DBA Varien (http://www.varien.com) * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ + +/** + * Reports Recently Products Abstract Block + * + * @category Mage + * @package Mage_Reports + * @author Magento Core Team + */ abstract class Mage_Reports_Block_Product_Abstract extends Mage_Catalog_Block_Product_Abstract { - protected $_eventTypeId = 0; + /** + * Product Index model name + * + * @var string + */ + protected $_indexName; + + /** + * Product Index model instance + * + * @var Mage_Reports_Model_Product_Index_Abstract + */ + protected $_indexModel; + + /** + * Product Index Collection + * + * @var Mage_Reports_Model_Mysql4_Product_Index_Collection_Abstract + */ + protected $_collection; /** - * Retrieve page size (count) + * Retrieve page size * * @return int */ - protected function getPageSize() + public function getPageSize() { if ($this->hasData('page_size')) { return $this->getData('page_size'); @@ -42,7 +69,8 @@ protected function getPageSize() } /** - * Obtain product ids, that must not be included in collection + * Retrieve product ids, that must not be included in collection + * * @return array */ protected function _getProductsToSkip() @@ -51,36 +79,68 @@ protected function _getProductsToSkip() } /** - * Get products collection and apply recent events log to it + * Retrieve Product Index model instance * - * @return Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection + * @return Mage_Reports_Model_Product_Index_Abstract */ - protected function _getRecentProductsCollection() + protected function _getModel() { - // get products collection and apply status and visibility filter - $collection = $this->_addProductAttributesAndPrices(Mage::getModel('catalog/product')->getCollection()) - ->addAttributeToSelect(Mage::getSingleton('catalog/config')->getProductAttributes()) - ->addUrlRewrite() - ->setPageSize($this->getPageSize()) - ->setCurPage(1) - ; - Mage::getSingleton('catalog/product_status')->addVisibleFilterToCollection($collection); - Mage::getSingleton('catalog/product_visibility')->addVisibleInSiteFilterToCollection($collection); + if (is_null($this->_indexModel)) { + if (is_null($this->_indexName)) { + Mage::throwException(Mage::helper('reports')->__('Index model name must be defined')); + } - // apply events log to collection with required parameters - $skip = $this->_getProductsToSkip(); - $subtype = 0; - if (Mage::getSingleton('customer/session')->isLoggedIn()) { - $subjectId = Mage::getSingleton('customer/session')->getCustomer()->getId(); - } else { - $subjectId = Mage::getSingleton('log/visitor')->getId(); - $subtype = 1; + $this->_indexModel = Mage::getModel($this->_indexName); } - Mage::getResourceSingleton('reports/event')->applyLogToCollection($collection, $this->_eventTypeId, $subjectId, $subtype, $skip); - foreach ($collection as $product) { - $product->setDoNotUseCategoryId(true); + return $this->_indexModel; + } + + /** + * Retrieve Index Product Collection + * + * @return Mage_Reports_Model_Mysql4_Product_Index_Collection_Abstract + */ + public function getItemsCollection() + { + if (is_null($this->_collection)) { + $attributes = Mage::getSingleton('catalog/config')->getProductAttributes(); + + $this->_collection = $this->_getModel() + ->getCollection() + ->addAttributeToSelect($attributes) + ->addIndexFilter() + ->excludeProductIds($this->_getModel()->getExcludeProductIds()) + ->setAddedAtOrder(); + + Mage::getSingleton('catalog/product_visibility') + ->addVisibleInSiteFilterToCollection($this->_collection); } - return $collection; + + return $this->_collection; + } + + /** + * Retrieve count of product index items + * + * @return int + */ + public function getCount() + { + if (!$this->_getModel()->getCount()) { + return 0; + } + return $this->getItemsCollection()->count(); + } + + /** + * Get products collection and apply recent events log to it + * + * @deprecated + * @return Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection + */ + protected function _getRecentProductsCollection() + { + return $this->getItemsCollection(); } } diff --git a/app/code/core/Mage/Reports/Block/Product/Compared.php b/app/code/core/Mage/Reports/Block/Product/Compared.php index 0f9f0458c2..08e9d1d8eb 100644 --- a/app/code/core/Mage/Reports/Block/Product/Compared.php +++ b/app/code/core/Mage/Reports/Block/Product/Compared.php @@ -20,7 +20,7 @@ * * @category Mage * @package Mage_Reports - * @copyright Copyright (c) 2008 Irubin Consulting Inc. DBA Varien (http://www.varien.com) + * @copyright Copyright (c) 2009 Irubin Consulting Inc. DBA Varien (http://www.varien.com) * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ @@ -29,21 +29,25 @@ * * @category Mage * @package Mage_Reports - * @author Magento Core Team + * @author Magento Core Team */ - class Mage_Reports_Block_Product_Compared extends Mage_Reports_Block_Product_Abstract { const XML_PATH_RECENTLY_COMPARED_COUNT = 'catalog/recently_products/compared_count'; - protected $_eventTypeId = Mage_Reports_Model_Event::EVENT_PRODUCT_COMPARE; + /** + * Compared Product Index model name + * + * @var string + */ + protected $_indexName = 'reports/product_index_compared'; /** * Retrieve page size (count) * * @return int */ - protected function getPageSize() + public function getPageSize() { if ($this->hasData('page_size')) { return $this->getData('page_size'); @@ -51,55 +55,19 @@ protected function getPageSize() return Mage::getStoreConfig(self::XML_PATH_RECENTLY_COMPARED_COUNT); } - /** - * Retrieve Product Ids to skip - * - * @return array - */ - protected function _getProductsToSkip() - { - $ids = array(); - if (Mage::helper('catalog/product_compare')->getItemCount()) { - foreach (Mage::helper('catalog/product_compare')->getItemCollection() as $_item) { - $ids[] = $_item->getId(); - } - if (($product = Mage::registry('product')) && $product->getId()) { - $ids[] = $product->getId(); - } - } - return $ids; - } - - /** - * Check session has compared products - * - * @return bool - */ - protected function _hasComparedProductsBefore() - { - return Mage::getSingleton('reports/session')->getData('compared_products'); - } - /** * Prepare to html - * check has compared products + * Check has compared products * * @return string */ protected function _toHtml() { - if (!$this->_hasComparedProductsBefore()) { + if (!$this->getCount()) { return ''; } - $collection = $this->_getRecentProductsCollection(); - $hasProducts = (bool)count($collection); - if (is_null($this->_hasComparedProductsBefore())) { - Mage::getSingleton('reports/session')->setData('compared_products', $hasProducts); - } - if ($hasProducts) { - $this->setRecentlyComparedProducts($collection); - } + $this->setRecentlyComparedProducts($this->getItemsCollection()); return parent::_toHtml(); } diff --git a/app/code/core/Mage/Reports/Block/Product/Viewed.php b/app/code/core/Mage/Reports/Block/Product/Viewed.php index e66a09a748..12fdb99946 100644 --- a/app/code/core/Mage/Reports/Block/Product/Viewed.php +++ b/app/code/core/Mage/Reports/Block/Product/Viewed.php @@ -20,7 +20,7 @@ * * @category Mage * @package Mage_Reports - * @copyright Copyright (c) 2008 Irubin Consulting Inc. DBA Varien (http://www.varien.com) + * @copyright Copyright (c) 2009 Irubin Consulting Inc. DBA Varien (http://www.varien.com) * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ @@ -29,21 +29,25 @@ * * @category Mage * @package Mage_Reports - * @author Magento Core Team + * @author Magento Core Team */ - class Mage_Reports_Block_Product_Viewed extends Mage_Reports_Block_Product_Abstract { const XML_PATH_RECENTLY_VIEWED_COUNT = 'catalog/recently_products/viewed_count'; - protected $_eventTypeId = Mage_Reports_Model_Event::EVENT_PRODUCT_VIEW; + /** + * Viewed Product Index model name + * + * @var string + */ + protected $_indexName = 'reports/product_index_viewed'; /** * Retrieve page size (count) * * @return int */ - protected function getPageSize() + public function getPageSize() { if ($this->hasData('page_size')) { return $this->getData('page_size'); @@ -51,30 +55,6 @@ protected function getPageSize() return Mage::getStoreConfig(self::XML_PATH_RECENTLY_VIEWED_COUNT); } - /** - * Retrieve Product Ids to skip - * - * @return array - */ - protected function _getProductsToSkip() - { - $ids = array(); - if (($product = Mage::registry('product')) && $product->getId()) { - $ids = (int)$product->getId(); - } - return $ids; - } - - /** - * Check session has viewed products - * - * @return bool - */ - protected function _hasViewedProductsBefore() - { - return Mage::getSingleton('reports/session')->getData('viewed_products'); - } - /** * Prepare to html * check has viewed products @@ -83,18 +63,11 @@ protected function _hasViewedProductsBefore() */ protected function _toHtml() { - if (!$this->_hasViewedProductsBefore()) { + if (!$this->getCount()) { return ''; } - $collection = $this->_getRecentProductsCollection(); - $hasProducts = (bool)count($collection); - if (is_null($this->_hasViewedProductsBefore())) { - Mage::getSingleton('reports/session')->setData('viewed_products', $hasProducts); - } - if ($hasProducts) { - $this->setRecentlyViewedProducts($collection); - } + $this->setRecentlyViewedProducts($this->getItemsCollection()); return parent::_toHtml(); } diff --git a/app/code/core/Mage/Reports/Helper/Data.php b/app/code/core/Mage/Reports/Helper/Data.php index fd2d63d9d8..89fd2da7d2 100644 --- a/app/code/core/Mage/Reports/Helper/Data.php +++ b/app/code/core/Mage/Reports/Helper/Data.php @@ -29,5 +29,4 @@ */ class Mage_Reports_Helper_Data extends Mage_Core_Helper_Abstract { - } diff --git a/app/code/core/Mage/Reports/Model/Event/Observer.php b/app/code/core/Mage/Reports/Model/Event/Observer.php index e4f1546b2a..5d8cf75698 100644 --- a/app/code/core/Mage/Reports/Model/Event/Observer.php +++ b/app/code/core/Mage/Reports/Model/Event/Observer.php @@ -20,20 +20,31 @@ * * @category Mage * @package Mage_Reports - * @copyright Copyright (c) 2008 Irubin Consulting Inc. DBA Varien (http://www.varien.com) + * @copyright Copyright (c) 2009 Irubin Consulting Inc. DBA Varien (http://www.varien.com) * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ + /** - * Report event observer model + * Reports Event observer model * * @category Mage * @package Mage_Reports - * @author Magento Core Team + * @author Magento Core Team */ - class Mage_Reports_Model_Event_Observer { + /** + * Abstract Event obeserver logic + * + * Save event + * + * @param int $eventTypeId + * @param int $objectId + * @param int $subjectId + * @param int $subtype + * @return Mage_Reports_Model_Event_Observer + */ protected function _event($eventTypeId, $objectId, $subjectId = null, $subtype = 0) { if (is_null($subjectId)) { @@ -60,48 +71,137 @@ protected function _event($eventTypeId, $objectId, $subjectId = null, $subtype = return $this; } - public function customerLogin(Varien_Event_Observer $observer) { + /** + * Customer login action + * + * @param Varien_Event_Observer $observer + * @return Mage_Reports_Model_Event_Observer + */ + public function customerLogin(Varien_Event_Observer $observer) + { if (!Mage::getSingleton('customer/session')->isLoggedIn()) { return $this; } - $customer = Mage::getSingleton('customer/session')->getCustomer(); - $visitorId = Mage::getSingleton('log/visitor')->getId(); - $customerId = $customer->getId(); + + $visitorId = Mage::getSingleton('log/visitor')->getId(); + $customerId = Mage::getSingleton('customer/session')->getCustomerId(); $eventModel = Mage::getModel('reports/event'); $eventModel->updateCustomerType($visitorId, $customerId); + + Mage::getModel('reports/product_index_compared') + ->updateCustomerFromVisitor() + ->calculate(); + Mage::getModel('reports/product_index_viewed') + ->updateCustomerFromVisitor() + ->calculate(); + + return $this; + } + + /** + * Customer logout processing + * + * @param Varien_Event_Observer $observer + * @return Mage_Reports_Model_Event_Observer + */ + public function customerLogout(Varien_Event_Observer $observer) + { + Mage::getModel('reports/product_index_compared') + ->purgeVisitorByCustomer() + ->calculate(); + Mage::getModel('reports/product_index_viewed') + ->purgeVisitorByCustomer() + ->calculate(); + return $this; } + /** + * View Catalog Product action + * + * @param Varien_Event_Observer $observer + * @return Mage_Reports_Model_Event_Observer + */ public function catalogProductView(Varien_Event_Observer $observer) { - Mage::getSingleton('reports/session')->setData('viewed_products', true); - return $this->_event( - Mage_Reports_Model_Event::EVENT_PRODUCT_VIEW, - $observer->getEvent()->getProduct()->getId() - ); + $productId = $observer->getEvent()->getProduct()->getId(); + + Mage::getModel('reports/product_index_viewed') + ->setProductId($productId) + ->save() + ->calculate(); + + return $this->_event(Mage_Reports_Model_Event::EVENT_PRODUCT_VIEW, $productId); } + /** + * Send Product link to friends action + * + * @param Varien_Event_Observer $observer + * @return Mage_Reports_Model_Event_Observer + */ public function sendfriendProduct(Varien_Event_Observer $observer) { - return $this->_event( - Mage_Reports_Model_Event::EVENT_PRODUCT_SEND, + return $this->_event(Mage_Reports_Model_Event::EVENT_PRODUCT_SEND, $observer->getEvent()->getProduct()->getId() ); } + /** + * Remove Product from Compare Products action + * + * Reset count of compared products cache + * + * @param Varien_Event_Observer $observer + * @return Mage_Reports_Model_Event_Observer + */ public function catalogProductCompareRemoveProduct(Varien_Event_Observer $observer) { - Mage::getSingleton('reports/session')->setData('compared_products', null); + Mage::getModel('reports/product_index_compared')->calculate(); + + return $this; + } + + /** + * Remove All Products from Compare Products + * + * Reset count of compared products cache + * + * @param Varien_Event_Observer $observer + * @return Mage_Reports_Model_Event_Observer + */ + public function catalogProductCompareClear(Varien_Event_Observer $observer) + { + Mage::getModel('reports/product_index_compared')->calculate(); + + return $this; } + /** + * Add Product to Compare Products List action + * + * Reset count of compared products cache + * + * @param Varien_Event_Observer $observer + * @return unknown + */ public function catalogProductCompareAddProduct(Varien_Event_Observer $observer) { - Mage::getSingleton('reports/session')->setData('compared_products', true); - return $this->_event( - Mage_Reports_Model_Event::EVENT_PRODUCT_COMPARE, - $observer->getEvent()->getProduct()->getId() - ); + $productId = $observer->getEvent()->getProduct()->getId(); + + Mage::getModel('reports/product_index_compared') + ->setProductId($productId) + ->save() + ->calculate(); + + return $this->_event(Mage_Reports_Model_Event::EVENT_PRODUCT_COMPARE, $productId); } + /** + * Add product to shopping cart action + * + * @param Varien_Event_Observer $observer + * @return Mage_Reports_Model_Event_Observer + */ public function checkoutCartAddProduct(Varien_Event_Observer $observer) { $quoteItem = $observer->getEvent()->getItem(); @@ -112,34 +212,49 @@ public function checkoutCartAddProduct(Varien_Event_Observer $observer) return $this; } + /** + * Add product to wishlist action + * + * @param Varien_Event_Observer $observer + * @return Mage_Reports_Model_Event_Observer + */ public function wishlistAddProduct(Varien_Event_Observer $observer) { - return $this->_event( - Mage_Reports_Model_Event::EVENT_PRODUCT_TO_WISHLIST, + return $this->_event(Mage_Reports_Model_Event::EVENT_PRODUCT_TO_WISHLIST, $observer->getEvent()->getProduct()->getId() ); } + /** + * Share customer wishlist action + * + * @param Varien_Event_Observer $observer + * @return Mage_Reports_Model_Event_Observer + */ public function wishlistShare(Varien_Event_Observer $observer) { - return $this->_event( - Mage_Reports_Model_Event::EVENT_WISHLIST_SHARE, + return $this->_event(Mage_Reports_Model_Event::EVENT_WISHLIST_SHARE, $observer->getEvent()->getWishlist()->getId() ); } /** - * event clean + * Clean events by old visitors + * + * @see Global Log Clean Settings * * @param Varien_Event_Observer $observer * @return Mage_Reports_Model_Event_Observer */ public function eventClean(Varien_Event_Observer $observer) { - $event = Mage::getModel('reports/event'); /* @var $event Mage_Reports_Model_Event */ + $event = Mage::getModel('reports/event'); $event->clean(); + Mage::getModel('reports/product_index_compared')->clean(); + Mage::getModel('reports/product_index_viewed')->clean(); + return $this; } -} \ No newline at end of file +} diff --git a/app/code/core/Mage/Reports/Model/Mysql4/Order/Collection.php b/app/code/core/Mage/Reports/Model/Mysql4/Order/Collection.php index 2114fa4824..33e2249895 100644 --- a/app/code/core/Mage/Reports/Model/Mysql4/Order/Collection.php +++ b/app/code/core/Mage/Reports/Model/Mysql4/Order/Collection.php @@ -114,7 +114,7 @@ public function getDateRange($range, $customStart, $customEnd, $returnObjects = break; case '1m': - $dateStart->setDay(1); + $dateStart->setDay(Mage::getStoreConfig('reports/dashboard/mtd_start')); break; case 'custom': @@ -123,13 +123,15 @@ public function getDateRange($range, $customStart, $customEnd, $returnObjects = break; case '1y': - $dateStart->setMonth(1); - $dateStart->setDay(1); - break; case '2y': - $dateStart->setMonth(1); - $dateStart->setDay(1); - $dateStart->subYear(1); + $startMonthDay = explode(',', Mage::getStoreConfig('reports/dashboard/ytd_start')); + $startMonth = isset($startMonthDay[0]) ? (int)$startMonthDay[0] : 1; + $startDay = isset($startMonthDay[1]) ? (int)$startMonthDay[1] : 1; + $dateStart->setMonth($startMonth); + $dateStart->setDay($startDay); + if ($range == '2y') { + $dateStart->subYear(1); + } break; } diff --git a/app/code/core/Mage/Reports/Model/Session.php b/app/code/core/Mage/Reports/Model/Session.php index c4d7ce2d12..eef34c9e15 100644 --- a/app/code/core/Mage/Reports/Model/Session.php +++ b/app/code/core/Mage/Reports/Model/Session.php @@ -1,41 +1,45 @@ - - */ -class Mage_Reports_Model_Session extends Mage_Core_Model_Session_Abstract -{ - public function __construct() - { - $this->init('reports'); - } -} \ No newline at end of file + + */ +class Mage_Reports_Model_Session extends Mage_Core_Model_Session_Abstract +{ + /** + * Initialize session name space + * + */ + public function __construct() + { + $this->init('reports'); + } +} diff --git a/app/code/core/Mage/Reports/etc/config.xml b/app/code/core/Mage/Reports/etc/config.xml index 8315d4f153..2a0aae3760 100644 --- a/app/code/core/Mage/Reports/etc/config.xml +++ b/app/code/core/Mage/Reports/etc/config.xml @@ -28,7 +28,7 @@ - 0.7.7 + 0.7.8 @@ -46,6 +46,12 @@ report_event_types
    + + report_compared_product_index
    +
    + + report_viewed_product_index
    +
    @@ -70,80 +76,7 @@ - - - - - singleton - reports/event_observer - catalogProductCompareRemoveProduct - - - - - - - singleton - reports/event_observer - customerLogin - - - - - - - singleton - reports/event_observer - catalogProductView - - - - - - - singleton - reports/event_observer - sendfriendProduct - - - - - - - singleton - reports/event_observer - catalogProductCompareAddProduct - - - - - - - singleton - reports/event_observer - checkoutCartAddProduct - - - - - - - singleton - reports/event_observer - wishlistAddProduct - - - - - - - singleton - reports/event_observer - wishlistShare - - - @@ -423,6 +356,17 @@ + + + + + + Reports + + + + + @@ -445,9 +389,101 @@ + + + + + singleton + reports/event_observer + catalogProductCompareRemoveProduct + + + + + + + singleton + reports/event_observer + customerLogin + + + + + + + singleton + reports/event_observer + customerLogout + + + + + + + singleton + reports/event_observer + catalogProductView + + + + + + + singleton + reports/event_observer + sendfriendProduct + + + + + + + singleton + reports/event_observer + catalogProductCompareAddProduct + + + + + + + singleton + reports/event_observer + catalogProductCompareClear + + + + + + + singleton + reports/event_observer + checkoutCartAddProduct + + + + + + + singleton + reports/event_observer + wishlistAddProduct + + + + + + + singleton + reports/event_observer + wishlistShare + + + + - + website @@ -455,5 +491,11 @@ 5 + + + 1,1 + 1 + +
    diff --git a/app/code/core/Mage/Reports/etc/system.xml b/app/code/core/Mage/Reports/etc/system.xml index 82bbb915ff..0b0b1838da 100644 --- a/app/code/core/Mage/Reports/etc/system.xml +++ b/app/code/core/Mage/Reports/etc/system.xml @@ -66,5 +66,45 @@ + + + general + text + 1000 + 1 + 0 + 0 + + + + text + 1 + 1 + 0 + 0 + + + + select + adminhtml/report_config_form_field_ytdStart + 1 + 1 + 0 + 0 + + + + select + adminhtml/report_config_form_field_mtdStart + Select day of the month + 2 + 1 + 0 + 0 + + + + +
    \ No newline at end of file diff --git a/app/code/core/Mage/Review/controllers/ProductController.php b/app/code/core/Mage/Review/controllers/ProductController.php index 138cb4ea88..87dd9231fb 100644 --- a/app/code/core/Mage/Review/controllers/ProductController.php +++ b/app/code/core/Mage/Review/controllers/ProductController.php @@ -68,7 +68,7 @@ public function preDispatch() * * @return Mage_Catalog_Model_Product */ - protected function _initProduct() + protected function _initProduct() { Mage::dispatchEvent('review_controller_product_init_before', array('controller_action'=>$this)); $categoryId = (int) $this->getRequest()->getParam('category', false); @@ -195,6 +195,7 @@ public function viewAction() { $this->loadLayout(); $this->_initLayoutMessages('review/session'); + $this->_initLayoutMessages('catalog/session'); $this->renderLayout(); } diff --git a/app/code/core/Mage/Rss/Block/Catalog/New.php b/app/code/core/Mage/Rss/Block/Catalog/New.php index daeb2aa628..422922b384 100644 --- a/app/code/core/Mage/Rss/Block/Catalog/New.php +++ b/app/code/core/Mage/Rss/Block/Catalog/New.php @@ -93,6 +93,15 @@ protected function _toHtml() public function addNewItemXmlCallback($args) { $product = $args['product']; + + $product->setAllowedInRss(true); + Mage::dispatchEvent('rss_catalog_new_xml_callback', $args); + + if (!$product->getAllowedInRss()) { + //Skip adding product to RSS + return; + } + //$product->unsetData()->load($args['row']['entity_id']); $product->setData($args['row']); $final_price = $product->getFinalPrice(); diff --git a/app/code/core/Mage/Rss/Block/Catalog/NotifyStock.php b/app/code/core/Mage/Rss/Block/Catalog/NotifyStock.php index 04f77bbeb3..9676c28d5a 100644 --- a/app/code/core/Mage/Rss/Block/Catalog/NotifyStock.php +++ b/app/code/core/Mage/Rss/Block/Catalog/NotifyStock.php @@ -58,7 +58,7 @@ protected function _toHtml() $_configManageStock = (int)Mage::getStoreConfigFlag(Mage_CatalogInventory_Model_Stock_Item::XML_PATH_MANAGE_STOCK); $stockItemWhere = "({{table}}.low_stock_date is not null) " . " and ({{table}}.low_stock_date>'0000-00-00') " - . " and IF({{table}}.use_config_manage_stock=1," . $_configManageStock . ",{{table}}.manage_stock)=1"; + . " and IF({{table}}.use_config_manage_stock=1," . $_configManageStock . ",{{table}}.manage_stock) <= 1"; $product = Mage::getModel('catalog/product'); $collection = $product->getCollection() diff --git a/app/code/core/Mage/Rss/Block/Catalog/Special.php b/app/code/core/Mage/Rss/Block/Catalog/Special.php index a02a1c9ab5..6fa5c48191 100644 --- a/app/code/core/Mage/Rss/Block/Catalog/Special.php +++ b/app/code/core/Mage/Rss/Block/Catalog/Special.php @@ -141,6 +141,21 @@ protected function _toHtml() public function addSpecialXmlCallback($args) { + /* + * RSS state object + */ + $product = new Varien_Object(); + //Product is allowed for RSS initially + $product->setAllowedInRss(true); + $args['product'] = $product; + + Mage::dispatchEvent('rss_catalog_special_xml_callback', $args); + + if (!$product->getAllowedInRss()) { + //Skip adding product to RSS + return; + } + //echo "
    ";
     //print_r($args['row']);
            $row = $args['row'];
    diff --git a/app/code/core/Mage/Rss/Block/Catalog/Tag.php b/app/code/core/Mage/Rss/Block/Catalog/Tag.php
    index ed1b4a51b2..1bf0b34726 100644
    --- a/app/code/core/Mage/Rss/Block/Catalog/Tag.php
    +++ b/app/code/core/Mage/Rss/Block/Catalog/Tag.php
    @@ -75,6 +75,15 @@ protected function _toHtml()
         public function addTaggedItemXml($args)
         {
             $product = $args['product'];
    +
    +        $product->setAllowedInRss(true);
    +        Mage::dispatchEvent('rss_catalog_tagged_item_xml_callback', $args);
    +
    +        if (!$product->getAllowedInRss()) {
    +            //Skip adding product to RSS
    +            return;
    +        }
    +
             $product->unsetData()->load($args['row']['entity_id']);
             $description = ''.
             ''.
    diff --git a/app/code/core/Mage/Rss/Block/Wishlist.php b/app/code/core/Mage/Rss/Block/Wishlist.php
    index f5db3797dd..86bc51018c 100644
    --- a/app/code/core/Mage/Rss/Block/Wishlist.php
    +++ b/app/code/core/Mage/Rss/Block/Wishlist.php
    @@ -20,85 +20,142 @@
      *
      * @category   Mage
      * @package    Mage_Rss
    - * @copyright  Copyright (c) 2008 Irubin Consulting Inc. DBA Varien (http://www.varien.com)
    + * @copyright  Copyright (c) 2009 Irubin Consulting Inc. DBA Varien (http://www.varien.com)
      * @license    http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
      */
     
     /**
    - * Review form block
    + * Customer Shared Wishlist Rss Block
      *
      * @category   Mage
      * @package    Mage_Rss
    - * @author      Magento Core Team 
    + * @author     Magento Core Team 
      */
    -class Mage_Rss_Block_Wishlist extends Mage_Core_Block_Template
    +class Mage_Rss_Block_Wishlist extends Mage_Wishlist_Block_Abstract
     {
    -    protected function _toHtml()
    +    /**
    +     * Customer instance
    +     *
    +     * @var Mage_Customer_Model_Customer
    +     */
    +    protected $_customer;
    +
    +    /**
    +     * Retrieve Wishlist model
    +     *
    +     * @return Mage_Wishlist_Model_Wishlist
    +     */
    +    protected function _getWishlist()
         {
    -        $descrpt = Mage::helper('core')->urlDecode($this->getRequest()->getParam('data'));
    -        $data = explode(',',$descrpt);
    -        $cid = (int)$data[0];
    +        if (is_null($this->_wishlist)) {
    +            $this->_wishlist = Mage::getModel('wishlist/wishlist');
    +            if ($this->_getCustomer()->getId()) {
    +                $this->_wishlist->loadByCustomer($this->_getCustomer());
    +            }
    +        }
    +        return $this->_wishlist;
    +    }
     
    -        $rssObj = Mage::getModel('rss/rss');
    +    /**
    +     * Retrieve Customer instance
    +     *
    +     * @return Mage_Customer_Model_Customer
    +     */
    +    protected function _getCustomer()
    +    {
    +        if (is_null($this->_customer)) {
    +            $this->_customer = Mage::getModel('customer/customer');
     
    -        if ($cid) {
    -            $customer = Mage::getModel('customer/customer')->load($cid);
    -            if ($customer && $customer->getId()) {
    +            $params = Mage::helper('core')->urlDecode($this->getRequest()->getParam('data'));
    +            $data   = explode(',', $params);
    +            $cId    = abs(intval($data[0]));
    +            if ($cId) {
    +                $this->_customer->load($cId);
    +            }
    +        }
    +
    +        return $this->_customer;
    +    }
     
    -                $wishlist = Mage::getModel('wishlist/wishlist')
    -                ->loadByCustomer($customer, true);
    +    /**
    +     * Render block HTML
    +     *
    +     * @return string
    +     */
    +    protected function _toHtml()
    +    {
    +        /* @var $rssObj Mage_Rss_Model_Rss */
    +        $rssObj = Mage::getModel('rss/rss');
     
    -                $newurl = Mage::getUrl('wishlist/shared/index',array('code'=>$wishlist->getSharingCode()));
    -                $title = Mage::helper('rss')->__('%s\'s Wishlist',$customer->getName());
    -                $lang = Mage::getStoreConfig('general/locale/code');
    +        if ($this->_getWishlist()->getId()) {
    +            $newUrl = Mage::getUrl('wishlist/shared/index', array(
    +                'code'  => $this->_getWishlist()->getSharingCode()
    +            ));
     
    -                $data = array('title' => $title,
    -                    'description' => $title,
    -                    'link'        => $newurl,
    -                    'charset'     => 'UTF-8',
    -                    'language'    => $lang
    -                );
    -                $rssObj->_addHeader($data);
    +            $title  = Mage::helper('rss')->__('%s\'s Wishlist', $this->_getCustomer()->getName());
    +            $lang   = Mage::getStoreConfig('general/locale/code');
     
    -                $collection = $wishlist->getProductCollection()
    -                            ->addAttributeToSelect('url_key')
    -                            ->addAttributeToSelect('name')
    -                            ->addAttributeToSelect('price')
    -                            ->addAttributeToSelect('thumbnail')
    -                            ->addAttributeToFilter('store_id', array('in'=> $wishlist->getSharedStoreIds()))
    -                            ->load();
    +            $rssObj->_addHeader(array(
    +                'title'         => $title,
    +                'description'   => $title,
    +                'link'          => $newUrl,
    +                'charset'       => 'UTF-8',
    +                'language'      => $lang
    +            ));
     
    -                $product = Mage::getModel('catalog/product');
    -                foreach($collection as $item){
    -                    $product->unsetData()->load($item->getProductId());
    -                    $description = '
    '. - ''. - ''. - '
    '. - $product->getDescription(). - '

    Price:'.Mage::helper('core')->currency($product->getPrice()). - ($product->getPrice() != $product->getFinalPrice() ? ' Special Price:'. Mage::helper('core')->currency($product->getFinalPrice()) : ''). - ($item->getDescription() && $item->getDescription() != Mage::helper('wishlist')->defaultCommentString() ? '

    Comment: '.$item->getDescription().'

    ' : ''). - '

    '; - $data = array( - 'title' => $product->getName(), - 'link' => $product->getProductUrl(), - 'description' => $description, - ); - $rssObj->_addEntry($data); + /* @var $product Mage_Catalog_Model_Product */ + foreach ($this->getWishlistItems() as $product) { + $description = '' + . '
    ' . $this->htmlEscape($product->getShortDescription()) . '

    '; + if ($product->getPrice() != $product->getFinalPrice()) { + $description .= Mage::helper('catalog')->__('Regular Price:') . ' ' + . Mage::helper('core')->currency($product->getPrice()) . ' ' + . Mage::helper('catalog')->__('Special Price:') . ' ' + . Mage::helper('core')->currency($product->getFinalPrice()).''; + } + else { + $description .= Mage::helper('catalog')->__('Price:') . ' ' + . Mage::helper('core')->currency($product->getFinalPrice()); + } + $description .= '

    '; + if ($this->hasDescription($product)) { + $description .= '

    ' . Mage::helper('wishlist')->__('Comment:') + . ' ' . $this->getEscapedDescription($product) . '

    '; } - } + $description .= '

    '; - } else { - $data = array('title' => Mage::helper('rss')->__('Cannot retrieve the wishlist'), - 'description' => Mage::helper('rss')->__('Cannot retrieve the wishlist'), - 'link' => Mage::getUrl(), - 'charset' => 'UTF-8', - ); - $rssObj->_addHeader($data); + $rssObj->_addEntry(array( + 'title' => $product->getName(), + 'link' => $this->getProductUrl($product), + 'description' => $description, + )); + } + } + else { + $rssObj->_addHeader(array( + 'title' => Mage::helper('rss')->__('Cannot retrieve the wishlist'), + 'description' => Mage::helper('rss')->__('Cannot retrieve the wishlist'), + 'link' => Mage::getUrl(), + 'charset' => 'UTF-8', + )); } + return $rssObj->createRssXml(); } -} \ No newline at end of file + /** + * Retrieve Product View URL + * + * @param Mage_Catalog_Model_Product $product + * @param array $additional + * @return string + */ + public function getProductUrl($product, $additional = array()) + { + $additional['_rss'] = true; + return parent::getProductUrl($product, $additional); + } +} diff --git a/app/code/core/Mage/Rule/Model/Rule.php b/app/code/core/Mage/Rule/Model/Rule.php index 86eb0c0682..4ddb5a6014 100644 --- a/app/code/core/Mage/Rule/Model/Rule.php +++ b/app/code/core/Mage/Rule/Model/Rule.php @@ -244,10 +244,13 @@ protected function _afterLoad() $this->getActions()->loadArray($actionsArr); } - $this->setWebsiteIds(explode(',',$this->getWebsiteIds())); + $websiteIds = $this->getWebsiteIds(); + if (is_string($websiteIds)) { + $this->setWebsiteIds(explode(',', $websiteIds)); + } $groupIds = $this->getCustomerGroupIds(); if (is_string($groupIds)) { - $this->setCustomerGroupIds(explode(',',$groupIds)); + $this->setCustomerGroupIds(explode(',', $groupIds)); } } diff --git a/app/code/core/Mage/Sales/Block/Order/Creditmemo.php b/app/code/core/Mage/Sales/Block/Order/Creditmemo.php index 2fa4862151..000cec8a28 100644 --- a/app/code/core/Mage/Sales/Block/Order/Creditmemo.php +++ b/app/code/core/Mage/Sales/Block/Order/Creditmemo.php @@ -31,7 +31,7 @@ * @package Mage_Sales * @author Magento Core Team */ -class Mage_Sales_Block_Order_Creditmemo extends Mage_Core_Block_Template +class Mage_Sales_Block_Order_Creditmemo extends Mage_Sales_Block_Order_Creditmemo_Items { protected function _construct() { diff --git a/app/code/core/Mage/Sales/Block/Order/Creditmemo/Items.php b/app/code/core/Mage/Sales/Block/Order/Creditmemo/Items.php index e7ab02804d..2bf085999b 100644 --- a/app/code/core/Mage/Sales/Block/Order/Creditmemo/Items.php +++ b/app/code/core/Mage/Sales/Block/Order/Creditmemo/Items.php @@ -43,11 +43,30 @@ public function getOrder() return Mage::registry('current_order'); } - public function getPrintCreditmemoUrl($creditmemo){ + public function getPrintCreditmemoUrl($creditmemo) + { return Mage::getUrl('*/*/printCreditmemo', array('creditmemo_id' => $creditmemo->getId())); } - public function getPrintAllCreditmemosUrl($order){ + public function getPrintAllCreditmemosUrl($order) + { return Mage::getUrl('*/*/printCreditmemo', array('order_id' => $order->getId())); } + + /** + * Get creditmemo totals block html + * + * @param Mage_Sales_Model_Order_Creditmemo $creditmemo + * @return string + */ + public function getTotalsHtml($creditmemo) + { + $totals = $this->getChild('creditmemo_totals'); + $html = ''; + if ($totals) { + $totals->setCreditmemo($creditmemo); + $html = $totals->toHtml(); + } + return $html; + } } \ No newline at end of file diff --git a/app/code/core/Mage/Sales/Block/Order/Invoice.php b/app/code/core/Mage/Sales/Block/Order/Invoice.php index da920969f8..2c73146049 100644 --- a/app/code/core/Mage/Sales/Block/Order/Invoice.php +++ b/app/code/core/Mage/Sales/Block/Order/Invoice.php @@ -31,7 +31,7 @@ * @package Mage_Sales * @author Magento Core Team */ -class Mage_Sales_Block_Order_Invoice extends Mage_Core_Block_Template +class Mage_Sales_Block_Order_Invoice extends Mage_Sales_Block_Order_Invoice_Items { protected function _construct() { diff --git a/app/code/core/Mage/Sales/Block/Order/Invoice/Items.php b/app/code/core/Mage/Sales/Block/Order/Invoice/Items.php index eb137e86aa..9b7ba601b5 100644 --- a/app/code/core/Mage/Sales/Block/Order/Invoice/Items.php +++ b/app/code/core/Mage/Sales/Block/Order/Invoice/Items.php @@ -43,11 +43,30 @@ public function getOrder() return Mage::registry('current_order'); } - public function getPrintInvoiceUrl($invoice){ + public function getPrintInvoiceUrl($invoice) + { return Mage::getUrl('*/*/printInvoice', array('invoice_id' => $invoice->getId())); } - public function getPrintAllInvoicesUrl($order){ + public function getPrintAllInvoicesUrl($order) + { return Mage::getUrl('*/*/printInvoice', array('order_id' => $order->getId())); } + + /** + * Get html of invoice totals block + * + * @param Mage_Sales_Model_Order_Invoice $invoice + * @return string + */ + public function getInvoiceTotalsHtml($invoice) + { + $html = ''; + $totals = $this->getChild('invoice_totals'); + if ($totals) { + $totals->setInvoice($invoice); + $html = $totals->toHtml(); + } + return $html; + } } \ No newline at end of file diff --git a/app/code/core/Mage/Sales/Block/Order/Print/Creditmemo.php b/app/code/core/Mage/Sales/Block/Order/Print/Creditmemo.php index f0f9f77c59..b674df12d7 100644 --- a/app/code/core/Mage/Sales/Block/Order/Print/Creditmemo.php +++ b/app/code/core/Mage/Sales/Block/Order/Print/Creditmemo.php @@ -34,12 +34,6 @@ class Mage_Sales_Block_Order_Print_Creditmemo extends Mage_Sales_Block_Items_Abstract { - - public function __construct() - { - parent::__construct(); - } - protected function _prepareLayout() { if ($headBlock = $this->getLayout()->getBlock('head')) { @@ -79,8 +73,23 @@ public function getCreditmemo() protected function _prepareItem(Mage_Core_Block_Abstract $renderer) { $renderer->setPrintStatus(true); - return parent::_prepareItem($renderer); } -} + /** + * Get Creditmemo totals block html gor specific creditmemo + * + * @param Mage_Sales_Model_Order_Creditmemo $creditmemo + * @return string + */ + public function getTotalsHtml($creditmemo) + { + $totals = $this->getChild('creditmemo_totals'); + $html = ''; + if ($totals) { + $totals->setCreditmemo($creditmemo); + $html = $totals->toHtml(); + } + return $html; + } +} \ No newline at end of file diff --git a/app/code/core/Mage/Sales/Block/Order/Print/Invoice.php b/app/code/core/Mage/Sales/Block/Order/Print/Invoice.php index f902c025de..3e983abfdf 100644 --- a/app/code/core/Mage/Sales/Block/Order/Print/Invoice.php +++ b/app/code/core/Mage/Sales/Block/Order/Print/Invoice.php @@ -34,12 +34,6 @@ class Mage_Sales_Block_Order_Print_Invoice extends Mage_Sales_Block_Items_Abstract { - - public function __construct() - { - parent::__construct(); - } - protected function _prepareLayout() { if ($headBlock = $this->getLayout()->getBlock('head')) { @@ -79,8 +73,25 @@ public function getInvoice() protected function _prepareItem(Mage_Core_Block_Abstract $renderer) { $renderer->setPrintStatus(true); - return parent::_prepareItem($renderer); } + + /** + * Get html of invoice totlas block + * + * @param Mage_Sales_Model_Order_Invoice $invoice + * @return string + */ + public function getInvoiceTotalsHtml($invoice) + { + $html = ''; + $totals = $this->getChild('invoice_totals'); + if ($totals) { + $totals->setInvoice($invoice); + $html = $totals->toHtml(); + } + return $html; + } + } diff --git a/app/code/core/Mage/Sales/Block/Order/Tax.php b/app/code/core/Mage/Sales/Block/Order/Tax.php index 05b36f0b45..1c5fa765cc 100644 --- a/app/code/core/Mage/Sales/Block/Order/Tax.php +++ b/app/code/core/Mage/Sales/Block/Order/Tax.php @@ -27,6 +27,7 @@ /** * Sales order view tax block * + * @deprecated after 1.3.2.2 * @category Mage * @package Mage_Sales * @author Magento Core Team diff --git a/app/code/core/Mage/Sales/Model/Convert/Order.php b/app/code/core/Mage/Sales/Model/Convert/Order.php index 55d721ff47..a21b18bba5 100644 --- a/app/code/core/Mage/Sales/Model/Convert/Order.php +++ b/app/code/core/Mage/Sales/Model/Convert/Order.php @@ -87,7 +87,6 @@ public function toQuote(Mage_Sales_Model_Order $order, $quote=null) // * Another data // */ // ->setCouponCode($order->getCouponCode()) -// ->setGiftcertCode($order->getGiftcertCode()) // ->setAppliedRuleIds($order->getAppliedRuleIds()); // //->collectTotals(); // @@ -116,7 +115,6 @@ public function toQuoteShippingAddress(Mage_Sales_Model_Order $order) // ->setTaxAmount($order->getTaxAmount()) // ->setDiscountAmount($order->getDiscountAmount()) // ->setShippingAmount($order->getShippingAmount()) -// ->setGiftcertAmount($order->getGiftcertAmount()) // ->setCustbalanceAmount($order->getCustbalanceAmount()) // ->setGrandTotal($order->getGrandTotal()) // @@ -124,7 +122,6 @@ public function toQuoteShippingAddress(Mage_Sales_Model_Order $order) // ->setBaseTaxAmount($order->getBaseTaxAmount()) // ->setBaseDiscountAmount($order->getBaseDiscountAmount()) // ->setBaseShippingAmount($order->getBaseShippingAmount()) -// ->setBaseGiftcertAmount($order->getBaseGiftcertAmount()) // ->setBaseCustbalanceAmount($order->getBaseCustbalanceAmount()) // ->setBaseGrandTotal($order->getBaseGrandTotal()); return $address; diff --git a/app/code/core/Mage/Sales/Model/Convert/Quote.php b/app/code/core/Mage/Sales/Model/Convert/Quote.php index 09d3cf5f2c..8a5b9ced04 100644 --- a/app/code/core/Mage/Sales/Model/Convert/Quote.php +++ b/app/code/core/Mage/Sales/Model/Convert/Quote.php @@ -96,7 +96,6 @@ public function toOrder(Mage_Sales_Model_Quote $quote, $order=null) // * Another data // */ // ->setCouponCode($quote->getCouponCode()) -// ->setGiftcertCode($quote->getGiftcertCode()) // ->setIsVirtual($quote->getIsVirtual()) // ->setIsMultiPayment($quote->getIsMultiPayment()) // ->setAppliedRuleIds($quote->getAppliedRuleIds()); @@ -131,7 +130,6 @@ public function addressToOrder(Mage_Sales_Model_Quote_Address $address, $order=n // ->setDiscountAmount($address->getDiscountAmount()) // ->setShippingAmount($address->getShippingAmount()) // ->setShippingTaxAmount($address->getShippingTaxAmount()) -// ->setGiftcertAmount($address->getGiftcertAmount()) // ->setCustbalanceAmount($address->getCustbalanceAmount()) // ->setGrandTotal($address->getGrandTotal()) // @@ -140,7 +138,6 @@ public function addressToOrder(Mage_Sales_Model_Quote_Address $address, $order=n // ->setBaseDiscountAmount($address->getBaseDiscountAmount()) // ->setBaseShippingAmount($address->getBaseShippingAmount()) // ->setBaseShippingTaxAmount($address->getBaseShippingTaxAmount()) -// ->setBaseGiftcertAmount($address->getBaseGiftcertAmount()) // ->setBaseCustbalanceAmount($address->getBaseCustbalanceAmount()) // ->setBaseGrandTotal($address->getBaseGrandTotal()); diff --git a/app/code/core/Mage/Sales/Model/Entity/Setup.php b/app/code/core/Mage/Sales/Model/Entity/Setup.php index 60de406f72..1f166bb471 100644 --- a/app/code/core/Mage/Sales/Model/Entity/Setup.php +++ b/app/code/core/Mage/Sales/Model/Entity/Setup.php @@ -290,7 +290,6 @@ public function getDefaultEntities() 'coupon_code' => array(), 'applied_rule_ids' => array(), - 'giftcert_code' => array(), 'global_currency_code' => array(), 'base_currency_code' => array(), @@ -311,7 +310,6 @@ public function getDefaultEntities() 'tax_amount' => array('type'=>'static'), 'shipping_amount' => array('type'=>'static'), 'discount_amount' => array('type'=>'static'), - 'giftcert_amount' => array('type'=>'decimal'), 'custbalance_amount'=> array('type'=>'decimal'), 'subtotal' => array('type'=>'static'), @@ -330,7 +328,6 @@ public function getDefaultEntities() 'base_tax_amount' => array('type'=>'static'), 'base_shipping_amount' => array('type'=>'static'), 'base_discount_amount' => array('type'=>'static'), - 'base_giftcert_amount' => array('type'=>'decimal'), 'base_custbalance_amount'=> array('type'=>'decimal'), 'base_subtotal' => array('type'=>'static'), diff --git a/app/code/core/Mage/Sales/Model/Mysql4/Setup.php b/app/code/core/Mage/Sales/Model/Mysql4/Setup.php index 4c2846469d..25fa721aac 100644 --- a/app/code/core/Mage/Sales/Model/Mysql4/Setup.php +++ b/app/code/core/Mage/Sales/Model/Mysql4/Setup.php @@ -343,7 +343,6 @@ public function getDefaultEntities() 'coupon_code' => array(), 'applied_rule_ids' => array(), - 'giftcert_code' => array(), 'global_currency_code' => array(), 'base_currency_code' => array(), @@ -364,7 +363,6 @@ public function getDefaultEntities() 'shipping_amount' => array('type'=>'static'), 'shipping_tax_amount' => array('type'=>'static'), 'discount_amount' => array('type'=>'static'), - 'giftcert_amount' => array('type'=>'decimal'), 'subtotal' => array('type'=>'static'), 'grand_total' => array('type'=>'static'), @@ -383,7 +381,6 @@ public function getDefaultEntities() 'base_shipping_amount' => array('type'=>'static'), 'base_shipping_tax_amount' => array('type'=>'static'), 'base_discount_amount' => array('type'=>'static'), - 'base_giftcert_amount' => array('type'=>'decimal'), 'base_subtotal' => array('type'=>'static'), 'base_grand_total' => array('type'=>'static'), diff --git a/app/code/core/Mage/Sales/Model/Order.php b/app/code/core/Mage/Sales/Model/Order.php index 88b8d3e5d0..0b17f7a7a0 100644 --- a/app/code/core/Mage/Sales/Model/Order.php +++ b/app/code/core/Mage/Sales/Model/Order.php @@ -1116,7 +1116,7 @@ public function getRealOrderId() } /** - * Retrieve order currency model instance + * Get currency model instance. Will be used currency with which order placed * * @return Mage_Directory_Model_Currency */ @@ -1129,7 +1129,7 @@ public function getOrderCurrency() } /** - * Retrieve formated price value includeing order rate + * Get formated price value including order currency rate to order website currency * * @param float $price * @param bool $addBrackets @@ -1137,7 +1137,12 @@ public function getOrderCurrency() */ public function formatPrice($price, $addBrackets = false) { - return $this->getOrderCurrency()->format($price, array(), true, $addBrackets); + return $this->formatPricePrecision($price, 2, $addBrackets); + } + + public function formatPricePrecision($price, $precision, $addBrackets = false) + { + return $this->getOrderCurrency()->formatPrecision($price, $precision, array(), true, $addBrackets); } /** @@ -1166,7 +1171,7 @@ public function getBaseCurrency() /** * Retrieve order website currency for working with base prices - * Deprecated method, please use getBaseCurrency instead. + * @deprecated please use getBaseCurrency instead. * * @return Mage_Directory_Model_Currency */ @@ -1177,7 +1182,12 @@ public function getStoreCurrency() public function formatBasePrice($price) { - return $this->getBaseCurrency()->format($price); + return $this->formatBasePricePrecision($price, 2); + } + + public function formatBasePricePrecision($price, $precision) + { + return $this->getBaseCurrency()->formatPrecision($price, $precision); } public function isCurrencyDifferent() @@ -1518,8 +1528,10 @@ public function prepareInvoice($qtys = array()) } else { if (isset($qtys[$orderItem->getId()])) { $qty = $qtys[$orderItem->getId()]; - } else { + } elseif (!count($qtys)) { $qty = $orderItem->getQtyToInvoice(); + } else { + continue; } } @@ -1554,8 +1566,10 @@ public function prepareShipment($qtys = array()) } else { if (isset($qtys[$orderItem->getId()])) { $qty = $qtys[$orderItem->getId()]; - } else { + } elseif (!count($qtys)) { $qty = $orderItem->getQtyToShip(); + } else { + continue; } } diff --git a/app/code/core/Mage/Sales/Model/Order/Creditmemo/Item.php b/app/code/core/Mage/Sales/Model/Order/Creditmemo/Item.php index aa27b0ff3a..2d71a340f5 100644 --- a/app/code/core/Mage/Sales/Model/Order/Creditmemo/Item.php +++ b/app/code/core/Mage/Sales/Model/Order/Creditmemo/Item.php @@ -150,11 +150,40 @@ public function cancel() */ public function calcRowTotal() { - $rowTotal = $this->getOrderItem()->getRowTotal()/$this->getOrderItem()->getQtyOrdered()*$this->getQty(); - $baseRowTotal = $this->getOrderItem()->getBaseRowTotal()/$this->getOrderItem()->getQtyOrdered()*$this->getQty(); - - $this->setRowTotal($this->getCreditmemo()->getStore()->roundPrice($rowTotal)); - $this->setBaseRowTotal($this->getCreditmemo()->getStore()->roundPrice($baseRowTotal)); + $store = $this->getCreditmemo()->getStore(); + $orderItem = $this->getOrderItem(); + $orderItemQty = $orderItem->getQtyOrdered(); + + $rowTotal = $orderItem->getRowTotal(); + $baseRowTotal = $orderItem->getBaseRowTotal(); + $rowTotalInclTax = $orderItem->getRowTotalInclTax(); + $baseRowTotalInclTax= $orderItem->getBaseRowTotalInclTax(); + + $rowTotal = $rowTotal/$orderItemQty*$this->getQty(); + $baseRowTotal = $baseRowTotal/$orderItemQty*$this->getQty(); + + $this->setRowTotal($store->roundPrice($rowTotal)); + $this->setBaseRowTotal($store->roundPrice($baseRowTotal)); + + if ($rowTotalInclTax && $baseRowTotalInclTax) { + $this->setRowTotalInclTax($store->roundPrice($rowTotalInclTax/$orderItemQty*$this->getQty())); + $this->setBaseRowTotalInclTax($store->roundPrice($baseRowTotalInclTax/$orderItemQty*$this->getQty())); + } return $this; } + + /** + * Checking if the item is last + * + * @return bool + */ + public function isLast() + { + $orderItem = $this->getOrderItem(); + if ($this->getQty() == $orderItem->getQtyToRefund() && !$orderItem->getQtyToInvoice()) { + return true; + } + return false; + } + } \ No newline at end of file diff --git a/app/code/core/Mage/Sales/Model/Order/Creditmemo/Total/Grand.php b/app/code/core/Mage/Sales/Model/Order/Creditmemo/Total/Grand.php index 22665f8868..3a74009440 100644 --- a/app/code/core/Mage/Sales/Model/Order/Creditmemo/Total/Grand.php +++ b/app/code/core/Mage/Sales/Model/Order/Creditmemo/Total/Grand.php @@ -32,9 +32,6 @@ public function collect(Mage_Sales_Model_Order_Creditmemo $creditmemo) $grandTotal = $creditmemo->getGrandTotal(); $baseGrandTotal = $creditmemo->getBaseGrandTotal(); - $grandTotal+= $creditmemo->getShippingAmount(); - $baseGrandTotal+= $creditmemo->getBaseShippingAmount(); - $grandTotal+= $creditmemo->getAdjustmentPositive(); $baseGrandTotal+= $creditmemo->getBaseAdjustmentPositive(); diff --git a/app/code/core/Mage/Sales/Model/Order/Creditmemo/Total/Subtotal.php b/app/code/core/Mage/Sales/Model/Order/Creditmemo/Total/Subtotal.php index 5b1e3af701..9457c3ca50 100644 --- a/app/code/core/Mage/Sales/Model/Order/Creditmemo/Total/Subtotal.php +++ b/app/code/core/Mage/Sales/Model/Order/Creditmemo/Total/Subtotal.php @@ -37,18 +37,26 @@ public function collect(Mage_Sales_Model_Order_Creditmemo $creditmemo) { $subtotal = 0; $baseSubtotal = 0; + $subtotalInclTax= 0; + $baseSubtotalInclTax = 0; foreach ($creditmemo->getAllItems() as $item) { $item->calcRowTotal(); + if ($item->getOrderItem()->isDummy()) { continue; } - $subtotal+= $item->getRowTotal(); - $baseSubtotal+= $item->getBaseRowTotal(); + + $subtotal += $item->getRowTotal(); + $baseSubtotal += $item->getBaseRowTotal(); + $subtotalInclTax+= $item->getRowTotalInclTax(); + $baseSubtotalInclTax += $item->getBaseRowTotalInclTax(); } $creditmemo->setSubtotal($subtotal); $creditmemo->setBaseSubtotal($baseSubtotal); + $creditmemo->setSubtotalInclTax($subtotalInclTax); + $creditmemo->setBaseSubtotalInclTax($baseSubtotalInclTax); $creditmemo->setGrandTotal($creditmemo->getGrandTotal() + $subtotal); $creditmemo->setBaseGrandTotal($creditmemo->getBaseGrandTotal() + $baseSubtotal); diff --git a/app/code/core/Mage/Sales/Model/Order/Creditmemo/Total/Tax.php b/app/code/core/Mage/Sales/Model/Order/Creditmemo/Total/Tax.php index 435678d8f7..68b29cc03a 100644 --- a/app/code/core/Mage/Sales/Model/Order/Creditmemo/Total/Tax.php +++ b/app/code/core/Mage/Sales/Model/Order/Creditmemo/Total/Tax.php @@ -33,6 +33,7 @@ public function collect(Mage_Sales_Model_Order_Creditmemo $creditmemo) $baseShippingTaxAmount = 0; $totalTax = 0; $baseTotalTax = 0; + $order = $creditmemo->getOrder(); foreach ($creditmemo->getAllItems() as $item) { if ($item->getOrderItem()->isDummy()) { @@ -43,11 +44,20 @@ public function collect(Mage_Sales_Model_Order_Creditmemo $creditmemo) $orderItemQty = $item->getOrderItem()->getQtyOrdered(); if ($orderItemTax && $orderItemQty) { - $tax = $orderItemTax*$item->getQty()/$orderItemQty; - $baseTax = $baseOrderItemTax*$item->getQty()/$orderItemQty; - - $tax = $creditmemo->getStore()->roundPrice($tax); - $baseTax = $creditmemo->getStore()->roundPrice($baseTax); + /** + * Check item tax amount + */ + if ($item->isLast()) { + $tax = $orderItemTax - $item->getOrderItem()->getTaxRefunded(); + $baseTax = $baseOrderItemTax - $item->getOrderItem()->getTaxRefunded(); + } + else { + $tax = $orderItemTax*$item->getQty()/$orderItemQty; + $baseTax = $baseOrderItemTax*$item->getQty()/$orderItemQty; + + $tax = $creditmemo->getStore()->roundPrice($tax); + $baseTax = $creditmemo->getStore()->roundPrice($baseTax); + } $item->setTaxAmount($tax); $item->setBaseTaxAmount($baseTax); @@ -58,37 +68,36 @@ public function collect(Mage_Sales_Model_Order_Creditmemo $creditmemo) } if ($invoice = $creditmemo->getInvoice()) { - $totalTax += $invoice->getShippingTaxAmount(); - $baseTotalTax += $invoice->getBaseShippingTaxAmount(); - - $creditmemo->setShippingTaxAmount($invoice->getShippingTaxAmount()); - $creditmemo->setBaseShippingTaxAmount($invoice->getBaseShippingTaxAmount()); + $totalTax += $invoice->getShippingTaxAmount(); + $baseTotalTax += $invoice->getBaseShippingTaxAmount(); + $shippingTaxAmount = $invoice->getShippingTaxAmount(); + $baseShippingTaxAmount = $invoice->getBaseShippingTaxAmount(); } else { - $shippingAmount = $creditmemo->getOrder()->getBaseShippingAmount(); - $shippingRefundedAmount = $creditmemo->getOrder()->getBaseShippingRefunded(); + $orderShippingAmount = $order->getShippingAmount(); + $baseOrderShippingAmount = $order->getBaseShippingAmount(); + $baseOrderShippingRefundedAmount = $order->getBaseShippingRefunded(); $shippingTaxAmount = 0; $baseShippingTaxAmount = 0; - if (($shippingAmount - $shippingRefundedAmount) > $creditmemo->getShippingAmount()) { - $shippingTaxAmount = $creditmemo->getShippingAmount()*($creditmemo->getOrder()->getShippingTaxAmount()/$shippingAmount); - $baseShippingTaxAmount = $creditmemo->getBaseShippingAmount()*($creditmemo->getOrder()->getBaseShippingTaxAmount()/$shippingAmount); + if (($baseOrderShippingAmount - $baseOrderShippingRefundedAmount) > $creditmemo->getBaseShippingAmount()) { + $shippingTaxAmount = $creditmemo->getShippingAmount()*($order->getShippingTaxAmount()/$orderShippingAmount); + $baseShippingTaxAmount = $creditmemo->getBaseShippingAmount()*($order->getBaseShippingTaxAmount()/$baseOrderShippingAmount); $shippingTaxAmount = $creditmemo->getStore()->roundPrice($shippingTaxAmount); $baseShippingTaxAmount = $creditmemo->getStore()->roundPrice($baseShippingTaxAmount); - } elseif (($shippingAmount - $shippingRefundedAmount) == $creditmemo->getShippingAmount()) { - $shippingTaxAmount = $creditmemo->getOrder()->getShippingTaxAmount() - $creditmemo->getOrder()->getShippingTaxRefunded(); - $baseShippingTaxAmount = $creditmemo->getOrder()->getBaseShippingTaxAmount() - $creditmemo->getOrder()->getBaseShippingTaxRefunded(); + } elseif (($baseOrderShippingAmount - $baseOrderShippingRefundedAmount) == $creditmemo->getBaseShippingAmount()) { + $shippingTaxAmount = $order->getShippingTaxAmount() - $order->getShippingTaxRefunded(); + $baseShippingTaxAmount = $order->getBaseShippingTaxAmount() - $order->getBaseShippingTaxRefunded(); } $totalTax += $shippingTaxAmount; $baseTotalTax += $baseShippingTaxAmount; } + + $allowedTax = $order->getTaxAmount() - $order->getTaxRefunded(); + $allowedBaseTax = $order->getBaseTaxAmount() - $order->getBaseTaxRefunded();; - $tmpBaseTotalTax = $baseTotalTax - ($creditmemo->getOrder()->getBaseTaxRefunded() - $creditmemo->getOrder()->getBaseShippingTaxRefunded()); - - if ($tmpBaseTotalTax<0) { - $baseTotalTax = 0; - $totalTax = 0; - } + $totalTax = min($allowedTax, $totalTax); + $baseTotalTax = min($allowedBaseTax, $baseTotalTax); $creditmemo->setTaxAmount($totalTax); $creditmemo->setBaseTaxAmount($baseTotalTax); diff --git a/app/code/core/Mage/Sales/Model/Order/Invoice/Item.php b/app/code/core/Mage/Sales/Model/Order/Invoice/Item.php index cd35d457fa..68dac8f56d 100644 --- a/app/code/core/Mage/Sales/Model/Order/Invoice/Item.php +++ b/app/code/core/Mage/Sales/Model/Order/Invoice/Item.php @@ -174,11 +174,25 @@ public function cancel() */ public function calcRowTotal() { - $rowTotal = $this->getOrderItem()->getRowTotal()/$this->getOrderItem()->getQtyOrdered()*$this->getQty(); - $baseRowTotal = $this->getOrderItem()->getBaseRowTotal()/$this->getOrderItem()->getQtyOrdered()*$this->getQty(); + $store = $this->getInvoice()->getStore(); + $orderItem = $this->getOrderItem(); + $orderItemQty = $orderItem->getQtyOrdered(); - $this->setRowTotal($this->getInvoice()->getStore()->roundPrice($rowTotal)); - $this->setBaseRowTotal($this->getInvoice()->getStore()->roundPrice($baseRowTotal)); + $rowTotal = $orderItem->getRowTotal(); + $baseRowTotal = $orderItem->getBaseRowTotal(); + $rowTotalInclTax = $orderItem->getRowTotalInclTax(); + $baseRowTotalInclTax= $orderItem->getBaseRowTotalInclTax(); + + $rowTotal = $rowTotal/$orderItemQty*$this->getQty(); + $baseRowTotal = $baseRowTotal/$orderItemQty*$this->getQty(); + + $this->setRowTotal($store->roundPrice($rowTotal)); + $this->setBaseRowTotal($store->roundPrice($baseRowTotal)); + + if ($rowTotalInclTax && $baseRowTotalInclTax) { + $this->setRowTotalInclTax($store->roundPrice($rowTotalInclTax/$orderItemQty*$this->getQty())); + $this->setBaseRowTotalInclTax($store->roundPrice($baseRowTotalInclTax/$orderItemQty*$this->getQty())); + } return $this; } diff --git a/app/code/core/Mage/Sales/Model/Order/Invoice/Total/Subtotal.php b/app/code/core/Mage/Sales/Model/Order/Invoice/Total/Subtotal.php index c8d9d82c69..36b9b4882c 100644 --- a/app/code/core/Mage/Sales/Model/Order/Invoice/Total/Subtotal.php +++ b/app/code/core/Mage/Sales/Model/Order/Invoice/Total/Subtotal.php @@ -35,8 +35,10 @@ class Mage_Sales_Model_Order_Invoice_Total_Subtotal extends Mage_Sales_Model_Ord */ public function collect(Mage_Sales_Model_Order_Invoice $invoice) { - $subtotal = 0; - $baseSubtotal = 0; + $subtotal = 0; + $baseSubtotal = 0; + $subtotalInclTax= 0; + $baseSubtotalInclTax = 0; foreach ($invoice->getAllItems() as $item) { $item->calcRowTotal(); @@ -45,12 +47,16 @@ public function collect(Mage_Sales_Model_Order_Invoice $invoice) continue; } - $subtotal+= $item->getRowTotal(); - $baseSubtotal+= $item->getBaseRowTotal(); + $subtotal += $item->getRowTotal(); + $baseSubtotal += $item->getBaseRowTotal(); + $subtotalInclTax+= $item->getRowTotalInclTax(); + $baseSubtotalInclTax += $item->getBaseRowTotalInclTax(); } $invoice->setSubtotal($subtotal); $invoice->setBaseSubtotal($baseSubtotal); + $invoice->setSubtotalInclTax($subtotalInclTax); + $invoice->setBaseSubtotalInclTax($baseSubtotalInclTax); $invoice->setGrandTotal($invoice->getGrandTotal() + $subtotal); $invoice->setBaseGrandTotal($invoice->getBaseGrandTotal() + $baseSubtotal); diff --git a/app/code/core/Mage/Sales/Model/Order/Invoice/Total/Tax.php b/app/code/core/Mage/Sales/Model/Order/Invoice/Total/Tax.php index c71bacc59a..10af5688ab 100644 --- a/app/code/core/Mage/Sales/Model/Order/Invoice/Total/Tax.php +++ b/app/code/core/Mage/Sales/Model/Order/Invoice/Total/Tax.php @@ -31,7 +31,7 @@ public function collect(Mage_Sales_Model_Order_Invoice $invoice) { $totalTax = 0; $baseTotalTax = 0; - + $order = $invoice->getOrder(); foreach ($invoice->getAllItems() as $item) { $orderItem = $item->getOrderItem(); $orderItemTax = $orderItem->getTaxAmount(); @@ -69,19 +69,24 @@ public function collect(Mage_Sales_Model_Order_Invoice $invoice) /** * Check shipping amount in previus invoices */ - foreach ($invoice->getOrder()->getInvoiceCollection() as $previusInvoice) { + foreach ($order->getInvoiceCollection() as $previusInvoice) { if ($previusInvoice->getShippingAmount() && !$previusInvoice->isCanceled()) { $includeShippingTax = false; } } if ($includeShippingTax) { - $totalTax += $invoice->getOrder()->getShippingTaxAmount(); - $baseTotalTax += $invoice->getOrder()->getBaseShippingTaxAmount(); - $invoice->setShippingTaxAmount($invoice->getOrder()->getShippingTaxAmount()); - $invoice->setBaseShippingTaxAmount($invoice->getOrder()->getBaseShippingTaxAmount()); + $totalTax += $order->getShippingTaxAmount(); + $baseTotalTax += $order->getBaseShippingTaxAmount(); + $invoice->setShippingTaxAmount($order->getShippingTaxAmount()); + $invoice->setBaseShippingTaxAmount($order->getBaseShippingTaxAmount()); } + $allowedTax = $order->getTaxAmount() - $order->getTaxInvoiced(); + $allowedBaseTax = $order->getBaseTaxAmount() - $order->getBaseTaxInvoiced();; + + $totalTax = min($allowedTax, $totalTax); + $baseTotalTax = min($allowedBaseTax, $baseTotalTax); $invoice->setTaxAmount($totalTax); $invoice->setBaseTaxAmount($baseTotalTax); diff --git a/app/code/core/Mage/Sales/Model/Order/Pdf/Abstract.php b/app/code/core/Mage/Sales/Model/Order/Pdf/Abstract.php index 7a43a01410..4b1a899e19 100644 --- a/app/code/core/Mage/Sales/Model/Order/Pdf/Abstract.php +++ b/app/code/core/Mage/Sales/Model/Order/Pdf/Abstract.php @@ -56,6 +56,8 @@ abstract class Mage_Sales_Model_Order_Pdf_Abstract extends Varien_Object */ protected $_pdf; + protected $_defaultTotalModel = 'sales/order_pdf_total_default'; + /** * Retrieve PDF * @@ -166,7 +168,7 @@ protected function insertAddress(&$page, $store = null) protected function _formatAddress($address) { $return = array(); - foreach (split('\|', $address) as $str) { + foreach (explode('|', $address) as $str) { foreach (Mage::helper('core/string')->str_split($str, 65, true, true) as $part) { if (empty($part)) { continue; @@ -378,62 +380,60 @@ protected function _getTotalsList($source) { $totals = Mage::getConfig()->getNode('global/pdf/totals')->asArray(); usort($totals, array($this, '_sortTotalsList')); + $totalModels = array(); + foreach ($totals as $index => $totalInfo) { + if (!empty($totalInfo['model'])) { + $totalModel = Mage::getModel($totalInfo['model']); + if ($totalModel instanceof Mage_Sales_Model_Order_Pdf_Total_Default) { + $totalInfo['model'] = $totalModel; + } else { + Mage::throwException( + Mage::helper('sales')->__('Pdf total model should extend Mage_Sales_Model_Order_Pdf_Total_Default') + ); + } + } else { + $totalModel = Mage::getModel($this->_defaultTotalModel); + } + $totalModel->setData($totalInfo); + $totalModels[] = $totalModel; + } - return $totals; + return $totalModels; } protected function insertTotals($page, $source){ $order = $source->getOrder(); -// $font = $this->_setFontBold($page); - $totals = $this->_getTotalsList($source); - $lineBlock = array( 'lines' => array(), 'height' => 15 ); foreach ($totals as $total) { - $amount = $source->getDataUsingMethod($total['source_field']); - $displayZero = (isset($total['display_zero']) ? $total['display_zero'] : 0); - - if ($amount != 0 || $displayZero) { - $amount = $order->formatPriceTxt($amount); - - if (isset($total['amount_prefix']) && $total['amount_prefix']) { - $amount = "{$total['amount_prefix']}{$amount}"; + $total->setOrder($order) + ->setSource($source); + + if ($total->canDisplay()) { + foreach ($total->getTotalsForDisplay() as $totalData) { + $lineBlock['lines'][] = array( + array( + 'text' => $totalData['label'], + 'feed' => 475, + 'align' => 'right', + 'font_size' => $totalData['font_size'], + 'font' => 'bold' + ), + array( + 'text' => $totalData['amount'], + 'feed' => 565, + 'align' => 'right', + 'font_size' => $totalData['font_size'], + 'font' => 'bold' + ), + ); } - - $fontSize = (isset($total['font_size']) ? $total['font_size'] : 7); - //$page->setFont($font, $fontSize); - - $label = Mage::helper('sales')->__($total['title']) . ':'; - - $lineBlock['lines'][] = array( - array( - 'text' => $label, - 'feed' => 475, - 'align' => 'right', - 'font_size' => $fontSize, - 'font' => 'bold' - ), - array( - 'text' => $amount, - 'feed' => 565, - 'align' => 'right', - 'font_size' => $fontSize, - 'font' => 'bold' - ), - ); - -// $page->drawText($label, 475-$this->widthForStringUsingFontSize($label, $font, $fontSize), $this->y, 'UTF-8'); -// $page->drawText($amount, 565-$this->widthForStringUsingFontSize($amount, $font, $fontSize), $this->y, 'UTF-8'); -// $this->y -=15; } } -// echo '
    ';
    -//        var_dump($lineBlock);
    -
             $page = $this->drawLineBlocks($page, array($lineBlock));
             return $page;
         }
    diff --git a/app/code/core/Mage/Sales/Model/Order/Shipment/Api.php b/app/code/core/Mage/Sales/Model/Order/Shipment/Api.php
    index 22db54aef4..767d61b48d 100644
    --- a/app/code/core/Mage/Sales/Model/Order/Shipment/Api.php
    +++ b/app/code/core/Mage/Sales/Model/Order/Shipment/Api.php
    @@ -149,53 +149,27 @@ public function create($orderIncrementId, $itemsQty = array(), $comment = null,
                  $this->_fault('data_invalid', Mage::helper('sales')->__('Can not do shipment for order.'));
             }
     
    -        $convertor   = Mage::getModel('sales/convert_order');
    -        $shipment    = $convertor->toShipment($order);
              /* @var $shipment Mage_Sales_Model_Order_Shipment */
    -
    -        foreach ($order->getAllItems() as $orderItem) {
    -            if (!$orderItem->getQtyToShip()) {
    -                continue;
    -            }
    -            if ($orderItem->getIsVirtual()) {
    -                continue;
    -            }
    -            
    -            if ((!isset($itemsQty[$orderItem->getId()])) && (count($itemsQty))) {
    -                continue;
    -            }
    -            
    -            $item = $convertor->itemToShipmentItem($orderItem);
    -            if (isset($itemsQty[$orderItem->getId()])) {
    -                $qty = $itemsQty[$orderItem->getId()];
    +        $shipment = $order->prepareShipment($itemsQty);
    +        if ($shipment) {
    +            $shipment->register();
    +            $shipment->addComment($comment, $email && $includeComment);
    +            if ($email) {
    +                $shipment->setEmailSent(true);
                 }
    -            else {
    -                $qty = $orderItem->getQtyToShip();
    +            $shipment->getOrder()->setIsInProcess(true);
    +            try {
    +                $transactionSave = Mage::getModel('core/resource_transaction')
    +                    ->addObject($shipment)
    +                    ->addObject($shipment->getOrder())
    +                    ->save();
    +                $shipment->sendEmail($email, ($includeComment ? $comment : ''));
    +            } catch (Mage_Core_Exception $e) {
    +                $this->_fault('data_invalid', $e->getMessage());
                 }
    -            $item->setQty($qty);
    -        	$shipment->addItem($item);
    -        }
    -        $shipment->register();
    -        $shipment->addComment($comment, $email && $includeComment);
    -
    -        if ($email) {
    -            $shipment->setEmailSent(true);
    +            return $shipment->getIncrementId();
             }
    -
    -        $shipment->getOrder()->setIsInProcess(true);
    -
    -        try {
    -            $transactionSave = Mage::getModel('core/resource_transaction')
    -                ->addObject($shipment)
    -                ->addObject($shipment->getOrder())
    -                ->save();
    -
    -            $shipment->sendEmail($email, ($includeComment ? $comment : ''));
    -        } catch (Mage_Core_Exception $e) {
    -            $this->_fault('data_invalid', $e->getMessage());
    -        }
    -
    -        return $shipment->getIncrementId();
    +        return null;
         }
     
         /**
    diff --git a/app/code/core/Mage/Sales/Model/Order/Shipment/Api/V2.php b/app/code/core/Mage/Sales/Model/Order/Shipment/Api/V2.php
    index f935338d5f..a7a7eff646 100644
    --- a/app/code/core/Mage/Sales/Model/Order/Shipment/Api/V2.php
    +++ b/app/code/core/Mage/Sales/Model/Order/Shipment/Api/V2.php
    @@ -128,48 +128,28 @@ public function create($orderIncrementId, $itemsQty = array(), $comment = null,
                  $this->_fault('data_invalid', Mage::helper('sales')->__('Can not do shipment for order.'));
             }
     
    -        $convertor   = Mage::getModel('sales/convert_order');
             $shipment    = $convertor->toShipment($order);
              /* @var $shipment Mage_Sales_Model_Order_Shipment */
    -
    -        foreach ($order->getAllItems() as $orderItem) {
    -            if (!$orderItem->getQtyToShip()) {
    -                continue;
    -            }
    -            if ($orderItem->getIsVirtual()) {
    -                continue;
    -            }
    -            $item = $convertor->itemToShipmentItem($orderItem);
    -            if (isset($itemsQty[$orderItem->getId()])) {
    -                $qty = $itemsQty[$orderItem->getId()];
    +        $shipment = $order->prepareShipment($itemsQty);
    +        if ($shipment) {
    +            $shipment->register();
    +            $shipment->addComment($comment, $email && $includeComment);
    +            if ($email) {
    +                $shipment->setEmailSent(true);
                 }
    -            else {
    -                $qty = $orderItem->getQtyToShip();
    +            $shipment->getOrder()->setIsInProcess(true);
    +            try {
    +                $transactionSave = Mage::getModel('core/resource_transaction')
    +                    ->addObject($shipment)
    +                    ->addObject($shipment->getOrder())
    +                    ->save();
    +                $shipment->sendEmail($email, ($includeComment ? $comment : ''));
    +            } catch (Mage_Core_Exception $e) {
    +                $this->_fault('data_invalid', $e->getMessage());
                 }
    -            $item->setQty($qty);
    -            $shipment->addItem($item);
    -        }
    -        $shipment->register();
    -        $shipment->addComment($comment, $email && $includeComment);
    -
    -        if ($email) {
    -            $shipment->setEmailSent(true);
    -        }
    -
    -        $shipment->getOrder()->setIsInProcess(true);
    -
    -        try {
    -            $transactionSave = Mage::getModel('core/resource_transaction')
    -                ->addObject($shipment)
    -                ->addObject($shipment->getOrder())
    -                ->save();
    -
    -            $shipment->sendEmail($email, ($includeComment ? $comment : ''));
    -        } catch (Mage_Core_Exception $e) {
    -            $this->_fault('data_invalid', $e->getMessage());
    +            return $shipment->getIncrementId();
             }
    -
    -        return $shipment->getIncrementId();
    +        return null;
         }
     
         /**
    diff --git a/app/code/core/Mage/Sales/Model/Quote.php b/app/code/core/Mage/Sales/Model/Quote.php
    index 6e1b433383..fd717ffee5 100644
    --- a/app/code/core/Mage/Sales/Model/Quote.php
    +++ b/app/code/core/Mage/Sales/Model/Quote.php
    @@ -726,13 +726,18 @@ public function addProduct(Mage_Catalog_Model_Product $product, $request=null)
          * @param   Mage_Catalog_Model_Product $product
          * @return  Mage_Sales_Model_Quote_Item
          */
    -    protected function _addCatalogProduct(Mage_Catalog_Model_Product $product, $qty=1)
    +    protected function _addCatalogProduct(Mage_Catalog_Model_Product $product, $qty = 1)
         {
    -
             $item = $this->getItemByProduct($product);
             if (!$item) {
                 $item = Mage::getModel('sales/quote_item');
                 $item->setQuote($this);
    +            if (Mage::app()->getStore()->isAdmin()) {
    +                $item->setStoreId($this->getStore()->getId());
    +            }
    +            else {
    +                $item->setStoreId(Mage::app()->getStore()->getId());
    +            }
             }
     
             /**
    @@ -909,9 +914,6 @@ public function collectTotals()
                 $address->setSubtotal(0);
                 $address->setBaseSubtotal(0);
     
    -            $address->setSubtotalWithDiscount(0);
    -            $address->setBaseSubtotalWithDiscount(0);
    -
                 $address->setGrandTotal(0);
                 $address->setBaseGrandTotal(0);
     
    @@ -969,11 +971,20 @@ public function collectTotals()
     
         /**
          * Get all quote totals (sorted by priority)
    +     * Metchod process quote states isVirtual and isMultiShipping
          *
          * @return array
          */
         public function getTotals()
         {
    +        /**
    +         * If quote is virtual we are using totals of billing address because
    +         * all items assigned to it
    +         */
    +        if ($this->isVirtual()) {
    +            return $this->getBillingAddress()->getTotals();
    +        }
    +        
             $totals = $this->getShippingAddress()->getTotals();
             foreach ($this->getBillingAddress()->getTotals() as $code => $total) {
                 if (isset($totals[$code])) {
    diff --git a/app/code/core/Mage/Sales/Model/Quote/Address.php b/app/code/core/Mage/Sales/Model/Quote/Address.php
    index 6c617a6eb0..fc53b6d161 100644
    --- a/app/code/core/Mage/Sales/Model/Quote/Address.php
    +++ b/app/code/core/Mage/Sales/Model/Quote/Address.php
    @@ -61,11 +61,11 @@ class Mage_Sales_Model_Quote_Address extends Mage_Customer_Model_Address_Abstrac
         protected $_rates = null;
     
         /**
    -     * Total models array
    +     * Total models collector
          *
    -     * @var array
    +     * @var Mage_Sales_Model_Quote_Address_Totla_Collector
          */
    -    protected $_totalModels;
    +    protected $_totalCollector = null;
     
         /**
          * Total data as array
    @@ -74,6 +74,9 @@ class Mage_Sales_Model_Quote_Address extends Mage_Customer_Model_Address_Abstrac
          */
         protected $_totals = array();
     
    +    protected $_totalAmounts = array();
    +    protected $_baseTotalAmounts = array();
    +
         /**
          * Initialize resource
          */
    @@ -240,7 +243,8 @@ public function getAllItems()
                     }
     
                     if (!$aItem->getQuoteItemImported()) {
    -                    if ($qItem = $this->getQuote()->getItemById($aItem->getQuoteItemId())) {
    +                    $qItem = $this->getQuote()->getItemById($aItem->getQuoteItemId());
    +                    if ($qItem) {
                             $this->addItem($aItem);
                             $aItem->importQuoteItem($qItem);
                         }
    @@ -253,12 +257,7 @@ public function getAllItems()
                     if ($qItem->isDeleted()) {
                         continue;
                     }
    -//                if ($this->getAddressType() == self::TYPE_BILLING && $qItem->getProduct()->getIsVirtual()) {
    -//                    $items[] = $qItem;
    -//                }
    -//                elseif ($this->getAddressType() == self::TYPE_SHIPPING && !$qItem->getProduct()->getIsVirtual()) {
    -//                    $items[] = $qItem;
    -//                }
    +
                     /**
                      * For virtual quote we assign all items to billing address
                      */
    @@ -312,7 +311,8 @@ public function getItemQty($itemId = 0)
                     $qty += $item->getQty();
                 }
             } else {
    -            if ($item = $this->getItemById($itemId)) {
    +            $item = $this->getItemById($itemId);
    +            if ($item) {
                     $qty = $item->getQty();
                 }
             }
    @@ -369,7 +369,8 @@ public function getItemByQuoteItemId($itemId)
          */
         public function removeItem($itemId)
         {
    -        if ($item = $this->getItemById($itemId)) {
    +        $item = $this->getItemById($itemId);
    +        if ($item) {
                 $item->isDeleted(true);
             }
             return $this;
    @@ -567,7 +568,9 @@ public function collectShippingRates()
     
             $this->removeAllShippingRates();
     
    -        if (!$this->getCountryId() && !$this->getPostcode()) {
    +        $havingOptionalZip = Mage::helper('directory')->getCountriesWithOptionalZip();
    +        $postcodeValid = $this->getPostcode() || in_array($this->getCountryId(), $havingOptionalZip);
    +        if (!$this->getCountryId() && !$postcodeValid) {
                 return $this;
             }
     
    @@ -636,30 +639,31 @@ public function collectShippingRates()
             return $this;
         }
     
    +    /**
    +     * Get totals collector model
    +     *
    +     * @return Mage_Sales_Model_Quote_Address_Total_Collector
    +     */
    +    public function getTotalCollector()
    +    {
    +        if ($this->_totalCollector === null) {
    +            $this->_totalCollector = Mage::getSingleton(
    +                'sales/quote_address_total_collector',
    +                array('store'=>$this->getQuote()->getStore())
    +            );
    +        }
    +        return $this->_totalCollector;
    +    }
    +
         /**
          * Retrieve total models
          *
    +     * @deprecated
          * @return array
          */
         public function getTotalModels()
         {
    -        if (!$this->_totalModels) {
    -            $totalsConfig = Mage::getConfig()->getNode('global/sales/quote/totals');
    -            $models = array();
    -            foreach ($totalsConfig->children() as $totalCode=>$totalConfig) {
    -                $sort = Mage::getStoreConfig('sales/totals_sort/'.$totalCode);
    -                while (isset($models[$sort])) {
    -                    $sort++;
    -                }
    -                $class = $totalConfig->getClassName();
    -                if ($class && ($model = Mage::getModel($class))) {
    -                    $models[$sort] = $model->setCode($totalCode);
    -                }
    -            }
    -            ksort($models);
    -            $this->_totalModels = $models;
    -        }
    -        return $this->_totalModels;
    +        return $this->getTotalCollector()->getRetrievers();
         }
     
         /**
    @@ -669,25 +673,21 @@ public function getTotalModels()
          */
         public function collectTotals()
         {
    -        foreach ($this->getTotalModels() as $model) {
    -            if (is_callable(array($model, 'collect'))) {
    -                $model->collect($this);
    -            }
    +        foreach ($this->getTotalCollector()->getCollectors() as $model) {
    +            $model->collect($this);
             }
             return $this;
         }
     
         /**
    -     * Retrieve totals as array
    +     * Get address totals as array
          *
          * @return array
          */
         public function getTotals()
         {
    -        foreach ($this->getTotalModels() as $model) {
    -            if (is_callable(array($model, 'fetch'))) {
    -                $model->fetch($this);
    -            }
    +        foreach ($this->getTotalCollector()->getRetrievers() as $model) {
    +            $model->fetch($this);
             }
             return $this->_totals;
         }
    @@ -706,6 +706,7 @@ public function addTotal($total)
             } elseif ($total instanceof Mage_Sales_Model_Quote_Total) {
                 $totalInstance = $total;
             }
    +        $totalInstance->setAddress($this);
             $this->_totals[$totalInstance->getCode()] = $totalInstance;
             return $this;
         }
    @@ -776,14 +777,16 @@ public function setAppliedTaxes($data)
          */
         public function setShippingAmount($value, $alreadyExclTax = false)
         {
    -        if (Mage::helper('tax')->shippingPriceIncludesTax()) {
    -            $includingTax = Mage::helper('tax')->getShippingPrice($value, true, $this, $this->getQuote()->getCustomerTaxClassId());
    -            if (!$alreadyExclTax) {
    -                $value = Mage::helper('tax')->getShippingPrice($value, false, $this, $this->getQuote()->getCustomerTaxClassId());
    -            }
    -            $this->setShippingTaxAmount($includingTax - $value);
    -        }
             return $this->setData('shipping_amount', $value);
    +//
    +//        if (Mage::helper('tax')->shippingPriceIncludesTax()) {
    +//            $includingTax = Mage::helper('tax')->getShippingPrice($value, true, $this, $this->getQuote()->getCustomerTaxClassId());
    +//            if (!$alreadyExclTax) {
    +//                $value = Mage::helper('tax')->getShippingPrice($value, false, $this, $this->getQuote()->getCustomerTaxClassId());
    +//            }
    +//            $this->setShippingTaxAmount($includingTax - $value);
    +//        }
    +//        return $this->setData('shipping_amount', $value);
         }
     
         /**
    @@ -795,13 +798,117 @@ public function setShippingAmount($value, $alreadyExclTax = false)
          */
         public function setBaseShippingAmount($value, $alreadyExclTax = false)
         {
    -        if (Mage::helper('tax')->shippingPriceIncludesTax()) {
    -            $includingTax = Mage::helper('tax')->getShippingPrice($value, true, $this, $this->getQuote()->getCustomerTaxClassId());
    -            if (!$alreadyExclTax) {
    -                $value = Mage::helper('tax')->getShippingPrice($value, false, $this, $this->getQuote()->getCustomerTaxClassId());
    -            }
    -            $this->setBaseShippingTaxAmount($includingTax - $value);
    -        }
             return $this->setData('base_shipping_amount', $value);
    +//
    +//        if (Mage::helper('tax')->shippingPriceIncludesTax()) {
    +//            $includingTax = Mage::helper('tax')->getShippingPrice($value, true, $this, $this->getQuote()->getCustomerTaxClassId());
    +//            if (!$alreadyExclTax) {
    +//                $value = Mage::helper('tax')->getShippingPrice($value, false, $this, $this->getQuote()->getCustomerTaxClassId());
    +//            }
    +//            $this->setBaseShippingTaxAmount($includingTax - $value);
    +//        }
    +//        return $this->setData('base_shipping_amount', $value);
    +    }
    +
    +    /**
    +     * Set total amount value
    +     *
    +     * @param   string $code
    +     * @param   float $amount
    +     * @return  Mage_Sales_Model_Quote_Address
    +     */
    +    public function setTotalAmount($code, $amount)
    +    {
    +        $this->_totalAmounts[$code] = $amount;
    +        if ($code != 'subtotal') {
    +            $code = $code.'_amount';
    +        }
    +        $this->setData($code, $amount);
    +        return $this;
    +    }
    +
    +    /**
    +     * Set total amount value in base store currency
    +     *
    +     * @param   string $code
    +     * @param   float $amount
    +     * @return  Mage_Sales_Model_Quote_Address
    +     */
    +    public function setBaseTotalAmount($code, $amount)
    +    {
    +        $this->_baseTotalAmounts[$code] = $amount;
    +        if ($code != 'subtotal') {
    +            $code = $code.'_amount';
    +        }
    +        $this->setData('base_'.$code, $amount);
    +        return $this;
    +    }
    +
    +    /**
    +     * Get total amount value by code
    +     *
    +     * @param   string $code
    +     * @return  float
    +     */
    +    public function getTotalAmount($code)
    +    {
    +        if (isset($this->_totalAmounts[$code])) {
    +            return  $this->_totalAmounts[$code];
    +        }
    +        return 0;
    +    }
    +
    +    /**
    +     * Get total amount value by code in base store curncy
    +     *
    +     * @param   string $code
    +     * @return  float
    +     */
    +    public function getBaseTotalAmount($code)
    +    {
    +        if (isset($this->_baseTotalAmounts[$code])) {
    +            return  $this->_baseTotalAmounts[$code];
    +        }
    +        return 0;
    +    }
    +
    +    /**
    +     * Get all total amount values
    +     *
    +     * @return array
    +     */
    +    public function getAllTotalAmounts()
    +    {
    +        return $this->_totalAmounts;
    +    }
    +
    +    /**
    +     * Get all total amount values in base currency
    +     *
    +     * @return array
    +     */
    +    public function getAllBaseTotalAmounts()
    +    {
    +        return $this->_baseTotalAmounts;
    +    }
    +
    +    /**
    +     * Get subtotal amount with applied discount in base currency
    +     *
    +     * @return float
    +     */
    +    public function getBaseSubtotalWithDiscount()
    +    {
    +        return $this->getBaseSubtotal()-$this->getBaseDiscountAmount();
    +    }
    +
    +    /**
    +     * Get subtotal amount with applied discount
    +     *
    +     * @return float
    +     */
    +    public function getSubtotalWithDiscount()
    +    {
    +        return $this->getSubtotal()-$this->getDiscountAmount();
         }
     }
    diff --git a/app/code/core/Mage/Sales/Model/Quote/Address/Total/Abstract.php b/app/code/core/Mage/Sales/Model/Quote/Address/Total/Abstract.php
    index bf23aebc8d..7336a398a2 100644
    --- a/app/code/core/Mage/Sales/Model/Quote/Address/Total/Abstract.php
    +++ b/app/code/core/Mage/Sales/Model/Quote/Address/Total/Abstract.php
    @@ -40,6 +40,7 @@ abstract class Mage_Sales_Model_Quote_Address_Total_Abstract
          * @var string
          */
         protected $_code;
    +    protected $_address = null;
     
         /**
          * Set total code code name
    @@ -64,13 +65,19 @@ public function getCode()
         }
     
         /**
    -     * Collect totals process
    +     * Collect totals process.
          *
          * @param Mage_Sales_Model_Quote_Address $address
          * @return Mage_Sales_Model_Quote_Address_Total_Abstract
          */
         public function collect(Mage_Sales_Model_Quote_Address $address)
         {
    +        $this->_setAddress($address);
    +        /**
    +         * Reset amounts
    +         */
    +        $this->_setAmount(0);
    +        $this->_setBaseAmount(0);
             return $this;
         }
     
    @@ -82,6 +89,102 @@ public function collect(Mage_Sales_Model_Quote_Address $address)
          */
         public function fetch(Mage_Sales_Model_Quote_Address $address)
         {
    +        $this->_setAddress($address);
             return array();
         }
    +
    +    /**
    +     * Set address shich can be used inside totals calculation
    +     *
    +     * @param   Mage_Sales_Model_Quote_Address $address
    +     * @return  Mage_Sales_Model_Quote_Address_Total_Abstract
    +     */
    +    protected function _setAddress(Mage_Sales_Model_Quote_Address $address)
    +    {
    +        $this->_address = $address;
    +        return $this;
    +    }
    +
    +    /**
    +     * Get quote address object
    +     *
    +     * @throw   Mage_Core_Exception if address not declared
    +     * @return  Mage_Sales_Model_Quote_Address
    +     */
    +    protected function _getAddress()
    +    {
    +        if ($this->_address === null) {
    +            Mage::throwException(
    +                Mage::helper('sales')->__('Address model is not defined')
    +            );
    +        }
    +        return $this->_address;
    +    }
    +
    +    /**
    +     * Set total model amount value to address
    +     *
    +     * @param   float $amount
    +     * @return  Mage_Sales_Model_Quote_Address_Total_Abstract
    +     */
    +    protected function _setAmount($amount)
    +    {
    +        $this->_getAddress()->setTotalAmount($this->getCode(), $amount);
    +        return $this;
    +    }
    +
    +    /**
    +     * Set total model base amount value to address
    +     *
    +     * @param   float $amount
    +     * @return  Mage_Sales_Model_Quote_Address_Total_Abstract
    +     */
    +    protected function _setBaseAmount($baseAmount)
    +    {
    +        $this->_getAddress()->setBaseTotalAmount($this->getCode(), $baseAmount);
    +        return $this;
    +    }
    +
    +    /**
    +     * Add total model amount value to address
    +     *
    +     * @param   float $amount
    +     * @return  Mage_Sales_Model_Quote_Address_Total_Abstract
    +     */
    +    protected function _addAmount($amount)
    +    {
    +        $this->_getAddress()->setTotalAmount(
    +            $this->getCode(),
    +            $this->_getAddress()->getTotalAmount($this->getCode())+$amount
    +        );
    +        return $this;
    +    }
    +
    +    /**
    +     * Add total model base amount value to address
    +     *
    +     * @param   float $amount
    +     * @return  Mage_Sales_Model_Quote_Address_Total_Abstract
    +     */
    +    protected function _addBaseAmount($baseAmount)
    +    {
    +        $this->_getAddress()->setBaseTotalAmount(
    +            $this->getCode(),
    +            $this->_getAddress()->getBaseTotalAmount($this->getCode())+$baseAmount
    +        );
    +        return $this;
    +    }
    +
    +    /**
    +     * Process model configuration array.
    +     * This method can be used for changing models apply sort order
    +     *
    +     * @param   array $config
    +     * @param   store $store
    +     * @return  array
    +     */
    +    public function processConfigArray($config, $store)
    +    {
    +        return $config;
    +    }
     }
    diff --git a/app/code/core/Mage/Sales/Model/Quote/Address/Total/Discount.php b/app/code/core/Mage/Sales/Model/Quote/Address/Total/Discount.php
    index f961e0a176..9f620f6400 100644
    --- a/app/code/core/Mage/Sales/Model/Quote/Address/Total/Discount.php
    +++ b/app/code/core/Mage/Sales/Model/Quote/Address/Total/Discount.php
    @@ -20,6 +20,8 @@
      *
      * @category   Mage
      * @package    Mage_Sales
    + * @deprecated Moved to SalesRule Module
    + * @deprecated after 1.3.2.2, functionality moved to salesRule module
      * @copyright  Copyright (c) 2008 Irubin Consulting Inc. DBA Varien (http://www.varien.com)
      * @license    http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
      */
    diff --git a/app/code/core/Mage/Sales/Model/Quote/Address/Total/Grand.php b/app/code/core/Mage/Sales/Model/Quote/Address/Total/Grand.php
    index 0b893c222a..515c9d7462 100644
    --- a/app/code/core/Mage/Sales/Model/Quote/Address/Total/Grand.php
    +++ b/app/code/core/Mage/Sales/Model/Quote/Address/Total/Grand.php
    @@ -27,13 +27,38 @@
     
     class Mage_Sales_Model_Quote_Address_Total_Grand extends Mage_Sales_Model_Quote_Address_Total_Abstract
     {
    +    /**
    +     * Collect grand total address amount
    +     *
    +     * @param   Mage_Sales_Model_Quote_Address $address
    +     * @return  Mage_Sales_Model_Quote_Address_Total_Grand
    +     */
    +    public function collect(Mage_Sales_Model_Quote_Address $address)
    +    {
    +        $grandTotal     = $address->getGrandTotal();
    +        $baseGrandTotal = $address->getBaseGrandTotal();
    +
    +        $totals     = array_sum($address->getAllTotalAmounts());
    +        $baseTotals = array_sum($address->getAllBaseTotalAmounts());
    +
    +        $address->setGrandTotal($grandTotal+$totals);
    +        $address->setBaseGrandTotal($baseGrandTotal+$baseTotals);
    +        return $this;
    +    }
    +
    +    /**
    +     * Add grand total information to adderess
    +     *
    +     * @param   Mage_Sales_Model_Quote_Address $address
    +     * @return  Mage_Sales_Model_Quote_Address_Total_Grand
    +     */
         public function fetch(Mage_Sales_Model_Quote_Address $address)
         {
             $address->addTotal(array(
    -            'code'=>$this->getCode(),
    -            'title'=>Mage::helper('sales')->__('Grand Total'),
    -            'value'=>$address->getGrandTotal(),
    -            'area'=>'footer',
    +            'code'  => $this->getCode(),
    +            'title' => Mage::helper('sales')->__('Grand Total'),
    +            'value' => $address->getGrandTotal(),
    +            'area'  => 'footer',
             ));
             return $this;
         }
    diff --git a/app/code/core/Mage/Sales/Model/Quote/Address/Total/Shipping.php b/app/code/core/Mage/Sales/Model/Quote/Address/Total/Shipping.php
    index 17eba71195..622358db48 100644
    --- a/app/code/core/Mage/Sales/Model/Quote/Address/Total/Shipping.php
    +++ b/app/code/core/Mage/Sales/Model/Quote/Address/Total/Shipping.php
    @@ -27,21 +27,34 @@
     
     class Mage_Sales_Model_Quote_Address_Total_Shipping extends Mage_Sales_Model_Quote_Address_Total_Abstract
     {
    +    public function __construct()
    +    {
    +        $this->setCode('shipping');
    +    }
    +
    +    /**
    +     * Collect totals information about shipping
    +     *
    +     * @param   Mage_Sales_Model_Quote_Address $address
    +     * @return  Mage_Sales_Model_Quote_Address_Total_Shipping
    +     */
         public function collect(Mage_Sales_Model_Quote_Address $address)
         {
    +        parent::collect($address);
    +        
             $oldWeight = $address->getWeight();
             $address->setWeight(0);
    -        $address->setShippingAmount(0);
    -        $address->setBaseShippingAmount(0);
             $address->setFreeMethodWeight(0);
    +        $this->_setAmount(0)
    +            ->_setBaseAmount(0);
     
             $items = $address->getAllItems();
             if (!count($items)) {
                 return $this;
             }
     
    -        $method = $address->getShippingMethod();
    -        $freeAddress = $address->getFreeShipping();
    +        $method     = $address->getShippingMethod();
    +        $freeAddress= $address->getFreeShipping();
     
             $addressWeight      = $address->getWeight();
             $freeMethodWeight   = $address->getFreeMethodWeight();
    @@ -52,10 +65,10 @@ public function collect(Mage_Sales_Model_Quote_Address $address)
                 /**
                  * Skip if this item is virtual
                  */
    -
                 if ($item->getProduct()->isVirtual()) {
                     continue;
                 }
    +            
                 /**
                  * Children weight we calculate for parent
                  */
    @@ -68,11 +81,11 @@ public function collect(Mage_Sales_Model_Quote_Address $address)
                         if ($child->getProduct()->isVirtual()) {
                             continue;
                         }
    -                    $addressQty += $item->getQty()*$child->getQty();
    +                    $addressQty += $child->getTotalQty();
     
                         if (!$item->getProduct()->getWeightType()) {
                             $itemWeight = $child->getWeight();
    -                        $itemQty    = $item->getQty()*$child->getQty();
    +                        $itemQty    = $child->getTotalQty();
                             $rowWeight  = $itemWeight*$itemQty;
                             $addressWeight += $rowWeight;
                             if ($freeAddress || $child->getFreeShipping()===true) {
    @@ -141,8 +154,8 @@ public function collect(Mage_Sales_Model_Quote_Address $address)
     
             $address->collectShippingRates();
     
    -        $address->setShippingAmount(0);
    -        $address->setBaseShippingAmount(0);
    +        $this->_setAmount(0)
    +            ->_setBaseAmount(0);
     
             $method = $address->getShippingMethod();
     
    @@ -150,19 +163,23 @@ public function collect(Mage_Sales_Model_Quote_Address $address)
                 foreach ($address->getAllShippingRates() as $rate) {
                     if ($rate->getCode()==$method) {
                         $amountPrice = $address->getQuote()->getStore()->convertPrice($rate->getPrice(), false);
    -                    $address->setShippingAmount($amountPrice);
    -                    $address->setBaseShippingAmount($rate->getPrice());
    +                    $this->_setAmount($amountPrice);
    +                    $this->_setBaseAmount($rate->getPrice());
                         $address->setShippingDescription($rate->getCarrierTitle().' - '.$rate->getMethodTitle());
                         break;
                     }
                 }
             }
     
    -        $address->setGrandTotal($address->getGrandTotal() + $address->getShippingAmount());
    -        $address->setBaseGrandTotal($address->getBaseGrandTotal() + $address->getBaseShippingAmount());
             return $this;
         }
     
    +    /**
    +     * Add shipping totals information to address object
    +     *
    +     * @param   Mage_Sales_Model_Quote_Address $address
    +     * @return  Mage_Sales_Model_Quote_Address_Total_Shipping
    +     */
         public function fetch(Mage_Sales_Model_Quote_Address $address)
         {
             $amount = $address->getShippingAmount();
    diff --git a/app/code/core/Mage/Sales/Model/Quote/Address/Total/Subtotal.php b/app/code/core/Mage/Sales/Model/Quote/Address/Total/Subtotal.php
    index 4d8c0a392f..ad4ff6e3a7 100644
    --- a/app/code/core/Mage/Sales/Model/Quote/Address/Total/Subtotal.php
    +++ b/app/code/core/Mage/Sales/Model/Quote/Address/Total/Subtotal.php
    @@ -35,13 +35,8 @@ class Mage_Sales_Model_Quote_Address_Total_Subtotal extends Mage_Sales_Model_Quo
          */
         public function collect(Mage_Sales_Model_Quote_Address $address)
         {
    -        /**
    -         * Reset subtotal information
    -         */
    -        $address->setSubtotal(0);
    -        $address->setBaseSubtotal(0);
    +        parent::collect($address);
             $address->setTotalQty(0);
    -        $address->setBaseTotalPriceIncTax(0);
     
             /**
              * Process address items
    @@ -57,8 +52,6 @@ public function collect(Mage_Sales_Model_Quote_Address $address)
             /**
              * Initialize grand totals
              */
    -        $address->setGrandTotal($address->getSubtotal());
    -        $address->setBaseGrandTotal($address->getBaseSubtotal());
             Mage::helper('sales')->checkQuoteAmount($address->getQuote(), $address->getSubtotal());
             Mage::helper('sales')->checkQuoteAmount($address->getQuote(), $address->getBaseSubtotal());
             return $this;
    @@ -104,13 +97,12 @@ protected function _initItem($address, $item)
                 );
                 $item->setPrice($finalPrice);
                 $item->calcRowTotal();
    -        }
    -        else if (!$quoteItem->getParentItem()) {
    +        } else if (!$quoteItem->getParentItem()) {
                 $finalPrice = $product->getFinalPrice($quoteItem->getQty());
                 $item->setPrice($finalPrice);
                 $item->calcRowTotal();
    -            $address->setSubtotal($address->getSubtotal() + $item->getRowTotal());
    -            $address->setBaseSubtotal($address->getBaseSubtotal() + $item->getBaseRowTotal());
    +            $this->_addAmount($item->getRowTotal());
    +            $this->_addBaseAmount($item->getBaseRowTotal());
                 $address->setTotalQty($address->getTotalQty() + $item->getQty());
             }
     
    @@ -142,12 +134,18 @@ protected function _removeItem($address, $item)
             return $this;
         }
     
    +    /**
    +     * Assign subtotal amount and label to address object
    +     *
    +     * @param   Mage_Sales_Model_Quote_Address $address
    +     * @return  Mage_Sales_Model_Quote_Address_Total_Subtotal
    +     */
         public function fetch(Mage_Sales_Model_Quote_Address $address)
         {
             $address->addTotal(array(
    -            'code'=>$this->getCode(),
    -            'title'=>Mage::helper('sales')->__('Subtotal'),
    -            'value'=>$address->getSubtotal()
    +            'code'  => $this->getCode(),
    +            'title' => Mage::helper('sales')->__('Subtotal'),
    +            'value' => $address->getSubtotal()
             ));
             return $this;
         }
    diff --git a/app/code/core/Mage/Sales/Model/Quote/Address/Total/Tax.php b/app/code/core/Mage/Sales/Model/Quote/Address/Total/Tax.php
    index 69a4027ce1..37325ba362 100644
    --- a/app/code/core/Mage/Sales/Model/Quote/Address/Total/Tax.php
    +++ b/app/code/core/Mage/Sales/Model/Quote/Address/Total/Tax.php
    @@ -20,6 +20,7 @@
      *
      * @category   Mage
      * @package    Mage_Sales
    + * @deprecated after 1.3.2.2, functionality moved to tax module
      * @copyright  Copyright (c) 2008 Irubin Consulting Inc. DBA Varien (http://www.varien.com)
      * @license    http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
      */
    diff --git a/app/code/core/Mage/Sales/Model/Quote/Item/Abstract.php b/app/code/core/Mage/Sales/Model/Quote/Item/Abstract.php
    index 1e9d524c78..f59dc2d213 100644
    --- a/app/code/core/Mage/Sales/Model/Quote/Item/Abstract.php
    +++ b/app/code/core/Mage/Sales/Model/Quote/Item/Abstract.php
    @@ -44,6 +44,11 @@ abstract class Mage_Sales_Model_Quote_Item_Abstract extends Mage_Core_Model_Abst
          */
         abstract function getQuote();
     
    +    /**
    +     * Specify parent item id before saving data
    +     *
    +     * @return  Mage_Sales_Model_Quote_Item_Abstract
    +     */
         protected function _beforeSave()
         {
             parent::_beforeSave();
    @@ -121,8 +126,8 @@ public function setMessage($messages) {
         /**
          * Add message of quote item to array of messages
          *
    -     * @param string $message
    -     * @return Mage_Sales_Model_Quote_Item_Abstract
    +     * @param   string $message
    +     * @return  Mage_Sales_Model_Quote_Item_Abstract
          */
         public function addMessage($message)
         {
    @@ -133,7 +138,8 @@ public function addMessage($message)
         /**
          * Get messages array of quote item
          *
    -     * @return array
    +     * @param   bool $string flag for converting messages to string
    +     * @return  array | string
          */
         public function getMessage($string = true)
         {
    @@ -163,15 +169,14 @@ public function checkData()
             $this->setHasError(false);
             $this->unsMessage();
     
    -        $qty = $this->getData('qty');
    +        $qty = $this->_getData('qty');
    +        
             try {
                 $this->setQty($qty);
    -        }
    -        catch (Mage_Core_Exception $e){
    +        } catch (Mage_Core_Exception $e){
                 $this->setHasError(true);
                 $this->setMessage($e->getMessage());
    -        }
    -        catch (Exception $e){
    +        } catch (Exception $e){
                 $this->setHasError(true);
                 $this->setMessage(Mage::helper('sales')->__('Item qty declare error'));
             }
    @@ -182,7 +187,9 @@ public function checkData()
                 $this->setHasError(true);
                 $this->setMessage($e->getMessage());
                 $this->getQuote()->setHasError(true);
    -            $this->getQuote()->addMessage(Mage::helper('sales')->__('Some of the products below don\'t have all the required options. Please remove them and add again with all the required options.'));
    +            $this->getQuote()->addMessage(
    +                Mage::helper('sales')->__('Some of the products below don\'t have all the required options. Please remove them and add again with all the required options.')
    +            );
             } catch (Exception $e) {
                 $this->setHasError(true);
                 $this->setMessage(Mage::helper('sales')->__('Item options declare error'));
    @@ -193,6 +200,29 @@ public function checkData()
             return $this;
         }
     
    +    /**
    +     * Get original (not related with parent item) item quantity
    +     *
    +     * @return  int|float
    +     */
    +    public function getQty()
    +    {
    +        return $this->_getData('qty');
    +    }
    +
    +    /**
    +     * Get total item quantity (include parent item relation)
    +     *
    +     * @return  int|float
    +     */
    +    public function getTotalQty()
    +    {
    +        if ($this->getParentItem()) {
    +            return $this->getQty()*$this->getParentItem()->getQty();
    +        }
    +        return $this->getQty();
    +    }
    +
         /**
          * Calculate item row total price
          *
    @@ -200,31 +230,207 @@ public function checkData()
          */
         public function calcRowTotal()
         {
    -        $qty = $this->getQty();
    +        $qty        = $this->getTotalQty();
    +        $total      = $this->getCalculationPrice()*$qty;
    +        $baseTotal  = $this->getBaseCalculationPrice()*$qty;
     
    -        if ($this->getParentItem()) {
    -            $qty = $qty*$this->getParentItem()->getQty();
    +        $this->setRowTotal($this->getStore()->roundPrice($total));
    +        $this->setBaseRowTotal($this->getStore()->roundPrice($baseTotal));
    +        return $this;
    +    }
    +
    +    /**
    +     * Get item price used for quote calculation process.
    +     * This method get custom price (if ut defined) or original product final price
    +     *
    +     * @return float
    +     */
    +    public function getCalculationPrice()
    +    {
    +        $price = $this->_getData('calculation_price');
    +        if (is_null($price)) {
    +            if ($this->hasCustomPrice()) {
    +                $price = $this->getCustomPrice();
    +            }
    +            else {
    +                $price = $this->getOriginalPrice();
    +            }
    +            $this->setData('calculation_price', $price);
             }
    +        return $price;
    +    }
     
    -        if ($rowTotal = $this->getRowTotalExcTax()) {
    -            $baseTotal = $rowTotal;
    -            $total = $this->getStore()->convertPrice($baseTotal);
    +    /**
    +     * Get calculation price used for quote calculation in base currency.
    +     *
    +     * @return float
    +     */
    +    public function getBaseCalculationPrice()
    +    {
    +        if (!$this->hasBaseCalculationPrice()) {
    +            if ($this->hasCustomPrice()) {
    +                $price = (float) $this->getCustomPrice();
    +                if ($price) {
    +                    $rate = $this->getStore()->convertPrice($price) / $price;
    +                    $price = $price / $rate;
    +                }
    +            } else {
    +                $price = $this->getPrice();
    +            }
    +            $this->setBaseCalculationPrice($price);
             }
    -        else {
    -            $total      = $this->getCalculationPrice()*$qty;
    -            $baseTotal  = $this->getBaseCalculationPrice()*$qty;
    +        return $this->_getData('base_calculation_price');
    +    }
    +
    +    /**
    +     * Get original price (retrieved from product) for item.
    +     * Original price value is in current selected currency
    +     *
    +     * @return float
    +     */
    +    public function getOriginalPrice()
    +    {
    +        $price = $this->_getData('original_price');
    +        if (is_null($price)) {
    +            $price = $this->getStore()->convertPrice($this->getPrice());
    +            $this->setData('original_price', $price);
             }
    +        return $price;
    +    }
     
    -        $this->setRowTotal($this->getStore()->roundPrice($total));
    -        $this->setBaseRowTotal($this->getStore()->roundPrice($baseTotal));
    +    /**
    +     * Set original price to item (calculation price will be refreshed too)
    +     *
    +     * @param   float $price
    +     * @return  Mage_Sales_Model_Quote_Item_Abstract
    +     */
    +    public function setOriginalPrice($price)
    +    {
    +        $this->setCalculationPrice(null);
    +        return $this->setData('original_price', $price);
    +    }
    +
    +    /**
    +     * Get Original item price (got from product) in base website currency
    +     *
    +     * @return float
    +     */
    +    public function getBaseOriginalPrice()
    +    {
    +        return $this->getPrice();
    +    }
    +
    +    /**
    +     * Get item price (item price always exclude price)
    +     *
    +     * @return decimal
    +     */
    +    public function getPrice()
    +    {
    +        return $this->_getData('price');
    +    }
     
    +    /**
    +     * Specify custom item price (used in case whe we have apply not product price to item)
    +     *
    +     * @param   float $value
    +     * @return  Mage_Sales_Model_Quote_Item_Abstract
    +     */
    +    public function setCustomPrice($value)
    +    {
    +        return $this->setData('custom_price', $value);
    +    }
    +
    +    /**
    +     * Specify item price (base calculation price will be refreshed too)
    +     *
    +     * @param   float $value
    +     * @return  Mage_Sales_Model_Quote_Item_Abstract
    +     */
    +    public function setPrice($value)
    +    {
    +        $this->setBaseCalculationPrice(null);
    +        return $this->setData('price', $value);
    +    }
    +
    +    /**
    +     * Clone quote item
    +     *
    +     * @return Mage_Sales_Model_Quote_Item
    +     */
    +    public function __clone()
    +    {
    +        $this->setId(null);
    +        $this->_parentItem  = null;
    +        $this->_children    = array();
    +        $this->_messages    = array();
             return $this;
         }
    +
    +    /**
    +     * Checking if there children calculated or parent item
    +     * when we have parent quote item and its children
    +     *
    +     * @return bool
    +     */
    +    public function isChildrenCalculated() {
    +        if ($this->getParentItem()) {
    +            $calculate = $this->getParentItem()->getProduct()->getPriceType();
    +        } else {
    +            $calculate = $this->getProduct()->getPriceType();
    +        }
    +
    +        if ((null !== $calculate) && (int)$calculate === Mage_Catalog_Model_Product_Type_Abstract::CALCULATE_CHILD) {
    +            return true;
    +        }
    +        return false;
    +    }
    +
    +
    +    /**
    +     * Checking can we ship product separatelly (each child separately)
    +     * or each parent product item can be shipped only like one item
    +     *
    +     * @return bool
    +     */
    +    public function isShipSeparately() {
    +        if ($this->getParentItem()) {
    +            $shipmentType = $this->getParentItem()->getProduct()->getShipmentType();
    +        } else {
    +            $shipmentType = $this->getProduct()->getShipmentType();
    +        }
    +
    +        if ((null !== $shipmentType) && (int)$shipmentType === Mage_Catalog_Model_Product_Type_Abstract::SHIPMENT_SEPARATELY) {
    +            return true;
    +        }
    +        return false;
    +    }
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
     
         /**
          * Calculate item tax amount
          *
    -     * @return Mage_Sales_Model_Quote_Item
    +     * @deprecated logic moved to tax totals calculation model
    +     * @return  Mage_Sales_Model_Quote_Item
          */
         public function calcTaxAmount()
         {
    @@ -279,72 +485,16 @@ public function calcTaxAmount()
             return $this;
         }
     
    -    /**
    -     * Retrieve item price used for calculation
    -     *
    -     * @return unknown
    -     */
    -    public function getCalculationPrice()
    -    {
    -        $price = $this->getData('calculation_price');
    -        if (is_null($price)) {
    -            if ($this->hasCustomPrice()) {
    -                $price = $this->getCustomPrice();
    -            }
    -            else {
    -                $price = $this->getOriginalPrice();
    -            }
    -            $this->setData('calculation_price', $price);
    -        }
    -        return $price;
    -    }
    -
    -    /**
    -     * Retrieve calculation price in base currency
    -     *
    -     * @return unknown
    -     */
    -    public function getBaseCalculationPrice()
    -    {
    -        if (!$this->hasBaseCalculationPrice()) {
    -            if ($this->hasCustomPrice()) {
    -                if ($price = (float) $this->getCustomPrice()) {
    -                    $rate = $this->getStore()->convertPrice($price) / $price;
    -                    $price = $price / $rate;
    -                }
    -                else {
    -                    $price = $this->getCustomPrice();
    -                }
    -            } else {
    -                $price = $this->getPrice();
    -            }
    -            $this->setBaseCalculationPrice($price);
    -        }
    -        return $this->getData('base_calculation_price');
    -    }
    -
    -    /**
    -     * Retrieve original price (retrieved from product) for item
    -     *
    -     * @return float
    -     */
    -    public function getOriginalPrice()
    -    {
    -        $price = $this->getData('original_price');
    -        if (is_null($price)) {
    -            $price = $this->getStore()->convertPrice($this->getPrice());
    -            $this->setData('original_price', $price);
    -        }
    -        return $price;
    -    }
    -
         /**
          * Get item tax amount
          *
    -     * @return decimal
    +     * @deprecated
    +     * @return  decimal
          */
         public function getTaxAmount()
         {
    +        return $this->_getData('tax_amount');
    +
             $priceType = $this->getProduct()->getPriceType();
             if ($this->getHasChildren() && (null !== $priceType) && (int)$priceType === Mage_Catalog_Model_Product_Type_Abstract::CALCULATE_CHILD) {
                 $amount = 0;
    @@ -358,13 +508,17 @@ public function getTaxAmount()
             }
         }
     
    +
         /**
          * Get item base tax amount
          *
    +     * @deprecated
          * @return decimal
          */
         public function getBaseTaxAmount()
         {
    +        return $this->_getData('base_tax_amount');
    +        
             $priceType = $this->getProduct()->getPriceType();
             if ($this->getHasChildren() && (null !== $priceType) && (int)$priceType === Mage_Catalog_Model_Product_Type_Abstract::CALCULATE_CHILD) {
                 $baseAmount = 0;
    @@ -381,45 +535,9 @@ public function getBaseTaxAmount()
         /**
          * Get item price (item price always exclude price)
          *
    +     * @deprecated
          * @return decimal
          */
    -    public function getPrice()
    -    {
    -        $priceType = $this->getProduct()->getPriceType();
    -        if ($this->getHasChildren() && (null !== $priceType) && (int)$priceType === Mage_Catalog_Model_Product_Type_Abstract::CALCULATE_CHILD) {
    -            $price = $this->_getData('price');
    -            /*
    -            foreach ($this->getChildren() as $child) {
    -                $price+= $child->getPrice()*$child->getQty();
    -            }
    -            */
    -            return $price;
    -        }
    -        else {
    -            return $this->_getData('price');
    -        }
    -    }
    -
    -    public function setCustomPrice($value)
    -    {
    -        if (is_null($value)) {
    -            return $this->setData('custom_price', $value);
    -        }
    -
    -        $excludingTax = $this->_calculatePrice($value, Mage::helper('tax')->applyTaxOnCustomPrice());
    -        $this->setData('original_custom_price', $value);
    -        return $this->setData('custom_price', $excludingTax);
    -    }
    -
    -    public function setPrice($value)
    -    {
    -        $saveTaxes = true;
    -        if (Mage::helper('tax')->applyTaxOnCustomPrice() && $this->hasCustomPrice()) {
    -            $saveTaxes = false;
    -        }
    -        return $this->setData('price', $this->_calculatePrice($value, $saveTaxes));
    -    }
    -
         protected function _calculatePrice($value, $saveTaxes = true)
         {
             $store = $this->getQuote()->getStore();
    @@ -513,56 +631,4 @@ protected function _calculatePrice($value, $saveTaxes = true)
     
             return $value;
         }
    -
    -    /**
    -     * Clone quote item
    -     *
    -     * @return Mage_Sales_Model_Quote_Item
    -     */
    -    public function __clone()
    -    {
    -        $this->setId(null);
    -        $this->_parentItem  = null;
    -        $this->_children    = array();
    -        return $this;
    -    }
    -
    -    /**
    -     * Checking if there children calculated or parent item
    -     * when we have parent quote item and its children
    -     *
    -     * @return bool
    -     */
    -    public function isChildrenCalculated() {
    -        if ($this->getParentItem()) {
    -            $calculate = $this->getParentItem()->getProduct()->getPriceType();
    -        } else {
    -            $calculate = $this->getProduct()->getPriceType();
    -        }
    -
    -        if ((null !== $calculate) && (int)$calculate === Mage_Catalog_Model_Product_Type_Abstract::CALCULATE_CHILD) {
    -            return true;
    -        }
    -        return false;
    -    }
    -
    -
    -    /**
    -     * Checking can we ship product separatelly (each child separately)
    -     * or each parent product item can be shipped only like one item
    -     *
    -     * @return bool
    -     */
    -    public function isShipSeparately() {
    -        if ($this->getParentItem()) {
    -            $shipmentType = $this->getParentItem()->getProduct()->getShipmentType();
    -        } else {
    -            $shipmentType = $this->getProduct()->getShipmentType();
    -        }
    -
    -        if ((null !== $shipmentType) && (int)$shipmentType === Mage_Catalog_Model_Product_Type_Abstract::SHIPMENT_SEPARATELY) {
    -            return true;
    -        }
    -        return false;
    -    }
    -}
    \ No newline at end of file
    +}
    diff --git a/app/code/core/Mage/Sales/Model/Quote/Payment.php b/app/code/core/Mage/Sales/Model/Quote/Payment.php
    index 4cd8b95e3d..f1dbf5a901 100644
    --- a/app/code/core/Mage/Sales/Model/Quote/Payment.php
    +++ b/app/code/core/Mage/Sales/Model/Quote/Payment.php
    @@ -66,11 +66,13 @@ public function getQuote()
         }
     
         /**
    -     * Import data
    +     * Import data array to payment method object,
    +     * Method calls quote totals collect because payment method availability
    +     * can be related to quote totals
          *
    -     * @param array $data
    -     * @throws Mage_Core_Exception
    -     * @return Mage_Sales_Model_Quote_Payment
    +     * @param   array $data
    +     * @throws  Mage_Core_Exception
    +     * @return  Mage_Sales_Model_Quote_Payment
          */
         public function importData(array $data)
         {
    @@ -86,6 +88,12 @@ public function importData(array $data)
             $this->setMethod($data->getMethod());
             $method = $this->getMethodInstance();
     
    +        /**
    +         * Payment avalability related with quote totals.
    +         * We have recollect quote totals before checking
    +         */
    +        $this->getQuote()->collectTotals();
    +        
             if (!$method->isAvailable($this->getQuote())) {
                 Mage::throwException(Mage::helper('sales')->__('Requested Payment Method is not available'));
             }
    @@ -117,17 +125,31 @@ protected function _beforeSave()
             return parent::_beforeSave();
         }
     
    +    /**
    +     * Checkout redirect URL getter
    +     *
    +     * @return string
    +     */
         public function getCheckoutRedirectUrl()
         {
             $method = $this->getMethodInstance();
    -
    -        return $method ? $method->getCheckoutRedirectUrl() : false;
    +        if ($method) {
    +            return $method->getCheckoutRedirectUrl();
    +        }
    +        return '';
         }
     
    +    /**
    +     * Checkout order place redirect URL getter
    +     *
    +     * @return string
    +     */
         public function getOrderPlaceRedirectUrl()
         {
             $method = $this->getMethodInstance();
    -
    -        return $method ? $method->getOrderPlaceRedirectUrl() : false;
    +        if ($method) {
    +            return $method->getOrderPlaceRedirectUrl();
    +        }
    +        return '';
         }
    -}
    \ No newline at end of file
    +}
    diff --git a/app/code/core/Mage/Sales/doc/order.txt b/app/code/core/Mage/Sales/doc/order.txt
    index a8001294a2..678b8c17f6 100644
    --- a/app/code/core/Mage/Sales/doc/order.txt
    +++ b/app/code/core/Mage/Sales/doc/order.txt
    @@ -20,7 +20,6 @@
             billing_address_id
             shipping_address_id
             coupon_code
    -        giftcert_code
             weight
             shipping_method
             shipping_description
    @@ -28,7 +27,6 @@
             tax_amount
             shipping_amount
             discount_amount
    -        giftcert_amount
             custbalance_amount
             grand_total
             total_paid
    diff --git a/app/code/core/Mage/Sales/doc/quote.txt b/app/code/core/Mage/Sales/doc/quote.txt
    index 1774ccbd2a..d6b8988d23 100644
    --- a/app/code/core/Mage/Sales/doc/quote.txt
    +++ b/app/code/core/Mage/Sales/doc/quote.txt
    @@ -9,7 +9,6 @@
             billing_address_id
             converted_at
             coupon_code
    -        giftcert_code
             custbalance_amount
             global_currency_code
             base_currency_code
    diff --git a/app/code/core/Mage/Sales/etc/config.xml b/app/code/core/Mage/Sales/etc/config.xml
    index 67389fa6e0..d68e0d08b2 100644
    --- a/app/code/core/Mage/Sales/etc/config.xml
    +++ b/app/code/core/Mage/Sales/etc/config.xml
    @@ -28,7 +28,7 @@
     
         
             
    -            0.9.38
    +            0.9.40
             
         
         
    @@ -99,7 +99,6 @@
                     base_to_order_rate
     
                     *
    -                *
                     *
                     *
                     *
    @@ -117,7 +116,6 @@
                     *
                     *
                     *
    -                *
                     *
                     *
     
    @@ -126,7 +124,6 @@
                     *
                     *
                     *
    -                *
                     *
                     *
     
    @@ -219,7 +216,6 @@
                     **
     
                     *
    -                *
                     *
     
                     *
    @@ -232,14 +228,12 @@
                     *
                     *
                     *
    -                *
                     *
     
                     *
                     *
                     *
                     *
    -                *
                     *
     
                     *
    @@ -499,23 +493,11 @@
                             sales/quote_address_total_subtotal
                             grand_total
                         
    -                    
    -                        sales/quote_address_total_discount
    -                        subtotal
    -                        grand_total,shipping
    -                    
                         
                             sales/quote_address_total_shipping
    -                        subtotal,discount
    +                        subtotal,freeshipping
                             grand_total
                         
    -                    
    -                        sales/quote_address_total_tax
    -                        subtotal,shipping
    -                        grand_total
    -                        checkout/total_tax
    -                        adminhtml/sales_order_create_totals_tax
    -                    
                         
                             sales/quote_address_total_grand
                             subtotal
    @@ -626,6 +608,9 @@
                         
                             sales/order_creditmemo_total_subtotal
                         
    +                    
    +                        sales/order_creditmemo_total_shipping
    +                    
                         
                             sales/order_creditmemo_total_tax
                         
    @@ -666,13 +651,6 @@
                         0
                         200
                     
    -                
    -                    Tax
    -                    tax_amount
    -                    7
    -                    0
    -                    300
    -                
                     
                         Shipping & Handling
                         shipping_amount
    @@ -685,21 +663,21 @@
                         adjustment_positive
                         7
                         0
    -                    100
    +                    500
                     
                     
                         Adjustment Fee
                         adjustment_negative
                         7
                         0
    -                    500
    +                    600
                     
                     
                         Grand Total
                         grand_total
                         8
                         1
    -                    600
    +                    700
                     
                 
             
    diff --git a/app/code/core/Mage/Sales/sql/sales_setup/mysql4-install-0.7.0.php b/app/code/core/Mage/Sales/sql/sales_setup/mysql4-install-0.7.0.php
    index 8f190e0432..1a9583158d 100644
    --- a/app/code/core/Mage/Sales/sql/sales_setup/mysql4-install-0.7.0.php
    +++ b/app/code/core/Mage/Sales/sql/sales_setup/mysql4-install-0.7.0.php
    @@ -68,22 +68,6 @@
     
     insert  into {$this->getTable('sales_discount_coupon')}(`coupon_id`,`coupon_code`,`discount_percent`,`discount_fixed`,`is_active`,`from_date`,`to_date`,`min_subtotal`,`limit_products`,`limit_categories`,`limit_attributes`) values (1,'test',10.0000,0.0000,1,'0000-00-00 00:00:00','0000-00-00 00:00:00',0.0000,'','','');
     
    -/*Table structure for table `sales_giftcert` */
    -
    --- DROP TABLE IF EXISTS {$this->getTable('sales_giftcert')};
    -
    -CREATE TABLE {$this->getTable('sales_giftcert')} (
    -  `giftcert_id` int(10) unsigned NOT NULL auto_increment,
    -  `giftcert_code` varchar(50) NOT NULL default '',
    -  `balance_amount` decimal(12,4) NOT NULL default '0.0000',
    -  PRIMARY KEY  (`giftcert_id`),
    -  UNIQUE KEY `gift_code` (`giftcert_code`)
    -) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    -
    -/*Data for the table `sales_giftcert` */
    -
    -insert  into {$this->getTable('sales_giftcert')}(`giftcert_id`,`giftcert_code`,`balance_amount`) values (1,'test',20.0000);
    -
     /*Table structure for table `sales_invoice_entity` */
     
     -- DROP TABLE IF EXISTS {$this->getTable('sales_invoice_entity')};
    diff --git a/app/code/core/Mage/Sales/sql/sales_setup/mysql4-install-0.8.11.php b/app/code/core/Mage/Sales/sql/sales_setup/mysql4-install-0.8.11.php
    index 332686093b..374bda5e4f 100644
    --- a/app/code/core/Mage/Sales/sql/sales_setup/mysql4-install-0.8.11.php
    +++ b/app/code/core/Mage/Sales/sql/sales_setup/mysql4-install-0.8.11.php
    @@ -64,15 +64,6 @@
       PRIMARY KEY  (`coupon_id`)
     ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
     
    --- DROP TABLE IF EXISTS `{$installer->getTable('sales_giftcert')}`;
    -CREATE TABLE `{$installer->getTable('sales_giftcert')}` (
    -  `giftcert_id` int(10) unsigned NOT NULL auto_increment,
    -  `giftcert_code` varchar(50) NOT NULL default '',
    -  `balance_amount` decimal(12,4) NOT NULL default '0.0000',
    -  PRIMARY KEY  (`giftcert_id`),
    -  UNIQUE KEY `gift_code` (`giftcert_code`)
    -) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    -
     -- DROP TABLE IF EXISTS `{$installer->getTable('sales_order_entity')}`;
     CREATE TABLE `{$installer->getTable('sales_order_entity')}` (
       `entity_id` int(10) unsigned NOT NULL auto_increment,
    diff --git a/app/code/core/Mage/Sales/sql/sales_setup/mysql4-upgrade-0.8.14-0.8.15.php b/app/code/core/Mage/Sales/sql/sales_setup/mysql4-upgrade-0.8.14-0.8.15.php
    index f30a7f55dc..05111f5873 100644
    --- a/app/code/core/Mage/Sales/sql/sales_setup/mysql4-upgrade-0.8.14-0.8.15.php
    +++ b/app/code/core/Mage/Sales/sql/sales_setup/mysql4-upgrade-0.8.14-0.8.15.php
    @@ -63,7 +63,6 @@
         `checkout_method` varchar(255) NOT NULL default '',
         `password_hash` varchar(255) NOT NULL default '',
         `coupon_code` varchar(255) NOT NULL default '',
    -    `giftcert_code` varchar(255) NOT NULL default '',
         `base_currency_code` varchar(255) NOT NULL default '',
         `store_currency_code` varchar(255) NOT NULL default '',
         `quote_currency_code` varchar(255) NOT NULL default '',
    diff --git a/app/code/core/Mage/Sales/sql/sales_setup/mysql4-upgrade-0.8.17-0.8.18.php b/app/code/core/Mage/Sales/sql/sales_setup/mysql4-upgrade-0.8.17-0.8.18.php
    index 2881a61b27..d6d565013f 100644
    --- a/app/code/core/Mage/Sales/sql/sales_setup/mysql4-upgrade-0.8.17-0.8.18.php
    +++ b/app/code/core/Mage/Sales/sql/sales_setup/mysql4-upgrade-0.8.17-0.8.18.php
    @@ -50,7 +50,6 @@
         change `checkout_method` `checkout_method` varchar (255)  NULL  COLLATE utf8_general_ci ,
         change `password_hash` `password_hash` varchar (255)  NULL  COLLATE utf8_general_ci ,
         change `coupon_code` `coupon_code` varchar (255)  NULL  COLLATE utf8_general_ci ,
    -    change `giftcert_code` `giftcert_code` varchar (255)  NULL  COLLATE utf8_general_ci ,
         change `base_currency_code` `base_currency_code` varchar (255)  NULL  COLLATE utf8_general_ci ,
         change `store_currency_code` `store_currency_code` varchar (255)  NULL  COLLATE utf8_general_ci ,
         change `quote_currency_code` `quote_currency_code` varchar (255)  NULL  COLLATE utf8_general_ci ,
    diff --git a/app/code/core/Mage/Sales/sql/sales_setup/mysql4-upgrade-0.8.29-0.9.0.php b/app/code/core/Mage/Sales/sql/sales_setup/mysql4-upgrade-0.8.29-0.9.0.php
    index 543c8f1780..f05839bd0d 100644
    --- a/app/code/core/Mage/Sales/sql/sales_setup/mysql4-upgrade-0.8.29-0.9.0.php
    +++ b/app/code/core/Mage/Sales/sql/sales_setup/mysql4-upgrade-0.8.29-0.9.0.php
    @@ -349,6 +349,5 @@
     
     DROP TABLE IF EXISTS {$this->getTable('sales_counter')};
     DROP TABLE IF EXISTS {$this->getTable('sales_discount_coupon')};
    -DROP TABLE IF EXISTS {$this->getTable('sales_giftcert')};
     ");
     $installer->endSetup();
    \ No newline at end of file
    diff --git a/app/code/core/Mage/SalesRule/Model/Mysql4/Rule.php b/app/code/core/Mage/SalesRule/Model/Mysql4/Rule.php
    index fd20e96f2e..4adb97a875 100644
    --- a/app/code/core/Mage/SalesRule/Model/Mysql4/Rule.php
    +++ b/app/code/core/Mage/SalesRule/Model/Mysql4/Rule.php
    @@ -65,4 +65,66 @@ public function getCustomerUses($rule, $customerId)
                 ->where('customer_id=?', $customerId);
             return $read->fetchOne($select);
         }
    +
    +    /**
    +     * Save rule labels for different store views
    +     *
    +     * @param   int $ruleId
    +     * @param   array $labels
    +     * @return  Mage_SalesRule_Model_Mysql4_Rule
    +     */
    +    public function saveStoreLabels($ruleId, $labels)
    +    {
    +        $delete = array();
    +        $save = array();
    +        $table = $this->getTable('salesrule/label');
    +        $adapter = $this->_getWriteAdapter();
    +        
    +        foreach ($labels as $storeId => $label) {
    +            if (Mage::helper('core/string')->strlen($label)) {
    +                $data = array('rule_id' => $ruleId, 'store_id' => $storeId, 'label' => $label);
    +                $adapter->insertOnDuplicate($table, $data, array('label'));
    +            } else {
    +                $delete[] = $storeId;
    +            }
    +        }
    +
    +        if (!empty($delete)) {
    +            $adapter->delete($table,
    +                $adapter->quoteInto('rule_id=? AND ', $ruleId) . $adapter->quoteInto('store_id IN (?)', $delete)
    +            );
    +        }
    +        return $this;
    +    }
    +
    +    /**
    +     * Get all existing rule labels
    +     *
    +     * @param   int $ruleId
    +     * @return  array
    +     */
    +    public function getStoreLabels($ruleId)
    +    {
    +        $select = $this->_getReadAdapter()->select()
    +            ->from($this->getTable('salesrule/label'), array('store_id', 'label'))
    +            ->where('rule_id=?', $ruleId);
    +        return $this->_getReadAdapter()->fetchPairs($select);
    +    }
    +
    +    /**
    +     * Get rule label by specific store id
    +     *
    +     * @param   int $ruleId
    +     * @param   int $storeId
    +     * @return  string
    +     */
    +    public function getStoreLabel($ruleId, $storeId)
    +    {
    +        $select = $this->_getReadAdapter()->select()
    +            ->from($this->getTable('salesrule/label'), 'label')
    +            ->where('rule_id=?', $ruleId)
    +            ->where('store_id IN(?)', array($storeId, 0))
    +            ->order('store_id DESC');
    +        return $this->_getReadAdapter()->fetchOne($select);
    +    }
     }
    \ No newline at end of file
    diff --git a/app/code/core/Mage/SalesRule/Model/Observer.php b/app/code/core/Mage/SalesRule/Model/Observer.php
    index 9ab232c475..310394a297 100644
    --- a/app/code/core/Mage/SalesRule/Model/Observer.php
    +++ b/app/code/core/Mage/SalesRule/Model/Observer.php
    @@ -29,6 +29,13 @@ class Mage_SalesRule_Model_Observer
     {
         protected $_validator;
     
    +    /**
    +     * Get quote item validator/processor object
    +     *
    +     * @deprecated
    +     * @param   Varien_Event $event
    +     * @return  Mage_SalesRule_Model_Validator
    +     */
         public function getValidator($event)
         {
             if (!$this->_validator) {
    @@ -38,6 +45,12 @@ public function getValidator($event)
             return $this->_validator;
         }
     
    +    /**
    +     * Process quote item (apply discount to item)
    +     *
    +     * @deprecated process call movet to total model
    +     * @param Varien_Event_Observer $observer
    +     */
         public function sales_quote_address_discount_item($observer)
         {
             $this->getValidator($observer->getEvent())
    diff --git a/app/code/core/Mage/SalesRule/Model/Rule.php b/app/code/core/Mage/SalesRule/Model/Rule.php
    index 432efeb399..740ae254d5 100644
    --- a/app/code/core/Mage/SalesRule/Model/Rule.php
    +++ b/app/code/core/Mage/SalesRule/Model/Rule.php
    @@ -30,6 +30,8 @@ class Mage_SalesRule_Model_Rule extends Mage_Rule_Model_Rule
         const FREE_SHIPPING_ITEM = 1;
         const FREE_SHIPPING_ADDRESS = 2;
     
    +    protected $_labels = array();
    +
         protected function _construct()
         {
             parent::_construct();
    @@ -37,9 +39,15 @@ protected function _construct()
             $this->setIdFieldName('rule_id');
         }
     
    +    /**
    +     * Check unique coupon code before saving and clear coupon related cache
    +     *
    +     * @return Mage_SalesRule_Model_Rule
    +     */
         protected function _beforeSave()
         {
    -        if($coupon = $this->getCouponCode()) {
    +        $coupon = $this->getCouponCode();
    +        if($coupon) {
                 $this->getResource()->addUniqueField(array(
                     'field' => 'coupon_code',
                     'title' => Mage::helper('salesRule')->__('Coupon with the same code')
    @@ -51,13 +59,18 @@ protected function _beforeSave()
             return parent::_beforeSave();
         }
     
    -
    +    /**
    +     * Delete rule coupon code related cache
    +     *
    +     * @return Mage_SalesRule_Model_Rule
    +     */
         protected function _beforeDelete()
         {
    -        if ($coupon = $this->getCouponCode()) {
    +        $coupon = $this->getCouponCode();
    +        if ($coupon) {
                 Mage::app()->cleanCache('salesrule_coupon_'.$coupon);
             }
    -        parent::_beforeDelete();
    +        return parent::_beforeDelete();
         }
     
         public function getConditionsInstance()
    @@ -83,16 +96,24 @@ public function toString($format='')
             return $str;
         }
     
    +    /**
    +     * Initialize rule model data from array
    +     *
    +     * @param   array $rule
    +     * @return  Mage_SalesRule_Model_Rule
    +     */
         public function loadPost(array $rule)
         {
             $arr = $this->_convertFlatToRecursive($rule);
    -		if (isset($arr['conditions'])) {
    -    		$this->getConditions()->setConditions(array())->loadArray($arr['conditions'][1]);
    -		}
    -		if (isset($arr['actions'])) {
    -    		$this->getActions()->setActions(array())->loadArray($arr['actions'][1], 'actions');
    -		}
    -
    +        if (isset($arr['conditions'])) {
    +            $this->getConditions()->setConditions(array())->loadArray($arr['conditions'][1]);
    +        }
    +        if (isset($arr['actions'])) {
    +            $this->getActions()->setActions(array())->loadArray($arr['actions'][1], 'actions');
    +        }
    +        if (isset($rule['store_labels'])) {
    +            $this->setStoreLabels($rule['store_labels']);
    +        }
         	return $this;
         }
     
    @@ -116,56 +137,59 @@ public function toArray(array $arrAttributes = array())
     
             return $out;
         }
    -    /*
    -    public function processProduct(Mage_Sales_Model_Product $product)
    +
    +    public function getResourceCollection()
         {
    -        $this->validateProduct($product) && $this->updateProduct($product);
    -        return $this;
    +        return Mage::getResourceModel('salesrule/rule_collection');
         }
     
    -    public function validateProduct(Mage_Sales_Model_Product $product)
    +    /**
    +     * Save rula labels after rule save
    +     *
    +     * @return Mage_SalesRule_Model_Rule
    +     */
    +    protected function _afterSave()
         {
    -        if (!$this->getIsCollectionValidated()) {
    -            $env = $this->getEnv();
    -            $result = $result && $this->getIsActive()
    -                && (strtotime($this->getStartAt()) <= $env->getNow())
    -                && (strtotime($this->getExpireAt()) >= $env->getNow())
    -                && ($this->getCustomerRegistered()==2 || $this->getCustomerRegistered()==$env->getCustomerRegistered())
    -                && ($this->getCustomerNewBuyer()==2 || $this->getCustomerNewBuyer()==$env->getCustomerNewBuyer())
    -                && $this->getConditions()->validateProduct($product);
    -        } else {
    -            $result = $this->getConditions()->validateProduct($product);
    +        if ($this->hasStoreLabels()) {
    +            $this->_getResource()->saveStoreLabels($this->getId(), $this->getStoreLabels());
             }
    -
    -        return $result;
    +        return parent::_afterSave();
         }
     
    -    public function updateProduct(Mage_Sales_Model_Product $product)
    +    /**
    +     * Get Rule label for specific store
    +     *
    +     * @param   store $store
    +     * @return  string | false
    +     */
    +    public function getStoreLabel($store=null)
         {
    -        $this->getActions()->updateProduct($product);
    -        return $this;
    +        $storeId = Mage::app()->getStore($store)->getId();
    +        if ($this->hasStoreLabels()) {
    +            $labels = $this->_getData('store_labels');
    +            if (isset($labels[$storeId])) {
    +                return $labels[$storeId];
    +            } elseif ($labels[0]) {
    +                return $labels[0];
    +            }
    +            return false;
    +        } elseif (!isset($this->_labels[$storeId])) {
    +            $this->_labels[$storeId] = $this->_getResource()->getStoreLabel($this->getId(), $storeId);
    +        }
    +        return $this->_labels[$storeId];
         }
    -    */
    -    public function getResourceCollection()
    +
    +    /**
    +     * Get all existing rule labels
    +     *
    +     * @return array
    +     */
    +    public function getStoreLabels()
         {
    -        return Mage::getResourceModel('salesrule/rule_collection');
    +        if (!$this->hasStoreLabels()) {
    +            $labels = $this->_getResource()->getStoreLabels($this->getId());
    +            $this->setStoreLabels($labels);
    +        }
    +        return $this->_getData('store_labels');
         }
    -
    -//    protected function _afterSave()
    -//    {
    -//        $this->_getResource()->updateRuleProductData($this);
    -//        parent::_afterSave();
    -//    }
    -//
    -//    public function validate(Varien_Object $quote)
    -//    {
    -//
    -//        if ($this->getUsesPerCustomer() && $quote->getCustomer()) {
    -//            $customerUses = $this->_getResource()->getCustomerUses($this, $quote->getCustomerId());
    -//            if ($customerUses >= $this->getUsesPerCustomer()) {
    -//                return false;
    -//            }
    -//        }
    -//        return parent::validate($quote);
    -//    }
     }
    diff --git a/app/code/core/Mage/SalesRule/Model/Validator.php b/app/code/core/Mage/SalesRule/Model/Validator.php
    index b3991609d9..4f56703cca 100644
    --- a/app/code/core/Mage/SalesRule/Model/Validator.php
    +++ b/app/code/core/Mage/SalesRule/Model/Validator.php
    @@ -43,6 +43,9 @@ class Mage_SalesRule_Model_Validator extends Mage_Core_Model_Abstract
          */
         protected $_rules;
     
    +    protected $_roundingDeltas = array();
    +    protected $_baseRoundingDeltas = array();
    +
         protected function _construct()
         {
             parent::_construct();
    @@ -51,133 +54,214 @@ protected function _construct()
     
         /**
          * Init validator
    +     * Init process load collection of rules for specific website,
    +     * customer group and coupon code
          *
    -     * @param int $websiteId
    -     * @param int $customerGroupId
    -     * @param string $couponCode
    -     * @return Mage_SalesRule_Model_Validator
    +     * @param   int $websiteId
    +     * @param   int $customerGroupId
    +     * @param   string $couponCode
    +     * @return  Mage_SalesRule_Model_Validator
          */
         public function init($websiteId, $customerGroupId, $couponCode)
         {
             $this->setWebsiteId($websiteId)
    -           ->setCustomerGroupId($customerGroupId)
    -           ->setCouponCode($couponCode);
    -
    -        $this->_rules = Mage::getResourceModel('salesrule/rule_collection')
    -            ->setValidationFilter($websiteId, $customerGroupId, $couponCode)
    -            ->load();
    +            ->setCustomerGroupId($customerGroupId)
    +            ->setCouponCode($couponCode);
     
    +        $key = $websiteId . '_' . $customerGroupId . '_' . $couponCode;
    +        if (!isset($this->_rules[$key])) {
    +            $this->_rules[$key] = Mage::getResourceModel('salesrule/rule_collection')
    +                ->setValidationFilter($websiteId, $customerGroupId, $couponCode)
    +                ->load();
    +        }
             return $this;
         }
     
    -    public function process(Mage_Sales_Model_Quote_Item_Abstract $item)
    +    /**
    +     * Get rules collection for current object state
    +     *
    +     * @return Mage_SalesRule_Model_Mysql4_Rule_Collection
    +     */
    +    protected function _getRules()
         {
    -        $item->setFreeShipping(false);
    -        $item->setDiscountAmount(0);
    -        $item->setBaseDiscountAmount(0);
    -        $item->setDiscountPercent(0);
    +        $key = $this->getWebsiteId() . '_' . $this->getCustomerGroupId() . '_' . $this->getCouponCode();
    +        return $this->_rules[$key];
    +    }
     
    -        $quote = $item->getQuote();
    +    /**
    +     * Get address object which can be used for discount calculation
    +     *
    +     * @param   Mage_Sales_Model_Quote_Item_Abstract $item
    +     * @return  Mage_Sales_Model_Quote_Address
    +     */
    +    protected function _getAddress(Mage_Sales_Model_Quote_Item_Abstract $item)
    +    {
             if ($item instanceof Mage_Sales_Model_Quote_Address_Item) {
                 $address = $item->getAddress();
    -        } elseif ($quote->isVirtual()) {
    -            $address = $quote->getBillingAddress();
    +        } elseif ($item->getQuote()->isVirtual()) {
    +            $address = $item->getQuote()->getBillingAddress();
             } else {
    -            $address = $quote->getShippingAddress();
    +            $address = $item->getQuote()->getShippingAddress();
             }
    +        return $address;
    +    }
     
    -        $customerId = $quote->getCustomerId();
    -        $ruleCustomer = Mage::getModel('salesrule/rule_customer');
    -        $appliedRuleIds = array();
    -
    -        foreach ($this->_rules as $rule) {
    -            /* @var $rule Mage_SalesRule_Model_Rule */
    +    /**
    +     * Check if rule can be applied for specific address/quote/customer
    +     *
    +     * @param   Mage_SalesRule_Model_Rule $rule
    +     * @param   Mage_Sales_Model_Quote_Address $address
    +     * @return  bool
    +     */
    +    protected function _canProcessRule($rule, $address)
    +    {
    +        if (!$rule->hasIsValid()) {
                 /**
    -             * already tried to validate and failed
    +             * too many times used in general
                  */
    -            if ($rule->getIsValid() === false) {
    -                continue;
    +            if ($rule->getUsesPerCoupon() && ($rule->getTimesUsed() >= $rule->getUsesPerCoupon())) {
    +                $rule->setIsValid(false);
    +                return false;
                 }
    -
    -            if ($rule->getIsValid() !== true) {
    -                /**
    -                 * too many times used in general
    -                 */
    -                if ($rule->getUsesPerCoupon() && ($rule->getTimesUsed() >= $rule->getUsesPerCoupon())) {
    -                    $rule->setIsValid(false);
    -                    continue;
    -                }
    -                /**
    -                 * too many times used for this customer
    -                 */
    -                $ruleId = $rule->getId();
    -                if ($ruleId && $rule->getUsesPerCustomer()) {
    -                    $ruleCustomer->loadByCustomerRule($customerId, $ruleId);
    -                    if ($ruleCustomer->getId()) {
    -                        if ($ruleCustomer->getTimesUsed() >= $rule->getUsesPerCustomer()) {
    -                            continue;
    -                        }
    +            /**
    +             * too many times used for this customer
    +             */
    +            $ruleId = $rule->getId();
    +            if ($ruleId && $rule->getUsesPerCustomer()) {
    +                $customerId     = $address->getQuote()->getCustomerId();
    +                $ruleCustomer   = Mage::getModel('salesrule/rule_customer');
    +                $ruleCustomer->loadByCustomerRule($customerId, $ruleId);
    +                if ($ruleCustomer->getId()) {
    +                    if ($ruleCustomer->getTimesUsed() >= $rule->getUsesPerCustomer()) {
    +                        $rule->setIsValid(false);
    +                        return false;
                         }
                     }
    -                $rule->afterLoad();
    -                /**
    -                 * quote does not meet rule's conditions
    -                 */
    -                if (!$rule->validate($address)) {
    -                    $rule->setIsValid(false);
    -                    continue;
    -                }
    -                /**
    -                 * passed all validations, remember to be valid
    -                 */
    -                $rule->setIsValid(true);
                 }
    -
    +            $rule->afterLoad();
                 /**
    -             * although the rule is valid, this item is not marked for action
    +             * quote does not meet rule's conditions
                  */
    +            if (!$rule->validate($address)) {
    +                $rule->setIsValid(false);
    +                return false;
    +            }
    +            /**
    +             * passed all validations, remember to be valid
    +             */
    +            $rule->setIsValid(true);
    +        }
    +        return $rule->getIsValid();
    +
    +    }
    +
    +    /**
    +     * Quote item free shipping ability check
    +     * This process not affect information about applied rules, coupon code etc.
    +     * This information will be added during discount amounts processing
    +     *
    +     * @param   Mage_Sales_Model_Quote_Item_Abstract $item
    +     * @return  Mage_SalesRule_Model_Validator
    +     */
    +    public function processFreeShipping(Mage_Sales_Model_Quote_Item_Abstract $item)
    +    {
    +        $address = $this->_getAddress($item);
    +        $item->setFreeShipping(false);
    +        
    +        foreach ($this->_getRules() as $rule) {
    +            /* @var $rule Mage_SalesRule_Model_Rule */
    +            if (!$this->_canProcessRule($rule, $address)) {
    +                continue;
    +            }
    +
                 if (!$rule->getActions()->validate($item)) {
                     continue;
                 }
    -            $qty = $item->getQty();
    -            if ($item->getParentItem()) {
    -                $qty*= $item->getParentItem()->getQty();
    +
    +            switch ($rule->getSimpleFreeShipping()) {
    +                case Mage_SalesRule_Model_Rule::FREE_SHIPPING_ITEM:
    +                    $item->setFreeShipping($rule->getDiscountQty() ? $rule->getDiscountQty() : true);
    +                    break;
    +
    +                case Mage_SalesRule_Model_Rule::FREE_SHIPPING_ADDRESS:
    +                    $address->setFreeShipping(true);
    +                    break;
    +            }
    +            if ($rule->getStopRulesProcessing()) {
    +                break;
    +            }
    +        }
    +        return $this;
    +    }
    +
    +    /**
    +     * Quote item discount calculation process
    +     *
    +     * @param   Mage_Sales_Model_Quote_Item_Abstract $item
    +     * @return  Mage_SalesRule_Model_Validator
    +     */
    +    public function process(Mage_Sales_Model_Quote_Item_Abstract $item)
    +    {
    +        $item->setDiscountAmount(0);
    +        $item->setBaseDiscountAmount(0);
    +        $item->setDiscountPercent(0);
    +        $quote      = $item->getQuote();
    +        $address    = $this->_getAddress($item);
    +        $itemPrice  = $item->getDiscountCalculationPrice();
    +        if ($itemPrice !== null) {
    +            $baseItemPrice = $item->getBaseDiscountCalculationPrice();
    +        } else {
    +            $itemPrice = $item->getCalculationPrice();
    +            $baseItemPrice = $item->getBaseCalculationPrice();
    +        }
    +
    +        $appliedRuleIds = array();
    +        foreach ($this->_getRules() as $rule) {
    +            /* @var $rule Mage_SalesRule_Model_Rule */
    +            if (!$this->_canProcessRule($rule, $address)) {
    +                continue;
    +            }
    +            
    +            if (!$rule->getActions()->validate($item)) {
    +                continue;
                 }
    +            $qty = $item->getTotalQty();
                 $qty = $rule->getDiscountQty() ? min($qty, $rule->getDiscountQty()) : $qty;
                 $rulePercent = min(100, $rule->getDiscountAmount());
    +
                 $discountAmount = 0;
                 $baseDiscountAmount = 0;
                 switch ($rule->getSimpleAction()) {
                     case 'to_percent':
                         $rulePercent = max(0, 100-$rule->getDiscountAmount());
                         //no break;
    -
                     case 'by_percent':
    -                    if ($step = $rule->getDiscountStep()) {
    +                    $step = $rule->getDiscountStep();
    +                    if ($step) {
                             $qty = floor($qty/$step)*$step;
                         }
    -                    $discountAmount    = ($qty*$item->getCalculationPrice() - $item->getDiscountAmount()) * $rulePercent/100;
    -                    $baseDiscountAmount= ($qty*$item->getBaseCalculationPrice() - $item->getBaseDiscountAmount()) * $rulePercent/100;
    +                    $discountAmount    = ($qty*$itemPrice - $item->getDiscountAmount()) * $rulePercent/100;
    +                    $baseDiscountAmount= ($qty*$baseItemPrice - $item->getBaseDiscountAmount()) * $rulePercent/100;
     
                         if (!$rule->getDiscountQty() || $rule->getDiscountQty()>$qty) {
                             $discountPercent = min(100, $item->getDiscountPercent()+$rulePercent);
                             $item->setDiscountPercent($discountPercent);
                         }
                         break;
    -
                     case 'to_fixed':
                         $quoteAmount = $quote->getStore()->convertPrice($rule->getDiscountAmount());
    -                    $discountAmount    = $qty*($item->getCalculationPrice()-$quoteAmount);
    -                    $baseDiscountAmount= $qty*($item->getBaseCalculationPrice()-$rule->getDiscountAmount());
    +                    $discountAmount    = $qty*($itemPrice-$quoteAmount);
    +                    $baseDiscountAmount= $qty*($baseItemPrice-$rule->getDiscountAmount());
                         break;
     
                     case 'by_fixed':
    -                    if ($step = $rule->getDiscountStep()) {
    +                    $step = $rule->getDiscountStep();
    +                    if ($step) {
                             $qty = floor($qty/$step)*$step;
                         }
    -                    $quoteAmount = $quote->getStore()->convertPrice($rule->getDiscountAmount());
    -                    $discountAmount    = $qty*$quoteAmount;
    -                    $baseDiscountAmount= $qty*$rule->getDiscountAmount();
    +                    $quoteAmount        = $quote->getStore()->convertPrice($rule->getDiscountAmount());
    +                    $discountAmount     = $qty*$quoteAmount;
    +                    $baseDiscountAmount = $qty*$rule->getDiscountAmount();
                         break;
     
                     case 'cart_fixed':
    @@ -186,9 +270,12 @@ public function process(Mage_Sales_Model_Quote_Item_Abstract $item)
                             $cartRules[$rule->getId()] = $rule->getDiscountAmount();
                         }
                         if ($cartRules[$rule->getId()] > 0) {
    -                        $quoteAmount = $quote->getStore()->convertPrice($cartRules[$rule->getId()]);
    -                        $discountAmount = min($item->getRowTotal(), $quoteAmount);
    -                        $baseDiscountAmount = min($item->getBaseRowTotal(), $cartRules[$rule->getId()]);
    +                        $quoteAmount        = $quote->getStore()->convertPrice($cartRules[$rule->getId()]);
    +                        /**
    +                         * We can't use row total here because row total not include tax
    +                         */
    +                        $discountAmount     = min($itemPrice*$qty, $quoteAmount);
    +                        $baseDiscountAmount = min($baseItemPrice*$qty, $cartRules[$rule->getId()]);
                             $cartRules[$rule->getId()] -= $baseDiscountAmount;
                         }
                         $address->setCartFixedRules($cartRules);
    @@ -211,8 +298,8 @@ public function process(Mage_Sales_Model_Quote_Item_Abstract $item)
                                 break;
                             }
                         }
    -                    $discountAmount    = $free*$item->getCalculationPrice();
    -                    $baseDiscountAmount= $free*$item->getBaseCalculationPrice();
    +                    $discountAmount    = $free*$itemPrice;
    +                    $baseDiscountAmount= $free*$baseItemPrice;
                         break;
                 }
     
    @@ -232,35 +319,126 @@ public function process(Mage_Sales_Model_Quote_Item_Abstract $item)
                 $discountAmount = $result->getDiscountAmount();
                 $baseDiscountAmount = $result->getBaseDiscountAmount();
     
    -            $discountAmount     = $quote->getStore()->roundPrice($discountAmount);
    -            $baseDiscountAmount = $quote->getStore()->roundPrice($baseDiscountAmount);
    -            $discountAmount     = min($item->getDiscountAmount()+$discountAmount, $item->getRowTotal());
    -            $baseDiscountAmount = min($item->getBaseDiscountAmount()+$baseDiscountAmount, $item->getBaseRowTotal());
    +            $percentKey = $item->getDiscountPercent();
    +            /**
    +             * Process "delta" rounding
    +             */
    +            if ($percentKey) {
    +                $delta      = isset($this->_roundingDeltas[$percentKey]) ? $this->_roundingDeltas[$percentKey] : 0;
    +                $baseDelta  = isset($this->_baseRoundingDeltas[$percentKey]) ? $this->_baseRoundingDeltas[$percentKey] : 0;
    +                $discountAmount+= $delta;
    +                $baseDiscountAmount+=$baseDelta;
    +
    +                $this->_roundingDeltas[$percentKey]     = $discountAmount - $quote->getStore()->roundPrice($discountAmount);
    +                $this->_baseRoundingDeltas[$percentKey] = $baseDiscountAmount - $quote->getStore()->roundPrice($baseDiscountAmount);
    +                $discountAmount = $quote->getStore()->roundPrice($discountAmount);
    +                $baseDiscountAmount = $quote->getStore()->roundPrice($baseDiscountAmount);
    +            } else {
    +                $discountAmount     = $quote->getStore()->roundPrice($discountAmount);
    +                $baseDiscountAmount = $quote->getStore()->roundPrice($baseDiscountAmount);
    +            }
    +
    +            /**
    +             * We can't use row total here because row total not include tax
    +             * Discount can be applied on price included tax
    +             */
    +            $discountAmount     = min($item->getDiscountAmount()+$discountAmount, $itemPrice*$qty);
    +            $baseDiscountAmount = min($item->getBaseDiscountAmount()+$baseDiscountAmount, $baseItemPrice*$qty);
     
                 $item->setDiscountAmount($discountAmount);
                 $item->setBaseDiscountAmount($baseDiscountAmount);
     
    -            switch ($rule->getSimpleFreeShipping()) {
    -                case Mage_SalesRule_Model_Rule::FREE_SHIPPING_ITEM:
    -                    $item->setFreeShipping($rule->getDiscountQty() ? $rule->getDiscountQty() : true);
    +            $appliedRuleIds[$rule->getRuleId()] = $rule->getRuleId();
    +
    +            if ($rule->getCouponCode() && ( strtolower($rule->getCouponCode()) == strtolower($this->getCouponCode()))) {
    +                $address->setCouponCode($this->getCouponCode());
    +            }
    +            $this->_addDiscountDescription($address, $rule);
    +            if ($rule->getStopRulesProcessing()) {
    +                break;
    +            }
    +        }
    +        $item->setAppliedRuleIds(join(',',$appliedRuleIds));
    +        $address->setAppliedRuleIds($this->mergeIds($address->getAppliedRuleIds(), $appliedRuleIds));
    +        $quote->setAppliedRuleIds($this->mergeIds($quote->getAppliedRuleIds(), $appliedRuleIds));
    +        return $this;
    +    }
    +
    +    /**
    +     * Apply discounts to shipping amount
    +     *
    +     * @param   Mage_Sales_Model_Quote_Address $address
    +     * @return  Mage_SalesRule_Model_Validator
    +     */
    +    public function processShippingAmount(Mage_Sales_Model_Quote_Address $address)
    +    {
    +        $shippingAmount     = $address->getShippingAmountForDiscount();
    +        if ($shippingAmount!==null) {
    +            $baseShippingAmount = $address->getBaseShippingAmountForDiscount();
    +        } else {
    +            $shippingAmount     = $address->getShippingAmount();
    +            $baseShippingAmount = $address->getBaseShippingAmount();
    +        }
    +        $quote              = $address->getQuote();
    +        $appliedRuleIds = array();
    +        foreach ($this->_getRules() as $rule) {
    +            /* @var $rule Mage_SalesRule_Model_Rule */
    +            if (!$rule->getApplyToShipping() || !$this->_canProcessRule($rule, $address)) {
    +                continue;
    +            }
    +            
    +            $discountAmount = 0;
    +            $baseDiscountAmount = 0;
    +            $rulePercent = min(100, $rule->getDiscountAmount());
    +            switch ($rule->getSimpleAction()) {
    +                case 'to_percent':
    +                    $rulePercent = max(0, 100-$rule->getDiscountAmount());
    +                case 'by_percent':
    +                    $discountAmount    = ($shippingAmount - $address->getShippingDiscountAmount()) * $rulePercent/100;
    +                    $baseDiscountAmount= ($baseShippingAmount - $address->getBaseShippingDiscountAmount()) * $rulePercent/100;
    +                    $discountPercent = min(100, $address->getShippingDiscountPercent()+$rulePercent);
    +                    $address->setShippingDiscountPercent($discountPercent);
    +                    break;
    +                case 'to_fixed':
    +                    $quoteAmount = $quote->getStore()->convertPrice($rule->getDiscountAmount());
    +                    $discountAmount    = $shippingAmount-$quoteAmount;
    +                    $baseDiscountAmount= $baseShippingAmount-$rule->getDiscountAmount();
    +                    break;
    +                case 'by_fixed':
    +                    $quoteAmount        = $quote->getStore()->convertPrice($rule->getDiscountAmount());
    +                    $discountAmount     = $quoteAmount;
    +                    $baseDiscountAmount = $rule->getDiscountAmount();
                         break;
     
    -                case Mage_SalesRule_Model_Rule::FREE_SHIPPING_ADDRESS:
    -                    $address->setFreeShipping(true);
    +                case 'cart_fixed':
    +                    $cartRules = $address->getCartFixedRules();
    +                    if (!isset($cartRules[$rule->getId()])) {
    +                        $cartRules[$rule->getId()] = $rule->getDiscountAmount();
    +                    }
    +                    if ($cartRules[$rule->getId()] > 0) {
    +                        $quoteAmount        = $quote->getStore()->convertPrice($cartRules[$rule->getId()]);
    +                        $discountAmount     = min($shippingAmount, $quoteAmount);
    +                        $baseDiscountAmount = min($baseShippingAmount, $cartRules[$rule->getId()]);
    +                        $cartRules[$rule->getId()] -= $baseDiscountAmount;
    +                    }
    +                    $address->setCartFixedRules($cartRules);
                         break;
                 }
     
    +            $discountAmount     = min($address->getShippingDiscountAmount()+$discountAmount, $shippingAmount);
    +            $baseDiscountAmount = min($address->getBaseShippingDiscountAmount()+$baseDiscountAmount, $baseShippingAmount);
    +            $address->setShippingDiscountAmount($discountAmount);
    +            $address->setBaseShippingDiscountAmount($baseDiscountAmount);
                 $appliedRuleIds[$rule->getRuleId()] = $rule->getRuleId();
     
                 if ($rule->getCouponCode() && ( strtolower($rule->getCouponCode()) == strtolower($this->getCouponCode()))) {
                     $address->setCouponCode($this->getCouponCode());
                 }
    -
    +            $this->_addDiscountDescription($address, $rule);
                 if ($rule->getStopRulesProcessing()) {
                     break;
                 }
             }
    -        $item->setAppliedRuleIds(join(',',$appliedRuleIds));
             $address->setAppliedRuleIds($this->mergeIds($address->getAppliedRuleIds(), $appliedRuleIds));
             $quote->setAppliedRuleIds($this->mergeIds($quote->getAppliedRuleIds(), $appliedRuleIds));
             return $this;
    @@ -280,4 +458,49 @@ public function mergeIds($a1, $a2, $asString=true)
             }
             return $a;
         }
    +
    +    /**
    +     * Add rule discount description label to address object
    +     *
    +     * @param   Mage_Sales_Model_Quote_Address $address
    +     * @param   Mage_SalesRule_Model_Rule $rule
    +     * @return  Mage_SalesRule_Model_Validator
    +     */
    +    protected function _addDiscountDescription($address, $rule)
    +    {
    +        $description = $address->getDiscountDescriptionArray();
    +        $ruleLabel = $rule->getStoreLabel($address->getQuote()->getStore());
    +        $label = '';
    +        if ($ruleLabel) {
    +            $label = $ruleLabel;
    +        } elseif ($rule->getCouponCode()) {
    +            $label = $rule->getCouponCode();
    +        }
    +        
    +        if (!empty($label)) {
    +            $description[$rule->getId()] = $label;
    +        }
    +        $address->setDiscountDescriptionArray($description);
    +        return $this;
    +    }
    +
    +    /**
    +     * Convert address discount description array to string
    +     *
    +     * @param Mage_Sales_Model_Quote_Address $address
    +     * @param string $separator
    +     * @return Mage_SalesRule_Model_Validator
    +     */
    +    public function prepareDescription($address, $separator=', ')
    +    {
    +        $description = $address->getDiscountDescriptionArray();
    +
    +        if (is_array($description) && !empty($description)) {
    +            $description = implode($separator, $description);
    +        } else {
    +            $description = '';
    +        }
    +        $address->setDiscountDescription($description);
    +        return $this;
    +    }
     }
    diff --git a/app/code/core/Mage/SalesRule/etc/config.xml b/app/code/core/Mage/SalesRule/etc/config.xml
    index 0fca08fa66..1c81493168 100644
    --- a/app/code/core/Mage/SalesRule/etc/config.xml
    +++ b/app/code/core/Mage/SalesRule/etc/config.xml
    @@ -28,7 +28,7 @@
     
         
             
    -            0.7.7
    +            0.7.9
             
         
         
    @@ -45,12 +45,9 @@
                 
                     Mage_SalesRule_Model_Mysql4
                     
    -                    
    -                        salesrule
    -
    - - salesrule_customer
    -
    + salesrule
    + salesrule_customer
    +
    @@ -58,6 +55,7 @@ Mage_SalesRule + Mage_Sales_Model_Mysql4_Setup core_setup @@ -74,17 +72,14 @@ - + + + * + * + * + + - - - - singleton - salesrule/observer - sales_quote_address_discount_item - - - @@ -95,6 +90,22 @@ + + + + + salesrule/quote_freeshipping + subtotal + shipping + + + salesrule/quote_discount + subtotal,shipping + grand_total + + + +
    diff --git a/app/code/core/Mage/Sendfriend/Block/Send.php b/app/code/core/Mage/Sendfriend/Block/Send.php index 5d90eff7de..a93e2c0dc2 100644 --- a/app/code/core/Mage/Sendfriend/Block/Send.php +++ b/app/code/core/Mage/Sendfriend/Block/Send.php @@ -18,61 +18,147 @@ * versions in the future. If you wish to customize Magento for your * needs please refer to http://www.magentocommerce.com for more information. * - * @category Mage - * @package Mage_Sendfriend - * @copyright Copyright (c) 2008 Irubin Consulting Inc. DBA Varien (http://www.varien.com) - * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @category Mage + * @package Mage_Sendfriend + * @copyright Copyright (c) 2009 Irubin Consulting Inc. DBA Varien (http://www.varien.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ +/** + * Email to a Friend Block + * + * @category Mage + * @package Mage_Sendfriend + * @author Magento Core Team + */ class Mage_Sendfriend_Block_Send extends Mage_Core_Block_Template { - /** + /** * Retrieve username for form field * * @return string */ public function getUserName() { - if ($name = $this->getFormData()->getData('sender/name')) { - return $name; + $name = $this->getFormData()->getData('sender/name'); + if (!empty($name)) { + return trim($name); + } + + /* @var $session Mage_Customer_Model_Session */ + $session = Mage::getSingleton('customer/session'); + + if ($session->isLoggedIn()) { + return $session->getCustomer()->getName(); } - $firstName =(string)Mage::getSingleton('customer/session')->getCustomer()->getFirstname(); - $lastName = (string)Mage::getSingleton('customer/session')->getCustomer()->getLastname(); - return $firstName.' '.$lastName; + + return ''; } + /** + * Retrieve sender email address + * + * @return string + */ public function getEmail() { - if ($email = $this->getFormData()->getData('sender/email')) { - return $email; + $email = $this->getFormData()->getData('sender/email'); + if (!empty($email)) { + return trim($email); + } + + /* @var $session Mage_Customer_Model_Session */ + $session = Mage::getSingleton('customer/session'); + + if ($session->isLoggedIn()) { + return $session->getCustomer()->getEmail(); } - return (string) Mage::getSingleton('customer/session')->getCustomer()->getEmail(); + + return ''; } + /** + * Retrieve Message text + * + * @return string + */ + public function getMessage() + { + return $this->getFormData()->getData('sender/message'); + } + + /** + * Retrieve Form data or empty Varien_Object + * + * @return Varien_Object + */ public function getFormData() { $data = $this->getData('form_data'); - if (is_null($data)) { - $data = new Varien_Object(Mage::getSingleton('catalog/session')->getFormData(true)); - $this->setFormData($data); + if (!$data instanceof Varien_Object) { + $data = new Varien_Object(); + $this->setData('form_data', $data); } + return $data; } + /** + * Set Form data array + * + * @param array $data + * @return Mage_Sendfriend_Block_Send + */ + public function setFormData($data) + { + if (is_array($data)) { + $this->setData('form_data', new Varien_Object($data)); + } + + return $this; + } + + /** + * Retrieve Current Product Id + * + * @return int + */ public function getProductId() { - return $this->getRequest()->getParam('id'); + return $this->getRequest()->getParam('id', null); } + /** + * Retrieve current category id for product + * + * @return int + */ public function getCategoryId() { return $this->getRequest()->getParam('cat_id', null); } - public function getMaxRecipients() - { - $sendToFriendModel = Mage::registry('send_to_friend_model'); - return $sendToFriendModel->getMaxRecipients(); - } -} \ No newline at end of file + /** + * Retrieve Max Recipients + * + * @return int + */ + public function getMaxRecipients() + { + return Mage::helper('sendfriend')->getMaxRecipients(); + } + + /** + * Retrieve Send URL for Form Action + * + * @return string + */ + public function getSendUrl() + { + return Mage::getUrl('*/*/sendmail', array( + 'id' => $this->getProductId(), + 'cat_id' => $this->getCategoryId() + )); + } +} diff --git a/app/code/core/Mage/Sendfriend/Helper/Data.php b/app/code/core/Mage/Sendfriend/Helper/Data.php index edf127f8a4..1328ad3da7 100644 --- a/app/code/core/Mage/Sendfriend/Helper/Data.php +++ b/app/code/core/Mage/Sendfriend/Helper/Data.php @@ -18,13 +18,118 @@ * versions in the future. If you wish to customize Magento for your * needs please refer to http://www.magentocommerce.com for more information. * - * @category Mage - * @package Mage_Adminhtml - * @copyright Copyright (c) 2008 Irubin Consulting Inc. DBA Varien (http://www.varien.com) - * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @category Mage + * @package Mage_Sedfriend + * @copyright Copyright (c) 2009 Irubin Consulting Inc. DBA Varien (http://www.varien.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ + +/** + * Sendfriend Data Helper + * + * @category Mage + * @package Mage_Sedfriend + * @author Magento Core Team + */ class Mage_Sendfriend_Helper_Data extends Mage_Core_Helper_Abstract { + const XML_PATH_ENABLED = 'sendfriend/email/enabled'; + const XML_PATH_ALLOW_FOR_GUEST = 'sendfriend/email/allow_guest'; + const XML_PATH_MAX_RECIPIENTS = 'sendfriend/email/max_recipients'; + const XML_PATH_MAX_PER_HOUR = 'sendfriend/email/max_per_hour'; + const XML_PATH_LIMIT_BY = 'sendfriend/email/check_by'; + const XML_PATH_EMAIL_TEMPLATE = 'sendfriend/email/template'; + + const COOKIE_NAME = 'stf'; + + const CHECK_IP = 1; + const CHECK_COOKIE = 0; + + /** + * Check is enabled Module + * + * @param int $store + * @return bool + */ + public function isEnabled($store = null) + { + return Mage::getStoreConfigFlag(self::XML_PATH_ENABLED, $store); + } + + /** + * Check allow send email for guest + * + * @param int $store + * @return bool + */ + public function isAllowForGuest($store = null) + { + return Mage::getStoreConfigFlag(self::XML_PATH_ALLOW_FOR_GUEST, $store); + } + + /** + * Retrieve Max Recipients + * + * @param int $store + * @return int + */ + public function getMaxRecipients($store = null) + { + return (int)Mage::getStoreConfig(self::XML_PATH_MAX_RECIPIENTS, $store); + } + + /** + * Retrieve Max Products Sent in 1 Hour + * + * @param int $store + * @return int + */ + public function getMaxEmailPerPeriod($store = null) + { + return (int)Mage::getStoreConfig(self::XML_PATH_MAX_PER_HOUR, $store); + } + + /** + * Retrieve Limitation Period in seconds (1 hour) + * + * @return int + */ + public function getPeriod() + { + return 3600; + } + + /** + * Retrieve Limit Sending By + * + * @param int $store + * @return int + */ + public function getLimitBy($store = null) + { + return (int)Mage::getStoreConfig(self::XML_PATH_LIMIT_BY, $store); + } + + /** + * Retrieve Email Template + * + * @param int $store + * @return mixed + */ + public function getEmailTemplate($store = null) + { + return Mage::getStoreConfig(self::XML_PATH_EMAIL_TEMPLATE, $store); + } + /** + * Retrieve Key Name for Cookie + * + * @see self::COOKIE_NAME + * @return string + */ + public function getCookieName() + { + return self::COOKIE_NAME; + } } diff --git a/app/code/core/Mage/Sendfriend/Model/Mysql4/Sendfriend.php b/app/code/core/Mage/Sendfriend/Model/Mysql4/Sendfriend.php index b06ffb263a..a81ca34c32 100644 --- a/app/code/core/Mage/Sendfriend/Model/Mysql4/Sendfriend.php +++ b/app/code/core/Mage/Sendfriend/Model/Mysql4/Sendfriend.php @@ -18,36 +18,63 @@ * versions in the future. If you wish to customize Magento for your * needs please refer to http://www.magentocommerce.com for more information. * - * @category Mage - * @package Mage_Sendfriend - * @copyright Copyright (c) 2008 Irubin Consulting Inc. DBA Varien (http://www.varien.com) - * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @category Mage + * @package Mage_Sendfriend + * @copyright Copyright (c) 2009 Irubin Consulting Inc. DBA Varien (http://www.varien.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ + +/** + * SendFriend Log Resource Model + * + * @category Mage + * @package Mage_Sendfriend + * @author Magento Core Team + */ class Mage_Sendfriend_Model_Mysql4_Sendfriend extends Mage_Core_Model_Mysql4_Abstract { + /** + * Initialize connection and table + * + */ protected function _construct() { $this->_init('sendfriend/sendfriend', 'log_id'); } - public function getSendCount($model, $ip, $startTime) + /** + * Retrieve Sended Emails By Ip + * + * @param Mage_Sendfriend_Model_Sendfriend $object + * @param int $ip + * @param int $startTime + * @return int + */ + public function getSendCount($object, $ip, $startTime) { $select = $this->_getReadAdapter()->select() - ->from(array('main_table' => $this->getTable('sendfriend')), new Zend_Db_Expr('count(*)')) - ->where('main_table.ip = ?', $ip) - ->where('main_table.time >= ?', $startTime); + ->from( + array('main_table' => $this->getTable('sendfriend')), + array('count' => new Zend_Db_Expr('count(*)'))) + ->where('ip=?', $ip) + ->where('time>=?', $startTime); - $data = $this->_getReadAdapter()->fetchRow($select); - - return $data['count(*)']; + $row = $this->_getReadAdapter()->fetchRow($select); + return $row['count']; } - public function deleteLogsBefore($time) - { - $deleted = $this->_getWriteAdapter() - ->delete($this->getTable('sendfriend'), $this->_getWriteAdapter()->quoteInto('time < ?', $time)); + /** + * Delete Old logs + * + * @param int $time + * @return Mage_Sendfriend_Model_Mysql4_Sendfriend + */ + public function deleteLogsBefore($time) + { + $cond = $this->_getWriteAdapter()->quoteInto('time_getWriteAdapter()->delete($this->getMainTable(), $cond); return $this; - } -} \ No newline at end of file + } +} diff --git a/app/code/core/Mage/Sendfriend/Model/Mysql4/Sendfriend/Collection.php b/app/code/core/Mage/Sendfriend/Model/Mysql4/Sendfriend/Collection.php index 743333ff58..383d04007d 100644 --- a/app/code/core/Mage/Sendfriend/Model/Mysql4/Sendfriend/Collection.php +++ b/app/code/core/Mage/Sendfriend/Model/Mysql4/Sendfriend/Collection.php @@ -18,16 +18,28 @@ * versions in the future. If you wish to customize Magento for your * needs please refer to http://www.magentocommerce.com for more information. * - * @category Mage - * @package Mage_Sendfriend - * @copyright Copyright (c) 2008 Irubin Consulting Inc. DBA Varien (http://www.varien.com) - * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @category Mage + * @package Mage_Sendfriend + * @copyright Copyright (c) 2009 Irubin Consulting Inc. DBA Varien (http://www.varien.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ + +/** + * Sendfriend log resource collection + * + * @category Mage + * @package Mage_Sendfriend + * @author Magento Core Team + */ class Mage_Sendfriend_Model_Mysql4_Sendfriend_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract { - protected function _construct() - { - $this->_init('sendfriend/sendfriend'); - } -} \ No newline at end of file + /** + * Init resource collection + * + */ + protected function _construct() + { + $this->_init('sendfriend/sendfriend'); + } +} diff --git a/app/code/core/Mage/Sendfriend/Model/Mysql4/Setup.php b/app/code/core/Mage/Sendfriend/Model/Mysql4/Setup.php index 6df2bb5d79..47df5c4196 100644 --- a/app/code/core/Mage/Sendfriend/Model/Mysql4/Setup.php +++ b/app/code/core/Mage/Sendfriend/Model/Mysql4/Setup.php @@ -18,12 +18,20 @@ * versions in the future. If you wish to customize Magento for your * needs please refer to http://www.magentocommerce.com for more information. * - * @category Mage - * @package Mage_Sendfriend - * @copyright Copyright (c) 2008 Irubin Consulting Inc. DBA Varien (http://www.varien.com) - * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + * @category Mage + * @package Mage_Sendfriend + * @copyright Copyright (c) 2009 Irubin Consulting Inc. DBA Varien (http://www.varien.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ + +/** + * Sendfriend module Setup Model + * + * @category Mage + * @package Mage_Sendfriend + * @author Magento Core Team + */ class Mage_Sendfriend_Model_Mysql4_Setup extends Mage_Core_Model_Resource_Setup { } diff --git a/app/code/core/Mage/Sendfriend/Model/Sendfriend.php b/app/code/core/Mage/Sendfriend/Model/Sendfriend.php index ff3a980464..530e0bd899 100644 --- a/app/code/core/Mage/Sendfriend/Model/Sendfriend.php +++ b/app/code/core/Mage/Sendfriend/Model/Sendfriend.php @@ -27,69 +27,100 @@ class Mage_Sendfriend_Model_Sendfriend extends Mage_Core_Model_Abstract { /** - * XML configuration paths + * Recipient Names + * + * @var array */ - const XML_PATH_SENDFRIEND_EMAIL_TEMPLATE = 'sendfriend/email/template'; + protected $_names = array(); - protected $_names = array(); - protected $_emails = array(); - protected $_sender = array(); - protected $_ip = 0; - protected $_product = null; + /** + * Recipient Emails + * + * @var array + */ + protected $_emails = array(); - protected $_period = 3600; // hour + /** + * Sender data array + * + * @var array + */ + protected $_sender = array(); - protected $_cookieName = 'stf'; + /** + * Product Instance + * + * @var Mage_Catalog_Model_Product + */ + protected $_product; + /** + * Initialize resource model + * + */ protected function _construct() { $this->_init('sendfriend/sendfriend'); } - public function toOptionArray() + /** + * Retrieve Data Helper + * + * @return Mage_Sendfriend_Helper_Data + */ + protected function _getHelper() { - if(!$collection = Mage::registry('config_system_email_template')) { - $collection = Mage::getResourceModel('core/email_template_collection') - ->load(); + return Mage::helper('sendfriend'); + } - Mage::register('config_system_email_template', $collection); - } - $options = $collection->toOptionArray(); - array_unshift($options, array('value'=>'', 'label'=>'')); - return $options; + /** + * Retrieve Option Array + * + * @deprecated It Is a not Source model + * @return array + */ + public function toOptionArray() + { + return array(); } public function send() { - $translate = Mage::getSingleton('core/translate'); /* @var $translate Mage_Core_Model_Translate */ + $translate = Mage::getSingleton('core/translate'); $translate->setTranslateInline(false); - $errors = array(); + /* @var $mailTemplate Mage_Core_Model_Email_Template */ + $mailTemplate = Mage::getModel('core/email_template'); - $this->_emailModel = Mage::getModel('core/email_template'); - $message = nl2br(htmlspecialchars($this->_sender['message'])); + $message = nl2br(htmlspecialchars($this->getSender()->getMessage())); $sender = array( - 'name' => strip_tags($this->_sender['name']), - 'email' => strip_tags($this->_sender['email']) - ); - - foreach($this->_emails as $key => $email) { - $this->_emailModel->setDesignConfig(array('area'=>'frontend', 'store'=>$this->getStoreId())) - ->sendTransactional( - Mage::getStoreConfig(self::XML_PATH_SENDFRIEND_EMAIL_TEMPLATE), + 'name' => $this->_getHelper()->htmlEscape($this->getSender()->getName()), + 'email' => $this->_getHelper()->htmlEscape($this->getSender()->getEmail()) + ); + + $mailTemplate->setDesignConfig(array( + 'area' => 'frontend', + 'store' => Mage::app()->getStore()->getId() + )); + + foreach ($this->getRecipients()->getEmails() as $k => $email) { + $name = $this->getRecipients()->getNames($k); + $mailTemplate->sendTransactional( + $this->getTemplate(), $sender, $email, - $this->_names[$key], + $name, array( - 'name' => $this->_names[$key], + 'name' => $name, 'email' => $email, - 'product_name' => $this->_product->getName(), - 'product_url' => $this->_product->getProductUrl(), + 'product_name' => $this->getProduct()->getName(), + 'product_url' => $this->getProduct()->getUrlInStore(), 'message' => $message, - 'sender_name' => strip_tags($this->_sender['name']), - 'sender_email' => strip_tags($this->_sender['email']), - 'product_image' => Mage::helper('catalog/image')->init($this->_product, 'small_image')->resize(75), + 'sender_name' => $sender['name'], + 'sender_email' => $sender['email'], + 'product_image' => Mage::helper('catalog/image')->init($this->getProduct(), + 'small_image')->resize(75), ) ); } @@ -99,87 +130,246 @@ public function send() return $this; } + /** + * Validate Form data + * + * @return bool|array + */ public function validate() { $errors = array(); - $helper = Mage::helper('sendfriend'); - if (empty($this->_sender['name'])) { - $errors[] = $helper->__('Sender name can\'t be empty'); + $name = $this->getSender()->getName(); + if (empty($name)) { + $errors[] = Mage::helper('sendfriend')->__('Sender name can\'t be empty'); + } + + $email = $this->getSender()->getEmail(); + if (empty($email) OR !Zend_Validate::is($email, 'EmailAddress')) { + $errors[] = Mage::helper('sendfriend')->__('Invalid sender email'); } - if (!isset($this->_sender['email']) || !Zend_Validate::is($this->_sender['email'], 'EmailAddress')) { - $errors[] = $helper->__('Invalid sender email'); + $message = $this->getSender()->getMessage(); + if (empty($message)) { + $errors[] = Mage::helper('sendfriend')->__('Message can\'t be empty'); } - if (empty($this->_sender['message'])) { - $errors[] = $helper->__('Message can\'t be empty'); + if (!$this->getRecipients()->getEmails()) { + $errors[] = Mage::helper('sendfriend')->__('You have to specify at least one recipient'); } - foreach ($this->_emails as $email) { + // validate recipients email addresses + foreach ($this->getRecipients()->getEmails() as $email) { if (!Zend_Validate::is($email, 'EmailAddress')) { - $errors[] = $helper->__('You input invalid email address for recipient'); + $errors[] = Mage::helper('sendfriend')->__('You input invalid email address for recipient'); break; } } - if (!$this->canEmailToFriend()) { - $errors[] = $helper->__('You cannot email this product to a friend'); - } + switch ($this->_getHelper()->getLimitBy()) { + case Mage_Sendfriend_Helper_Data::CHECK_COOKIE: + $amount = $this->_amountByCookies(); + break; - if ($this->_getSendToFriendCheckType()) { - $amount = $this->_amountByCookies(); - } else { - $amount = $this->_amountByIp(); + case Mage_Sendfriend_Helper_Data::CHECK_IP: + $amount = $this->_amountByIp(); + break; + default: + $amount = 0; + break; } if ($amount >= $this->getMaxSendsToFriend()){ - $errors[] = $helper->__('You have exceeded limit of %d sends in an hour', $this->getMaxSendsToFriend()); + $errors[] = Mage::helper('sendfriend')->__('You have exceeded limit of %d sends in an hour', $this->getMaxSendsToFriend()); } $maxRecipients = $this->getMaxRecipients(); - if (count($this->_emails) > $maxRecipients) { - $errors[] = $helper->__('You cannot send more than %d emails at a time', $this->getMaxRecipients()); + if (count($this->getRecipients()->getEmails()) > $maxRecipients) { + $errors[] = Mage::helper('sendfriend')->__('You cannot send more than %d emails at a time', $this->getMaxRecipients()); } - if (count($this->_emails) < 1) { - $errors[] = $helper->__('You have to specify at least one recipient'); + if (empty($errors)) { + return true; } - if (!$this->getTemplate()){ - $errors[] = $helper->__('Email template is not specified by administrator'); - } + return $errors; + } + /** + * Set cookie instance + * + * @param Mage_Core_Model_Cookie $product + * @return Mage_Sendfriend_Model_Sendfriend + */ + public function setCookie($cookie) + { + return $this->setData('_cookie', $cookie); + } - if (empty($errors)) { - return true; + /** + * Retrieve Cookie instance + * + * @throws Mage_Core_Exception + * @return Mage_Core_Model_Cookie + */ + public function getCookie() + { + $cookie = $this->_getData('_cookie'); + if (!$cookie instanceof Mage_Core_Model_Cookie) { + Mage::throwException(Mage::helper('sendfriend')->__('Please define correct Cookie instance')); } - return $errors; + return $cookie; } - public function setIp($ip) + /** + * Set Visitor Remote Address + * + * @param int $ipAddr the IP address on Long Format + * @return Mage_Sendfriend_Model_Sendfriend + */ + public function setRemoteAddr($ipAddr) { - $this->_ip = $ip; + Mage::log(array(__METHOD__, $ipAddr)); + $this->setData('_remote_addr', $ipAddr); + return $this; } + /** + * Retrieve Visitor Remote Address + * + * @return int + */ + public function getRemoteAddr() + { + Mage::log(array(__METHOD__, $this->_getData('_remote_addr'))); + return $this->_getData('_remote_addr'); + } + + /** + * Set Recipients + * + * @param array $recipients + * @return Mage_Sendfriend_Model_Sendfriend + */ public function setRecipients($recipients) { - $this->_emails = array_unique($recipients['email']); - $this->_names = $recipients['name']; + // validate array + if (!is_array($recipients) OR !isset($recipients['email']) + OR !isset($recipients['name']) OR !is_array($recipients['email']) + OR !is_array($recipients['name'])) { + return $this; + } + + $emails = array(); + $names = array(); + foreach ($recipients['email'] as $k => $email) { + if (!isset($emails[$email]) && isset($recipients['name'][$k])) { + $emails[$email] = true; + $names[] = $recipients['name'][$k]; + } + } + + if ($emails) { + $emails = array_keys($emails); + } + + return $this->setData('_recipients', new Varien_Object(array( + 'emails' => $emails, + 'names' => $names + ))); + } + + /** + * Retrieve Recipients object + * + * @return Varien_Object + */ + public function getRecipients() + { + $recipients = $this->_getData('_recipients'); + if (!$recipients instanceof Varien_Object) { + $recipients = new Varien_Object(array( + 'emails' => array(), + 'names' => array() + )); + $this->setData('_recipients', $recipients); + } + return $recipients; } - public function setProduct($product){ - $this->_product = $product; + /** + * Set product instance + * + * @param Mage_Catalog_Model_Product $product + * @return Mage_Sendfriend_Model_Sendfriend + */ + public function setProduct($product) + { + return $this->setData('_product', $product); + } + + /** + * Retrieve Product instance + * + * @throws Mage_Core_Exception + * @return Mage_Catalog_Model_Product + */ + public function getProduct() + { + $product = $this->_getData('_product'); + if (!$product instanceof Mage_Catalog_Model_Product) { + Mage::throwException(Mage::helper('sendfriend')->__('Please define correct Product instance')); + } + return $product; + } + + /** + * Set Sender Information array + * + * @param array $sender + * @return Mage_Sendfriend_Model_Sendfriend + */ + public function setSender($sender) + { + if (!is_array($sender)) { + Mage::helper('sendfriend')->__('Invalid Sender information'); + } + + return $this->setData('_sender', new Varien_Object($sender)); } - public function setSender($sender){ - $this->_sender = $sender; + /** + * Retrieve Sender Information Object + * + * @throws Mage_Core_Exception + * @return Varien_Object + */ + public function getSender() + { + $sender = $this->_getData('_sender'); + if (!$sender instanceof Varien_Object) { + Mage::throwException(Mage::helper('sendfriend')->__('Please define correct Sender information')); + } + return $sender; } - public function getSendCount($ip, $startTime) + /** + * Retrieve Send count by IP + * + * @param int $ip + * @param int $startTime + * @return int + */ + public function getSendCount($ip = null, $startTime = null) { - $count = $this->_getResource()->getSendCount($this, $ip, $startTime); - return $count; + if (is_null($ip)) { + $ip = $this->getRemoteAddr(); + } + if (is_null($startTime)) { + $startTime = time() - $this->_getHelper()->getPeriod(); + } + + return $this->_getResource()->getSendCount($this, $ip, $startTime); } /** @@ -189,17 +379,17 @@ public function getSendCount($ip, $startTime) */ public function getMaxSendsToFriend() { - return max(0, (int) Mage::getStoreConfig('sendfriend/email/max_per_hour')); + return $this->_getHelper()->getMaxEmailPerPeriod(); } /** - * Get current "Send to friend" template + * Get current Email "Send to friend" template * * @return string */ public function getTemplate() { - return Mage::getStoreConfig('sendfriend/email/template'); + return $this->_getHelper()->getEmailTemplate(); } /** @@ -209,7 +399,7 @@ public function getTemplate() */ public function getMaxRecipients() { - return max(0, (int) Mage::getStoreConfig('sendfriend/email/max_recipients')); + return $this->_getHelper()->getMaxRecipients(); } /** @@ -219,84 +409,63 @@ public function getMaxRecipients() */ public function canEmailToFriend() { - if (!Mage::getStoreConfig('sendfriend/email/enabled')) { - return false; - } - if (!Mage::getStoreConfig('sendfriend/email/allow_guest') - && !Mage::getSingleton('customer/session')->isLoggedIn()) { - return false; - } - return true; - } - - /** - * Get check type for "Send to Friend" function - * - * @return integer - */ - private function _getSendToFriendCheckType() - { - return max(0, (int) Mage::getStoreConfig('sendfriend/email/check_by')); + return $this->_getHelper()->isEnabled(); } /** * Retrieve amount by cookie + * * @return int */ - private function _amountByCookies() + protected function _amountByCookies() { + $cookie = $this->_getHelper()->getCookieName(); + $time = time(); $newTimes = array(); - $oldTimes = Mage::app()->getCookie() - ->get($this->_cookieName); - if ($oldTimes){ + $oldTimes = $this->getCookie()->get($cookie); + if ($oldTimes) { $oldTimes = explode(',', $oldTimes); - foreach ($oldTimes as $time){ - if (is_numeric($time) && $time >= time()-$this->_period){ - $newTimes[] = $time; + foreach ($oldTimes as $oldTime) { + $periodTime = $time - $this->_getHelper()->getPeriod(); + if (is_numeric($oldTime) AND $oldTime >= $periodTime) { + $newTimes[] = $oldTime; } } } + $amount = count($newTimes); + $newTimes[] = $time; - $newTimes[] = time(); - Mage::app()->getCookie() - ->set($this->_cookieName, implode(',', $newTimes), $this->_period); + $this->getCookie()->set($cookie, implode(',', $newTimes)); return $amount; } /** * Retrieve amount by IP address - * + * * @return int */ - private function _amountByIp() + protected function _amountByIp() { - $this->_deleteLogsBefore(time() - $this->_period); + $time = time(); + $period = $this->_getHelper()->getPeriod(); + + // delete expired logs + $this->_getResource()->deleteLogsBefore($time - $period); $amount = $this->getSendCount($this->_ip, time() - $this->_period); - $this->setData(array('ip'=>$this->_ip, 'time'=>time())); - $this->save(); + $this->setIp($this->getRemoteAddr()) + ->setTime($time) + ->save(); return $amount; } /** - * Delete Before Log - * - * @param int $time - * @return Mage_Sendfriend_Model_Sendfriend - */ - private function _deleteLogsBefore($time) - { - $this->_getResource()->deleteLogsBefore($time); - return $this; - } - - /** - * Check and register object - * + * Register self in global register with name send_to_friend_model + * * @return Mage_Sendfriend_Model_Sendfriend */ public function register() @@ -306,4 +475,4 @@ public function register() } return $this; } -} \ No newline at end of file +} diff --git a/app/code/core/Mage/Sendfriend/controllers/ProductController.php b/app/code/core/Mage/Sendfriend/controllers/ProductController.php index 5c09575199..32e08876ba 100644 --- a/app/code/core/Mage/Sendfriend/controllers/ProductController.php +++ b/app/code/core/Mage/Sendfriend/controllers/ProductController.php @@ -24,24 +24,66 @@ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ +/** + * Email to a Friend Product Controller + * + * @category Mage + * @package Mage_Sedfriend + * @author Magento Core Team + */ class Mage_Sendfriend_ProductController extends Mage_Core_Controller_Front_Action { /** - * Initialize product instance + * Predispatch: check is enable module + * If allow only for customer - redirect to login page + * + * @return Mage_Sendfriend_ProductController + */ + public function preDispatch() + { + parent::preDispatch(); + + /* @var $helper Mage_Sendfriend_Helper_Data */ + $helper = Mage::helper('sendfriend'); + /* @var $session Mage_Customer_Model_Session */ + $session = Mage::getSingleton('customer/session'); + + if (!$helper->isEnabled()) { + $this->_forward('noRoute'); + return $this; + } + + if (!$helper->isAllowForGuest() && !$session->authenticate($this)) { + $this->setFlag('', self::FLAG_NO_DISPATCH, true); + if ($this->getRequest()->getActionName() == 'sendemail') { + $session->setBeforeAuthUrl(Mage::getUrl('*/*/send', array( + '_current' => true + ))); + Mage::getSingleton('catalog/session') + ->setSendfriendFormData($this->getRequest()->getPost()); + } + } + + return $this; + } + + /** + * Initialize Product Instance * * @return Mage_Catalog_Model_Product */ protected function _initProduct() { - $productId = (int) $this->getRequest()->getParam('id'); + $productId = (int)$this->getRequest()->getParam('id'); if (!$productId) { return false; } $product = Mage::getModel('catalog/product') ->load($productId); - if (!$product->getId()) { + if (!$product->getId() || !$product->isVisibleInCatalog()) { return false; } + Mage::register('product', $product); return $product; } @@ -51,94 +93,114 @@ protected function _initProduct() * * @return Mage_Sendfriend_Model_Sendfriend */ - protected function _initSendToFriendModel(){ - $sendToFriendModel = Mage::getModel('sendfriend/sendfriend'); - Mage::register('send_to_friend_model', $sendToFriendModel); - return $sendToFriendModel; - } + protected function _initSendToFriendModel() + { + $model = Mage::getModel('sendfriend/sendfriend'); + $model->setRemoteAddr(Mage::helper('core/http')->getRemoteAddr(true)); + $model->setCookie(Mage::app()->getCookie()); - public function sendAction(){ - $product = $this->_initProduct(); - $this->_initSendToFriendModel(); + Mage::register('send_to_friend_model', $model); - if (!$product || !$product->isVisibleInCatalog()) { - $this->_forward('noRoute'); - return; - } + return $model; + } - $productHelper = Mage::helper('catalog/product'); - $sendToFriendModel = Mage::registry('send_to_friend_model'); + /** + * Show Send to a Friend Form + * + */ + public function sendAction() + { + $product = $this->_initProduct(); + $model = $this->_initSendToFriendModel(); - /** - * check if user is allowed to send product to a friend - */ - if (!$sendToFriendModel->canEmailToFriend()) { - Mage::getSingleton('catalog/session')->addError( - $this->__('You cannot email this product to a friend') - ); - $this->_redirectReferer($product->getProductUrl()); + if (!$product) { + $this->_forward('noRoute'); return; } - $maxSendsToFriend = $sendToFriendModel->getMaxSendsToFriend(); - if ($maxSendsToFriend){ + if ($model->getMaxSendsToFriend()) { Mage::getSingleton('catalog/session')->addNotice( - $this->__('You cannot send more than %d times in an hour', $maxSendsToFriend) + $this->__('You cannot send more than %d times in an hour', $model->getMaxSendsToFriend()) ); } $this->loadLayout(); $this->_initLayoutMessages('catalog/session'); + + Mage::dispatchEvent('sendfriend_product', array('product' => $product)); + $data = Mage::getSingleton('catalog/session')->getSendfriendFormData(); + if ($data) { + Mage::getSingleton('catalog/session')->setSendfriendFormData(true); + $block = $this->getLayout()->getBlock('sendfriend.send'); + if ($block) { + $block->setFormData($data); + } + } + $this->renderLayout(); - Mage::dispatchEvent('sendfriend_product', array('product'=>$product)); } + /** + * Send Email Post Action + * + */ public function sendmailAction() { - $product = $this->_initProduct(); - $sendToFriendModel = $this->_initSendToFriendModel(); - $data = $this->getRequest()->getPost(); + if (!$this->_validateFormKey()) { + return $this->_redirect('*/*/send', array('_current' => true)); + } - if (!$product || !$product->isVisibleInCatalog() || !$data) { + $product = $this->_initProduct(); + $model = $this->_initSendToFriendModel(); + $data = $this->getRequest()->getPost(); + + if (!$product || !$data) { $this->_forward('noRoute'); return; } $categoryId = $this->getRequest()->getParam('cat_id', null); - if ($categoryId && $category = Mage::getModel('catalog/category')->load($categoryId)) { + if ($categoryId) { + $category = Mage::getModel('catalog/category') + ->load($categoryId); + $product->setCategory($category); Mage::register('current_category', $category); } - $sendToFriendModel->setSender($this->getRequest()->getPost('sender')); - $sendToFriendModel->setRecipients($this->getRequest()->getPost('recipients')); - $sendToFriendModel->setIp(Mage::getSingleton('log/visitor')->getRemoteAddr()); - $sendToFriendModel->setProduct($product); + $model->setSender($this->getRequest()->getPost('sender')); + $model->setRecipients($this->getRequest()->getPost('recipients')); + $model->setProduct($product); try { - $validateRes = $sendToFriendModel->validate(); - if (true === $validateRes) { - $sendToFriendModel->send(); + $validate = $model->validate(); + if ($validate === true) { + $model->send(); Mage::getSingleton('catalog/session')->addSuccess($this->__('Link to a friend was sent.')); $this->_redirectSuccess($product->getProductUrl()); return; } else { - Mage::getSingleton('catalog/session')->setFormData($data); - if (is_array($validateRes)) { - foreach ($validateRes as $errorMessage) { - Mage::getSingleton('catalog/session')->addError($errorMessage); + if (is_array($validate)) { + foreach ($validate as $errorMessage) { + Mage::getSingleton('catalog/session')->addError($errorMessage); } - } else { + } + else { Mage::getSingleton('catalog/session')->addError($this->__('Some problems with data.')); } } - } catch (Mage_Core_Exception $e) { + } + catch (Mage_Core_Exception $e) { Mage::getSingleton('catalog/session')->addError($e->getMessage()); - } catch (Exception $e) { + } + catch (Exception $e) { Mage::getSingleton('catalog/session') ->addException($e, $this->__('Some emails was not sent')); } - $this->_redirectError(Mage::getURL('*/*/send',array('id'=>$product->getId()))); + // save form data + Mage::getSingleton('catalog/session')->setSendfriendFormData($data); + + $this->_redirectError(Mage::getURL('*/*/send', array('_current' => true))); } -} \ No newline at end of file +} diff --git a/app/code/core/Mage/Sendfriend/etc/config.xml b/app/code/core/Mage/Sendfriend/etc/config.xml index 156b2db85b..255e62463e 100644 --- a/app/code/core/Mage/Sendfriend/etc/config.xml +++ b/app/code/core/Mage/Sendfriend/etc/config.xml @@ -26,52 +26,52 @@ */ --> - - - 0.7.2 - - - - - - Mage_Sendfriend_Model - sendfriend_mysql4 - - - Mage_Sendfriend_Model_Mysql4 - sendfriend_mysql4 - - - sendfriend_log
    -
    -
    -
    -
    - - - - Mage_Sendfriend - Mage_Sendfriend_Model_Mysql4_Setup - - - core_setup - - - - - core_write - - - - - core_read - - - - - Mage_Sendfriend_Block - -