diff --git a/RELEASE_NOTES.txt b/RELEASE_NOTES.txt index 513c159e5d..8099958f98 100644 --- a/RELEASE_NOTES.txt +++ b/RELEASE_NOTES.txt @@ -1,3 +1,96 @@ +==== 1.5.0.0-beta1 ===== + +=== Improvements === +Fixed several memory leaks in product model. Added tool method clear() to clean object data and references to this object +Implemented Order payment action for PayPal +Implemented SOAP Api calls for shopping cart + +=== Fixes === +Fixed Only "Library Mail" works for USPS +Fixed The "MY WISHLIST" link always shows quantity of line items in the Wishlist and never the real quantity of items +- fix for case when out of stock products are not shown on frontend +Fixed Wrong behavior of Varien_Data_Collection_Db::_getConditionSql +Fixed Incorrect shipping tax calculation on invoice creditmemos with included tax +- Rounding of shipment taxes was added +Fixed Impossible save empty values for store view scope +- Remove store_id from EAV module and move all store functionality into catalog module. +Fixed Wrong tax calculation for bundle products +Fixed File configuration dialog is not closed when pressing 'Ok' button +- additional fix of backend Customer functionality for IE8 to eliminate JS errors +Fixed Product creation -> Necessary validation for SKU field +Fixed Link "Gift Options" is not shown in Items Ordered grid of create Order page, when "Allow Gift Messages for Order Items" is set to "No" +- considering design html at right place +- removed useless variable from observer +Fixed Price for composite products in a products grid on Order creation page +Fixed Tax from orders in status pending presents in Tax Report +Fixed Catalog Price Rule is not applied +Fixed Incorrect tax summary for partial credit memos/invoices +Fixed Order success page is not displayed after placing Order using Website Payments Pro Hosted Solution method +- now, return and cancel urls can be secure (https) +Fixed Problems with newsletter template preview on newsletter queue edit page +Fixed Link "configure" is inactive for downloadable products in product grid on Order creation page in backend +Fixed A system error message is missing for cases when media storage synchronization is complete or an error occurred +- output messages for notifications edited +Fixed Incorrect price calculation for bundle product during backend order creation(Tax is doubles in Total) +Fixed Gift Options tab is present on product page for virtual product types +Fixed Magento Backend performance optimization +Fixed Gift Message for Individual Item prompt is shown in AJAX-popup, although "Allow Gift Messages for Order Items" is disabled +Fixed Unable to change customer password when email confirmation is enabled +Fixed Incorrect tax calculation for Tax Calculation Method Based On = Unit Price and Catalog Prices = Including Tax +Fixed "Preferred State" for extensions is not working +Fixed Total amount is not recounted, when customer cancels the Gift Options during OnePageCheckout +Fixed In "Gift options" AJAX popup "OK" button written incorrectly +Fixed No address autocomplete while admin order create with single store +- fixes due to unnecessary AJAX calls +Fixed Information about Gift Options is not stored, when admin user performs Edit Order action in backend +Fixed Gift column should be removed from product grid +Fixed SKU validation error on creating products +Fixed Shipped order has status "Processing" if invoice has been posted with "Not Capture" and amount was later captured on paypal side. +- considering online and offline capture amout when checking if capture is final +- trailing white spaces removed +Fixed Link to file from downloadable product is not available after authorize and capture payment action via Authorize.net +- Link management observer call methods are moved to save_commit_after events (for order and its item respectively) instead of save_after events +Fixed Price for product with file custom options in Wishlist is calculated incorrect +- Added ability to use special price templates for displaying wishlist items (as they can be partially/fully configured and catalog price template doesn't support it) +- Added default template, that shows configured price in addition to default clean product price +Fixed Cross-sells products disappears after adding another products to shopping cart + + +==== 1.5.x-devel-90295 ==== + +=== Fixes === +Fixed Configurable Product:Associated Product tab - Rounding issue +Fixed Wrong usage of @see tag in phpdocs +- replaced @see into @link phpdocs in cases where the value is a link +Fixed A system error message is missing for cases when media storage synchronization is complete or an error occurred +Fixed Order success page is not displayed after placing Order using Website Payments Pro Hosted Solution method +Fixed Order contains information about used card type with Payflow Link (for USA and Canada) payment using +Fixed Product export have no Entity Attributes +Fixed Authorize.net Directpost payment method doesn't work when secure urls in frontend are being used +Fixed The options in the action dropdown for export are incorrectly labeled in the Sales section +- Rename XML and MSXML to Excel XML +Fixed Round up to 0.01 of amount with tax in cart +Fixed Shipped order has status "Processing" if invoice has been posted with "Not Capture" and amount was later captured on paypal side. +- Return invoice model for transaction, if it didn't return by transaction_id +Fixed File configuration dialog is not closed when pressing 'Ok' button +- also made better logic to disable/enable file controls, so that file is not uploaded (and just thrown away by server) when there's no need in it +Fixed Deleting attached files do not work +Fixed Price for composite products in a products grid on Order creation page +- it was also fixed converting to current currency rates +Fixed Firefox iframe issue +Fixed Can not add product to order from backend (IE8) +Fixed Moving product with file custom options to Wishlist works incorrect +Fixed Displaying Out of Stock Products on the front-end +Fixed Price for composite products in a products grid on Order creation page +- forgot to add parent::_afterLoad(); in Mage_Bundle_Model_Mysql4_Selection_Collection::_afterLoad() method witch leads to exception +Fixed Fix for HSS amount is sent to PayPal. But need to test includeTax/excludeTax settings. +Fixed A system error message is missing for cases when media storage synchronization is complete or an error occurred +- fixed ability to save storage witch last sync was made on +- removed link "read details" for local messages at notice bar +- messages correction +Fixed Authorize.net Directpost payment method. Can't create capture and refund transaction + + === 1.5.0.0-alpha2 ==== === Major Highlights === diff --git a/app/Mage.php b/app/Mage.php index f1b0f00798..acd71a3782 100644 --- a/app/Mage.php +++ b/app/Mage.php @@ -154,8 +154,8 @@ public static function getVersionInfo() 'minor' => '5', 'revision' => '0', 'patch' => '0', - 'stability' => 'alpha', - 'number' => '2', + 'stability' => 'beta', + 'number' => '1', ); } diff --git a/app/code/community/Find/Feed/etc/system.xml b/app/code/community/Find/Feed/etc/system.xml index 61993b7323..a5121c5fa5 100755 --- a/app/code/community/Find/Feed/etc/system.xml +++ b/app/code/community/Find/Feed/etc/system.xml @@ -36,7 +36,7 @@ find - 10 + 100 1 1 1 diff --git a/app/code/core/Mage/AdminNotification/Model/Inbox.php b/app/code/core/Mage/AdminNotification/Model/Inbox.php index 44107d55be..5ec0369055 100644 --- a/app/code/core/Mage/AdminNotification/Model/Inbox.php +++ b/app/code/core/Mage/AdminNotification/Model/Inbox.php @@ -98,6 +98,6 @@ public function getNoticeStatus() */ public function parse(array $data) { - return $this->getResource()->parse($this, $data);; + return $this->getResource()->parse($this, $data); } } diff --git a/app/code/core/Mage/AdminNotification/Model/Mysql4/Inbox.php b/app/code/core/Mage/AdminNotification/Model/Mysql4/Inbox.php index dbb8ed5d89..60e9120862 100644 --- a/app/code/core/Mage/AdminNotification/Model/Mysql4/Inbox.php +++ b/app/code/core/Mage/AdminNotification/Model/Mysql4/Inbox.php @@ -82,7 +82,13 @@ public function parse(Mage_AdminNotification_Model_Inbox $object, array $data) $select = $write->select() ->from($this->getMainTable()) ->where('url=?', $item['url']); - $row = $write->fetchRow($select); + + if (isset($item['internal'])) { + $row = false; + unset($item['internal']); + } else { + $row = $write->fetchRow($select); + } if (!$row) { $write->insert($this->getMainTable(), $item); diff --git a/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Composite/Fieldset/Grouped.php b/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Composite/Fieldset/Grouped.php index 0e9b5ad3e5..428646896b 100644 --- a/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Composite/Fieldset/Grouped.php +++ b/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Composite/Fieldset/Grouped.php @@ -131,4 +131,16 @@ public function getIsLastFieldset() } return $isLast; } + + /** + * Returns price converted to current currency rate + * + * @param float $price + * @return float + */ + public function getCurrencyPrice($price) + { + $store = $this->getProduct()->getStore(); + return $this->helper('core')->currencyByStore($price, $store, false); + } } diff --git a/app/code/core/Mage/Adminhtml/Block/Customer/Edit/Tab/Tags.php b/app/code/core/Mage/Adminhtml/Block/Customer/Edit/Tab/Tags.php index bd0a4f2c17..77e4828614 100644 --- a/app/code/core/Mage/Adminhtml/Block/Customer/Edit/Tab/Tags.php +++ b/app/code/core/Mage/Adminhtml/Block/Customer/Edit/Tab/Tags.php @@ -110,7 +110,7 @@ protected function _prepareColumns() ->setColumnFilter('name'); $this->addExportType('*/*/exportCsv', Mage::helper('customer')->__('CSV')); - $this->addExportType('*/*/exportXml', Mage::helper('customer')->__('XML')); + $this->addExportType('*/*/exportXml', Mage::helper('customer')->__('Excel XML')); return parent::_prepareColumns(); } diff --git a/app/code/core/Mage/Adminhtml/Block/Customer/Grid.php b/app/code/core/Mage/Adminhtml/Block/Customer/Grid.php index 6eea2e69ad..d9fc6b4044 100644 --- a/app/code/core/Mage/Adminhtml/Block/Customer/Grid.php +++ b/app/code/core/Mage/Adminhtml/Block/Customer/Grid.php @@ -164,7 +164,7 @@ protected function _prepareColumns() )); $this->addExportType('*/*/exportCsv', Mage::helper('customer')->__('CSV')); - $this->addExportType('*/*/exportXml', Mage::helper('customer')->__('XML')); + $this->addExportType('*/*/exportXml', Mage::helper('customer')->__('Excel XML')); return parent::_prepareColumns(); } diff --git a/app/code/core/Mage/Adminhtml/Block/Customer/Grid/Renderer/Multiaction.php b/app/code/core/Mage/Adminhtml/Block/Customer/Grid/Renderer/Multiaction.php index 67c3832987..3e003bce4d 100644 --- a/app/code/core/Mage/Adminhtml/Block/Customer/Grid/Renderer/Multiaction.php +++ b/app/code/core/Mage/Adminhtml/Block/Customer/Grid/Renderer/Multiaction.php @@ -76,13 +76,11 @@ protected function _toLinkHtml($action, Varien_Object $row) $product = $row->getProduct(); if (isset($action['process']) && $action['process'] == 'configurable') { - $hasConfigurableOptions = (bool)($product->isComposite() || $product->getOptions() - || in_array($product->getTypeId(), array('giftcard', 'downloadable'))); - if ($hasConfigurableOptions) { + if ($product->canConfigure()) { $style = ''; $onClick = sprintf('onclick="return %s.configureItem(%s)"', $action['control_object'], $row->getId()); } else { - $style = 'style="color: #CCC"'; + $style = 'style="color: #CCC;"'; $onClick = ''; } diff --git a/app/code/core/Mage/Adminhtml/Block/Newsletter/Subscriber/Grid.php b/app/code/core/Mage/Adminhtml/Block/Newsletter/Subscriber/Grid.php index 2e9fa9a1b4..db191aef5b 100644 --- a/app/code/core/Mage/Adminhtml/Block/Newsletter/Subscriber/Grid.php +++ b/app/code/core/Mage/Adminhtml/Block/Newsletter/Subscriber/Grid.php @@ -139,7 +139,7 @@ protected function _prepareColumns() )); $this->addExportType('*/*/exportCsv', Mage::helper('customer')->__('CSV')); - $this->addExportType('*/*/exportXml', Mage::helper('customer')->__('XML')); + $this->addExportType('*/*/exportXml', Mage::helper('customer')->__('Excel XML')); return parent::_prepareColumns(); } diff --git a/app/code/core/Mage/Adminhtml/Block/Notification/Toolbar.php b/app/code/core/Mage/Adminhtml/Block/Notification/Toolbar.php index 0f27a66863..214ae8db96 100644 --- a/app/code/core/Mage/Adminhtml/Block/Notification/Toolbar.php +++ b/app/code/core/Mage/Adminhtml/Block/Notification/Toolbar.php @@ -64,9 +64,12 @@ public function isShow() if ($this->getRequest()->getControllerName() == 'notification') { return false; } - if ($this->getCriticalCount() == 0 && $this->getMajorCount() == 0 && $this->getMinorCount() == 0 && $this->getNoticeCount() == 0) { + if ($this->getCriticalCount() == 0 && $this->getMajorCount() == 0 && $this->getMinorCount() == 0 + && $this->getNoticeCount() == 0 + ) { return false; } + return true; } diff --git a/app/code/core/Mage/Adminhtml/Block/Page/Footer.php b/app/code/core/Mage/Adminhtml/Block/Page/Footer.php index fac5ae3a34..5babf55b56 100644 --- a/app/code/core/Mage/Adminhtml/Block/Page/Footer.php +++ b/app/code/core/Mage/Adminhtml/Block/Page/Footer.php @@ -34,11 +34,19 @@ */ class Mage_Adminhtml_Block_Page_Footer extends Mage_Adminhtml_Block_Template { + const CACHE_LIFETIME = 7200; + const CACHE_KEY = 'footer'; + const CACHE_TAG = 'adminhtml'; protected function _construct() { $this->setTemplate('page/footer.phtml'); $this->setShowProfiler(true); + $this->addData(array( + 'cache_lifetime' => self::CACHE_LIFETIME, + 'cache_tags' => array(self::CACHE_TAG), + 'cache_key' => self::CACHE_KEY + )); } public function getChangeLocaleUrl() @@ -66,7 +74,7 @@ public function getLanguageSelect() ->setValue(Mage::app()->getLocale()->getLocaleCode()) ->setOptions(Mage::app()->getLocale()->getTranslatedOptionLocales()) ->getHtml(); + return $html; } - } diff --git a/app/code/core/Mage/Adminhtml/Block/Sales/Order/Create/Data.php b/app/code/core/Mage/Adminhtml/Block/Sales/Order/Create/Data.php index b1de6cb3b5..a250b44fda 100644 --- a/app/code/core/Mage/Adminhtml/Block/Sales/Order/Create/Data.php +++ b/app/code/core/Mage/Adminhtml/Block/Sales/Order/Create/Data.php @@ -49,9 +49,7 @@ public function getAvailableCurrencies() ); foreach ($dirtyCodes as $code) { if (isset($rates[$code]) || $code == Mage::app()->getStore()->getBaseCurrencyCode()) { - $currency = Mage::app()->getLocale()->currency($code); - $symbol = $currency->getSymbol() ? $currency->getSymbol() : $currency->getShortName(); - $codes[$symbol] = $code; + $codes[] = $code; } } } @@ -69,6 +67,18 @@ public function getCurrencyName($code) return Mage::app()->getLocale()->currency($code)->getName(); } + /** + * Retrieve curency name by code + * + * @param string $code + * @return string + */ + public function getCurrencySymbol($code) + { + $currency = Mage::app()->getLocale()->currency($code); + return $currency->getSymbol() ? $currency->getSymbol() : $currency->getShortName(); + } + /** * Retrieve current order currency code * diff --git a/app/code/core/Mage/Adminhtml/Block/Sales/Order/Create/Items/Grid.php b/app/code/core/Mage/Adminhtml/Block/Sales/Order/Create/Items/Grid.php index 7dead708d0..793d0289fb 100644 --- a/app/code/core/Mage/Adminhtml/Block/Sales/Order/Create/Items/Grid.php +++ b/app/code/core/Mage/Adminhtml/Block/Sales/Order/Create/Items/Grid.php @@ -257,10 +257,12 @@ public function getMoveToCustomerStorage() public function displaySubtotalInclTax($item) { - $tax = ($item->getTaxBeforeDiscount()) - ? $item->getTaxBeforeDiscount() - : ($item->getTaxAmount() ? $item->getTaxAmount() : 0); - return $this->formatPrice($item->getRowTotal()+$tax); + if ($item->getTaxBeforeDiscount()) { + $tax = $item->getTaxBeforeDiscount(); + } else { + $tax = $item->getTaxAmount() ? $item->getTaxAmount() : 0; + } + return $this->formatPrice($item->getRowTotal() + $tax); } public function displayOriginalPriceInclTax($item) @@ -301,14 +303,12 @@ public function getStore() public function getConfigureButtonHtml($item) { $product = $item->getProduct(); - $isConfigurable = $product->isComposite() || $product->getOptions() - || in_array($product->getTypeId(), array('downloadable', 'giftcard')); $options = array( 'label' => Mage::helper('sales')->__('Configure'), 'title' => Mage::helper('sales')->__('This product does not have any configurable options.') ); - if ($isConfigurable) { + if ($product->canConfigure()) { $options['onclick'] = sprintf('order.showQuoteItemConfiguration(%s)', $item->getId()); } else { $options['class'] = ' disabled'; diff --git a/app/code/core/Mage/Adminhtml/Block/Sales/Order/Create/Search/Grid.php b/app/code/core/Mage/Adminhtml/Block/Sales/Order/Create/Search/Grid.php index afca296117..3a12099307 100644 --- a/app/code/core/Mage/Adminhtml/Block/Sales/Order/Create/Search/Grid.php +++ b/app/code/core/Mage/Adminhtml/Block/Sales/Order/Create/Search/Grid.php @@ -89,11 +89,11 @@ protected function _addColumnFilterToCollection($column) protected function _prepareCollection() { + $attributes = Mage::getSingleton('catalog/config')->getProductAttributes(); $collection = Mage::getModel('catalog/product')->getCollection() ->setStore($this->getStore()) - ->addAttributeToSelect('name') + ->addAttributeToSelect($attributes) ->addAttributeToSelect('sku') - ->addAttributeToSelect('price') ->addMinimalPrice() ->addStoreFilter() ->addAttributeToFilter('type_id', array_keys( @@ -147,20 +147,6 @@ protected function _prepareColumns() 'sortable' => false, )); - $this->addColumn('giftmessage', array( - 'filter' => false, - 'sortable' => false, - 'header' => Mage::helper('sales')->__('Gift'), - 'renderer' => 'adminhtml/sales_order_create_search_grid_renderer_giftmessage', - 'field_name'=> 'giftmessage', - 'inline_css'=> 'checkbox input-text', - 'align' => 'center', - 'index' => 'entity_id', - 'values' => $this->_getGiftmessageSaveModel()->getAllowQuoteItemsProducts(), - 'width' => '1', - )); - - $this->addColumn('qty', array( 'filter' => false, 'sortable' => false, @@ -193,6 +179,7 @@ protected function _getSelectedProducts() /** * Retrieve gift message save model * + * @deprecated after 1.4.2.0 * @return Mage_Adminhtml_Model_Giftmessage_Save */ protected function _getGiftmessageSaveModel() @@ -209,6 +196,4 @@ protected function _afterLoadCollection() { $this->getCollection()->addOptionsToResult(); return parent::_afterLoadCollection(); } - } - diff --git a/app/code/core/Mage/Adminhtml/Block/Sales/Order/Create/Search/Grid/Renderer/Giftmessage.php b/app/code/core/Mage/Adminhtml/Block/Sales/Order/Create/Search/Grid/Renderer/Giftmessage.php index 147386ed7e..224ff9f697 100644 --- a/app/code/core/Mage/Adminhtml/Block/Sales/Order/Create/Search/Grid/Renderer/Giftmessage.php +++ b/app/code/core/Mage/Adminhtml/Block/Sales/Order/Create/Search/Grid/Renderer/Giftmessage.php @@ -27,9 +27,11 @@ /** * Adminhtml sales create order product search grid giftmessage column renderer * + * @deprecated after 1.4.2.0 - gift column has been removed from search grid + * * @category Mage * @package Mage_Adminhtml - * @author Magento Core Team + * @author Magento Core Team */ class Mage_Adminhtml_Block_Sales_Order_Create_Search_Grid_Renderer_Giftmessage extends Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Checkbox { diff --git a/app/code/core/Mage/Adminhtml/Block/Sales/Order/Create/Search/Grid/Renderer/Product.php b/app/code/core/Mage/Adminhtml/Block/Sales/Order/Create/Search/Grid/Renderer/Product.php index 51b422f91c..3e68b13e98 100644 --- a/app/code/core/Mage/Adminhtml/Block/Sales/Order/Create/Search/Grid/Renderer/Product.php +++ b/app/code/core/Mage/Adminhtml/Block/Sales/Order/Create/Search/Grid/Renderer/Product.php @@ -42,8 +42,7 @@ class Mage_Adminhtml_Block_Sales_Order_Create_Search_Grid_Renderer_Product exten public function render(Varien_Object $row) { $rendered = parent::render($row); - $isConfigurable = ($row->isComposite() || $row->getOptions() || $row->getTypeId() == 'giftcard' - || $row->getTypeId() == 'downloadable') ? true : false; + $isConfigurable = $row->canConfigure(); $style = $isConfigurable ? '' : 'style="color: #CCC;"'; $prodAttributes = $isConfigurable ? sprintf('list_type = "product_to_add" product_id = %s', $row->getId()) : 'disabled="disabled"'; return sprintf('%s', diff --git a/app/code/core/Mage/Adminhtml/Block/Sales/Order/Create/Search/Grid/Renderer/Qty.php b/app/code/core/Mage/Adminhtml/Block/Sales/Order/Create/Search/Grid/Renderer/Qty.php index 6dfd007ddf..4b76678498 100644 --- a/app/code/core/Mage/Adminhtml/Block/Sales/Order/Create/Search/Grid/Renderer/Qty.php +++ b/app/code/core/Mage/Adminhtml/Block/Sales/Order/Create/Search/Grid/Renderer/Qty.php @@ -31,8 +31,20 @@ * @package Mage_Adminhtml * @author Magento Core Team */ -class Mage_Adminhtml_Block_Sales_Order_Create_Search_Grid_Renderer_Qty extends Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Input +class Mage_Adminhtml_Block_Sales_Order_Create_Search_Grid_Renderer_Qty + extends Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Input { + /** + * Returns whether this qty field must be inactive + * + * @param Varien_Object $row + * @return bool + */ + protected function _isInactive($row) + { + return $row->getTypeId() == Mage_Catalog_Model_Product_Type_Grouped::TYPE_CODE; + } + /** * Render product qty field * @@ -41,11 +53,23 @@ class Mage_Adminhtml_Block_Sales_Order_Create_Search_Grid_Renderer_Qty extends M */ public function render(Varien_Object $row) { - $isInactive = $row->getTypeId() == Mage_Catalog_Model_Product_Type_Grouped::TYPE_CODE; + // Prepare values + $isInactive = $this->_isInactive($row); + + if ($isInactive) { + $qty = ''; + } else { + $qty = $row->getData($this->getColumn()->getIndex()); + $qty *= 1; + if (!$qty) { + $qty = ''; + } + } + // Compose html $html = 'getColumn()->getId() . '" '; - $html .= 'value="' . $row->getData($this->getColumn()->getIndex()) . '" '; + $html .= 'value="' . $qty . '" '; if ($isInactive) { $html .= 'disabled="disabled" '; } diff --git a/app/code/core/Mage/Adminhtml/Block/Sales/Order/View/Items/Renderer/Default.php b/app/code/core/Mage/Adminhtml/Block/Sales/Order/View/Items/Renderer/Default.php index 6d6f2efd78..17e4c4339b 100644 --- a/app/code/core/Mage/Adminhtml/Block/Sales/Order/View/Items/Renderer/Default.php +++ b/app/code/core/Mage/Adminhtml/Block/Sales/Order/View/Items/Renderer/Default.php @@ -38,9 +38,41 @@ public function getItem() return $this->_getData('item'); } + /** + * Retrieve real html id for field + * + * @param string $name + * @return string + */ + public function getFieldId($id) + { + return $this->getFieldIdPrefix() . $id; + } + + /** + * Retrieve field html id prefix + * + * @return string + */ + public function getFieldIdPrefix() + { + return 'order_item_' . $this->getItem()->getId() . '_'; + } + + /** + * Indicate that block can display container + * + * @return boolean + */ + public function canDisplayContainer() + { + return $this->getRequest()->getParam('reload') != 1; + } + /** * Giftmessage object * + * @deprecated after 1.4.2.0 * @var Mage_GiftMessage_Model_Message */ protected $_giftMessage = array(); @@ -48,6 +80,7 @@ public function getItem() /** * Retrive default value for giftmessage sender * + * @deprecated after 1.4.2.0 * @return string */ public function getDefaultSender() @@ -66,6 +99,7 @@ public function getDefaultSender() /** * Retrive default value for giftmessage recipient * + * @deprecated after 1.4.2.0 * @return string */ public function getDefaultRecipient() @@ -94,6 +128,7 @@ public function getDefaultRecipient() /** * Retrive real name for field * + * @deprecated after 1.4.2.0 * @param string $name * @return string */ @@ -102,30 +137,10 @@ public function getFieldName($name) return 'giftmessage[' . $this->getItem()->getId() . '][' . $name . ']'; } - /** - * Retrive real html id for field - * - * @param string $name - * @return string - */ - public function getFieldId($id) - { - return $this->getFieldIdPrefix() . $id; - } - - /** - * Retrive field html id prefix - * - * @return string - */ - public function getFieldIdPrefix() - { - return 'giftmessage_item_' . $this->getItem()->getId() . '_'; - } - /** * Initialize gift message for entity * + * @deprecated after 1.4.2.0 * @return Mage_Adminhtml_Block_Sales_Order_Edit_Items_Grid_Renderer_Name_Giftmessage */ protected function _initMessage() @@ -147,6 +162,7 @@ protected function _initMessage() /** * Retrive gift message for entity * + * @deprecated after 1.4.2.0 * @return Mage_GiftMessage_Model_Message */ public function getMessage() @@ -161,6 +177,7 @@ public function getMessage() /** * Retrieve save url * + * @deprecated after 1.4.2.0 * @return array */ public function getSaveUrl() @@ -175,6 +192,7 @@ public function getSaveUrl() /** * Retrive block html id * + * @deprecated after 1.4.2.0 * @return string */ public function getHtmlId() @@ -182,19 +200,10 @@ public function getHtmlId() return substr($this->getFieldIdPrefix(), 0, -1); } - /** - * Indicate that block can display container - * - * @return boolean - */ - public function canDisplayContainer() - { - return $this->getRequest()->getParam('reload')!=1; - } - /** * Indicates that block can display giftmessages form * + * @deprecated after 1.4.2.0 * @return boolean */ public function canDisplayGiftmessage() diff --git a/app/code/core/Mage/Adminhtml/Block/System/Config/System/Storage/Media/Synchronize.php b/app/code/core/Mage/Adminhtml/Block/System/Config/System/Storage/Media/Synchronize.php index 46126fff9c..c5c5d79e97 100644 --- a/app/code/core/Mage/Adminhtml/Block/System/Config/System/Storage/Media/Synchronize.php +++ b/app/code/core/Mage/Adminhtml/Block/System/Config/System/Storage/Media/Synchronize.php @@ -103,4 +103,38 @@ public function getButtonHtml() return $button->toHtml(); } + + /** + * Retrieve last sync params settings + * + * Return array format: + * array ( + * => storage_type int, + * => connection_name string + * ) + * + * @return array + */ + public function getSyncStorageParams() + { + $flag = Mage::getSingleton('core/file_storage')->getSyncFlag(); + $flagData = $flag->getFlagData(); + + if ($flag->getState() == Mage_Core_Model_File_Storage_Flag::STATE_NOTIFIED + && is_array($flagData) + && isset($flagData['destination_storage_type']) && $flagData['destination_storage_type'] != '' + && isset($flagData['destination_connection_name']) + ) { + $storageType = $flagData['destination_storage_type']; + $connectionName = $flagData['destination_connection_name']; + } else { + $storageType = Mage_Core_Model_File_Storage::STORAGE_MEDIA_FILE_SYSTEM; + $connectionName = ''; + } + + return array( + 'storage_type' => $storageType, + 'connection_name' => $connectionName + ); + } } diff --git a/app/code/core/Mage/Adminhtml/Block/Tax/Rate/Grid.php b/app/code/core/Mage/Adminhtml/Block/Tax/Rate/Grid.php index 51792d734d..0468bdf776 100644 --- a/app/code/core/Mage/Adminhtml/Block/Tax/Rate/Grid.php +++ b/app/code/core/Mage/Adminhtml/Block/Tax/Rate/Grid.php @@ -90,7 +90,7 @@ protected function _prepareColumns() )); $this->addExportType('*/*/exportCsv', Mage::helper('tax')->__('CSV')); - $this->addExportType('*/*/exportXml', Mage::helper('tax')->__('XML')); + $this->addExportType('*/*/exportXml', Mage::helper('tax')->__('Excel XML')); return parent::_prepareColumns(); } diff --git a/app/code/core/Mage/Adminhtml/Helper/Catalog/Product/Composite.php b/app/code/core/Mage/Adminhtml/Helper/Catalog/Product/Composite.php index dd24ee0fe4..a9f8c5b3e6 100644 --- a/app/code/core/Mage/Adminhtml/Helper/Catalog/Product/Composite.php +++ b/app/code/core/Mage/Adminhtml/Helper/Catalog/Product/Composite.php @@ -145,6 +145,7 @@ public function renderConfigureResult($controller, Varien_Object $configureResul $productType = null; Mage::register('composite_configure_result_error_message', $e->getMessage()); } + $this->_initConfigureResultLayout($controller, $isOk, $productType); $controller->renderLayout(); } diff --git a/app/code/core/Mage/Adminhtml/Model/Giftmessage/Save.php b/app/code/core/Mage/Adminhtml/Model/Giftmessage/Save.php index b8dfc26866..d36aef1a34 100644 --- a/app/code/core/Mage/Adminhtml/Model/Giftmessage/Save.php +++ b/app/code/core/Mage/Adminhtml/Model/Giftmessage/Save.php @@ -45,13 +45,6 @@ public function saveAllInQuote() { $giftmessages = $this->getGiftmessages(); - // remove disabled giftmessages - foreach ($this->_getQuote()->getAllItems() as $item) { - if($item->getGiftMessageId() && !in_array($item->getId(), $this->getAllowQuoteItems())) { - $this->_deleteOne($item); - } - } - if (!is_array($giftmessages)) { return $this; } @@ -109,7 +102,6 @@ protected function _saveOne($entityId, $giftmessage) { break; } - if ($entityModel->getGiftMessageId()) { $giftmessageModel->load($entityModel->getGiftMessageId()); } 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 8266eedcdf..c8736c6d13 100644 --- a/app/code/core/Mage/Adminhtml/Model/Sales/Order/Create.php +++ b/app/code/core/Mage/Adminhtml/Model/Sales/Order/Create.php @@ -409,6 +409,14 @@ public function initFromOrderItem(Mage_Sales_Model_Order_Item $orderItem, $qty = ) )); } + + Mage::helper('core')->copyFieldset( + 'sales_copy_order_item', + 'to_edit_item', + $orderItem, + $item + ); + Mage::dispatchEvent('sales_convert_order_item_to_quote_item', array( 'order_item' => $orderItem, 'quote_item' => $item @@ -634,13 +642,9 @@ public function applySidebarData($data) } if (isset($data['add_wishlist_item'])) { foreach ($data['add_wishlist_item'] as $itemId => $qty) { - $item = Mage::getModel('wishlist/item')->load($itemId); - if ($item) { - $options = Mage::getResourceModel('wishlist/item_option_collection') - ->addFieldToFilter('code', 'info_buyRequest') - ->addItemFilter(array($itemId)); - - $item->setOptions($options->getOptionsByItem($itemId)); + $item = Mage::getModel('wishlist/item') + ->loadWithOptions($itemId, 'info_buyRequest'); + if ($item->getId()) { $this->addProduct($item->getProduct(), $item->getBuyRequest()->toArray()); } } @@ -708,15 +712,20 @@ public function removeQuoteItem($item) /** * Add product to current order quote + * $product can be either product id or product model + * $config can be either buyRequest config, or just qty * - * @param mixed $product - * @param Varien_Object $config + * @param int|Mage_Catalog_Model_Product $product + * @param float|array|Varien_Object $config * @return Mage_Adminhtml_Model_Sales_Order_Create */ - public function addProduct($product, array $config) + public function addProduct($product, $config = 1) { + if (!is_array($config) && !($config instanceof Varien_Object)) { + $config = array('qty' => $config); + } $config = new Varien_Object($config); - $qty = (float)$config->getQty(); + if (!($product instanceof Mage_Catalog_Model_Product)) { $productId = $product; $product = Mage::getModel('catalog/product') @@ -730,36 +739,28 @@ public function addProduct($product, array $config) } } - if ($product->getStockItem()) { - if (!$product->getStockItem()->getIsQtyDecimal()) { - $qty = (int)$qty; - } else { - $product->setIsQtyDecimal(1); - } + $stockItem = $product->getStockItem(); + if ($stockItem && $stockItem->getIsQtyDecimal()) { + $product->setIsQtyDecimal(1); } - $qty = $qty > 0 ? $qty : 1; - $item = $this->getQuote()->getItemByProduct($product); - if ($item) { - $item->setQty($item->getQty()+$qty); - } else { - $product->setCartQty($config->getQty()); - $item = $this->getQuote()->addProductAdvanced( + + $product->setCartQty($config->getQty()); + $item = $this->getQuote()->addProductAdvanced( + $product, + $config, + Mage_Catalog_Model_Product_Type_Abstract::PROCESS_MODE_FULL + ); + if (is_string($item)) { + $item = $this->getQuote()->addProductAdvanced( $product, $config, - Mage_Catalog_Model_Product_Type_Abstract::PROCESS_MODE_FULL + Mage_Catalog_Model_Product_Type_Abstract::PROCESS_MODE_LITE ); if (is_string($item)) { - $item = $this->getQuote()->addProductAdvanced( - $product, - $config, - Mage_Catalog_Model_Product_Type_Abstract::PROCESS_MODE_LITE - ); - if (is_string($item)) { - Mage::throwException($item); - } + Mage::throwException($item); } - $item->checkData(); } + $item->checkData(); $this->setRecollect(true); return $this; @@ -769,7 +770,7 @@ public function addProduct($product, array $config) * Add multiple products to current order quote * * @param array $products - * @return Mage_Adminhtml_Model_Sales_Order_Create + * @return Mage_Adminhtml_Model_Sales_Order_Create|Exception */ public function addProducts(array $products) { diff --git a/app/code/core/Mage/Adminhtml/controllers/Catalog/ProductController.php b/app/code/core/Mage/Adminhtml/controllers/Catalog/ProductController.php index e97aa466b7..189c04a8c9 100644 --- a/app/code/core/Mage/Adminhtml/controllers/Catalog/ProductController.php +++ b/app/code/core/Mage/Adminhtml/controllers/Catalog/ProductController.php @@ -72,7 +72,12 @@ protected function _initProduct() $product->setData('_edit_mode', true); if ($productId) { - $product->load($productId); + try { + $product->load($productId); + } catch (Exception $e) { + $product->setTypeId(Mage_Catalog_Model_Product_Type::DEFAULT_TYPE); + Mage::logException($e); + } } $attributes = $this->getRequest()->getParam('attributes'); @@ -682,6 +687,9 @@ public function saveAction() ->save(); } } + + Mage::getModel('catalogrule/rule')->applyToProduct($productId); + $this->_getSession()->addSuccess($this->__('The product has been saved.')); } catch (Mage_Core_Exception $e) { @@ -1052,4 +1060,22 @@ protected function _isAllowed() return Mage::getSingleton('admin/session')->isAllowed('catalog/products'); } + /** + * Show item update result from updateAction + * in Wishlist and Cart controllers. + * + */ + public function showUpdateResultAction() + { + $session = Mage::getSingleton('adminhtml/session'); + if ($session->hasCompositeProductResult() && $session->getCompositeProductResult() instanceof Varien_Object){ + /* @var $helper Mage_Adminhtml_Helper_Catalog_Product_Composite */ + $helper = Mage::helper('adminhtml/catalog_product_composite'); + $helper->renderUpdateResult($this, $session->getCompositeProductResult()); + $session->unsCompositeProductResult(); + } else { + $session->unsCompositeProductResult(); + return false; + } + } } diff --git a/app/code/core/Mage/Adminhtml/controllers/Customer/Cart/Product/Composite/CartController.php b/app/code/core/Mage/Adminhtml/controllers/Customer/Cart/Product/Composite/CartController.php index 8848b8a83f..214d874b7e 100644 --- a/app/code/core/Mage/Adminhtml/controllers/Customer/Cart/Product/Composite/CartController.php +++ b/app/code/core/Mage/Adminhtml/controllers/Customer/Cart/Product/Composite/CartController.php @@ -142,10 +142,9 @@ public function updateAction() $updateResult->setMessage($e->getMessage()); } - /* @var $helper Mage_Adminhtml_Helper_Catalog_Product_Composite */ - $helper = Mage::helper('adminhtml/catalog_product_composite'); $updateResult->setJsVarName($this->getRequest()->getParam('as_js_varname')); - $helper->renderUpdateResult($this, $updateResult); + Mage::getSingleton('adminhtml/session')->setCompositeProductResult($updateResult); + $this->_redirect('*/catalog_product/showUpdateResult'); return $this; } diff --git a/app/code/core/Mage/Adminhtml/controllers/Customer/Wishlist/Product/Composite/WishlistController.php b/app/code/core/Mage/Adminhtml/controllers/Customer/Wishlist/Product/Composite/WishlistController.php index 657baa4525..9fa9abde9e 100644 --- a/app/code/core/Mage/Adminhtml/controllers/Customer/Wishlist/Product/Composite/WishlistController.php +++ b/app/code/core/Mage/Adminhtml/controllers/Customer/Wishlist/Product/Composite/WishlistController.php @@ -62,16 +62,12 @@ protected function _initData() /* @var $wishlistItem Mage_Wishlist_Model_Item */ $wishlistItem = Mage::getModel('wishlist/item') - ->load($wishlistItemId); + ->loadWithOptions($wishlistItemId); if (!$wishlistItem->getWishlistId()) { Mage::throwException($this->__('Wishlist item is not loaded.')); } - $optionCollection = Mage::getModel('wishlist/item_option')->getCollection() - ->addItemFilter(array($wishlistItemId)); - $wishlistItem->setOptions($optionCollection->getOptionsByItem($wishlistItem)); - $this->_wishlist = Mage::getModel('wishlist/wishlist') ->load($wishlistItem->getWishlistId()); @@ -135,29 +131,9 @@ public function updateAction() $updateResult->setMessage($e->getMessage()); } $updateResult->setJsVarName($this->getRequest()->getParam('as_js_varname')); - /* @var $helper Mage_Adminhtml_Helper_Catalog_Product_Composite */ - $helper = Mage::helper('adminhtml/catalog_product_composite'); Mage::getSingleton('adminhtml/session')->setCompositeProductResult($updateResult); - $this->_redirect('*/*/showUpdateResult'); + $this->_redirect('*/catalog_product/showUpdateResult'); return false; } - - /* - * Show item update result from updateAction - * - */ - public function showUpdateResultAction() - { - $session = Mage::getSingleton('adminhtml/session'); - if ($session->hasCompositeProductResult() && $session->getCompositeProductResult() instanceof Varien_Object){ - /* @var $helper Mage_Adminhtml_Helper_Catalog_Product_Composite */ - $helper = Mage::helper('adminhtml/catalog_product_composite'); - $helper->renderUpdateResult($this, $session->getCompositeProductResult()); - $session->unsCompositeProductResult(null); - } else { - $session->unsCompositeProductResult(); - return false; - } - } } diff --git a/app/code/core/Mage/Adminhtml/controllers/IndexController.php b/app/code/core/Mage/Adminhtml/controllers/IndexController.php index 250e07d1dc..7472170b29 100644 --- a/app/code/core/Mage/Adminhtml/controllers/IndexController.php +++ b/app/code/core/Mage/Adminhtml/controllers/IndexController.php @@ -67,15 +67,16 @@ public function loginAction() } else { $data['username'] = null; } - #print_r($data); + $this->_outTemplate('login', $data); } public function logoutAction() { - $auth = Mage::getSingleton('admin/session')->unsetAll(); - Mage::getSingleton('adminhtml/session')->unsetAll(); - Mage::getSingleton('adminhtml/session')->addSuccess(Mage::helper('adminhtml')->__('You have logged out.')); + $adminSession = Mage::getSingleton('admin/session'); + $adminSession->unsetAll(); + $adminSession->addSuccess(Mage::helper('adminhtml')->__('You have logged out.')); + $this->_redirect('*'); } @@ -86,15 +87,20 @@ public function globalSearchAction() if ( !Mage::getSingleton('admin/session')->isAllowed('admin/global_search') ) { $items[] = array( - 'id'=>'error', - 'type'=>'Error', - 'name'=>Mage::helper('adminhtml')->__('Access Denied'), - 'description'=>Mage::helper('adminhtml')->__('You have not enough permissions to use this functionality.') + 'id' => 'error', + 'type' => 'Error', + 'name' => Mage::helper('adminhtml')->__('Access Denied'), + 'description' => Mage::helper('adminhtml')->__('You have not enough permissions to use this functionality.') ); $totalCount = 1; } else { if (empty($searchModules)) { - $items[] = array('id'=>'error', 'type'=>'Error', 'name'=>Mage::helper('adminhtml')->__('No search modules were registered'), 'description'=>Mage::helper('adminhtml')->__('Please make sure that all global admin search modules are installed and activated.')); + $items[] = array( + 'id' => 'error', + 'type' => 'Error', + 'name' => Mage::helper('adminhtml')->__('No search modules were registered'), + 'description' => Mage::helper('adminhtml')->__('Please make sure that all global admin search modules are installed and activated.') + ); $totalCount = 1; } else { $start = $this->getRequest()->getParam('start', 1); @@ -170,7 +176,7 @@ protected function _getDeniedIframe() return ''; } - public function forgotpasswordAction () + public function forgotpasswordAction() { $email = $this->getRequest()->getParam('email'); $params = $this->getRequest()->getParams(); 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 d2f9a7a1c4..d10be9d214 100644 --- a/app/code/core/Mage/Adminhtml/controllers/Sales/Order/CreateController.php +++ b/app/code/core/Mage/Adminhtml/controllers/Sales/Order/CreateController.php @@ -179,11 +179,11 @@ protected function _processData($action = null) } /** - * Adding products to quote from special grid and + * Adding products to quote from special grid */ if ($this->getRequest()->has('item') && !$this->getRequest()->getPost('update_items') && !($action == 'save')) { $items = $this->getRequest()->getPost('item'); - $items = $this->_processFiles('create_items', $items); + $items = $this->_processFiles($items); $this->_getOrderCreateModel()->addProducts($items); } @@ -192,24 +192,26 @@ protected function _processData($action = null) */ if ($this->getRequest()->getPost('update_items')) { $items = $this->getRequest()->getPost('item', array()); - $items = $this->_processFiles('update_items', $items); + $items = $this->_processFiles($items); $this->_getOrderCreateModel()->updateQuoteItems($items); } /** * Remove quote item */ - if ( ($itemId = (int) $this->getRequest()->getPost('remove_item')) - && ($from = (string) $this->getRequest()->getPost('from'))) { - $this->_getOrderCreateModel($itemId)->removeItem($itemId, $from); + $removeItemId = (int) $this->getRequest()->getPost('remove_item'); + $removeFrom = (string) $this->getRequest()->getPost('from'); + if ($removeItemId && $removeFrom) { + $this->_getOrderCreateModel()->removeItem($removeItemId, $removeFrom); } /** * Move quote item */ - if ( ($itemId = (int) $this->getRequest()->getPost('move_item')) - && ($moveTo = (string) $this->getRequest()->getPost('to')) ) { - $this->_getOrderCreateModel()->moveQuoteItem($itemId, $moveTo); + $moveItemId = (int) $this->getRequest()->getPost('move_item'); + $moveTo = (string) $this->getRequest()->getPost('to'); + if ($moveItemId && $moveTo) { + $this->_getOrderCreateModel()->moveQuoteItem($moveItemId, $moveTo); } /*if ($paymentData = $this->getRequest()->getPost('payment')) { @@ -271,28 +273,18 @@ protected function _processData($action = null) /** * Process buyRequest file options of items * - * @param string $method * @param array $items * @return array */ - protected function _processFiles ($method, $items) + protected function _processFiles($items) { + /* @var $productHelper Mage_Catalog_Helper_Product */ $productHelper = Mage::helper('catalog/product'); foreach ($items as $id => $item) { $buyRequest = new Varien_Object($item); - switch ($method) { - case 'create_items': - $buyRequest = $productHelper->processBuyRequestFiles($buyRequest, null, $id); - break; - case 'update_items': - $quoteItem = $this->_getQuote()->getItemById($id); - if ($quoteItem instanceof Mage_Sales_Model_Quote_Item) { - $itemBuyRequest = $quoteItem->getBuyRequest(); - $buyRequest = $productHelper->processBuyRequestFiles($buyRequest, $itemBuyRequest, $id); - } - break; - } - if ($buyRequest instanceof Varien_Object && $buyRequest->hasData()) { + $params = array('files_prefix' => 'item_' . $id . '_'); + $buyRequest = $productHelper->addParamsToBuyRequest($buyRequest, $params); + if ($buyRequest->hasData()) { $items[$id] = $buyRequest->toArray(); } } @@ -344,6 +336,7 @@ protected function _reloadQuote() */ public function loadBlockAction() { + $request = $this->getRequest(); try { $this->_initSession() ->_processData(); @@ -358,8 +351,8 @@ public function loadBlockAction() } - $asJson= $this->getRequest()->getParam('json'); - $block = $this->getRequest()->getParam('block'); + $asJson= $request->getParam('json'); + $block = $request->getParam('block'); $update = $this->getLayout()->getUpdate(); if ($asJson) { @@ -379,7 +372,13 @@ public function loadBlockAction() } } $this->loadLayoutUpdates()->generateLayoutXml()->generateLayoutBlocks(); - $this->getResponse()->setBody($this->getLayout()->getBlock('content')->toHtml()); + $result = $this->getLayout()->getBlock('content')->toHtml(); + if ($request->getParam('as_js_varname')) { + Mage::getSingleton('adminhtml/session')->setUpdateResult($result); + $this->_redirect('*/*/showUpdateResult'); + } else { + $this->getResponse()->setBody($result); + } } /** @@ -406,9 +405,9 @@ public function addConfiguredAction() $updateResult->setOk(true); } - /* @var $helper Mage_Adminhtml_Helper_Catalog_Product_Composite */ - $helper = Mage::helper('adminhtml/catalog_product_composite'); - $helper->renderUpdateResult($this, $updateResult); + $updateResult->setJsVarName($this->getRequest()->getParam('as_js_varname')); + Mage::getSingleton('adminhtml/session')->setCompositeProductResult($updateResult); + $this->_redirect('*/catalog_product/showUpdateResult'); } /** @@ -484,7 +483,7 @@ public function saveAction() */ protected function _isAllowed() { - $action = strtolower($this->getRequest()->getActionName()); + $action = strtolower($this->getRequest()->getActionName()); switch ($action) { case 'index': $aclResource = 'sales/order/actions/create'; @@ -573,4 +572,22 @@ public function configureQuoteItemsAction() return $this; } + + + /** + * Show item update result from loadBlockAction + * to prevent popup alert with resend data question + * + */ + public function showUpdateResultAction() + { + $session = Mage::getSingleton('adminhtml/session'); + if ($session->hasUpdateResult() && is_scalar($session->getUpdateResult())){ + $this->getResponse()->setBody($session->getUpdateResult()); + $session->unsUpdateResult(); + } else { + $session->unsUpdateResult(); + return false; + } + } } diff --git a/app/code/core/Mage/Adminhtml/controllers/System/Config/System/StorageController.php b/app/code/core/Mage/Adminhtml/controllers/System/Config/System/StorageController.php index e5faf74262..376af71c88 100644 --- a/app/code/core/Mage/Adminhtml/controllers/System/Config/System/StorageController.php +++ b/app/code/core/Mage/Adminhtml/controllers/System/Config/System/StorageController.php @@ -34,6 +34,16 @@ class Mage_Adminhtml_System_Config_System_StorageController extends Mage_Adminhtml_Controller_Action { + /** + * Return file storage singleton + * + * @return Mage_Core_Model_File_Storage + */ + protected function _getSyncSingleton() + { + return Mage::getSingleton('core/file_storage'); + } + /** * Return synchronize process status flag * @@ -41,7 +51,7 @@ class Mage_Adminhtml_System_Config_System_StorageController extends Mage_Adminht */ protected function _getSyncFlag() { - return Mage::getModel('core/file_storage_flag')->loadSelf(); + return $this->_getSyncSingleton()->getSyncFlag(); } /** @@ -51,12 +61,12 @@ protected function _getSyncFlag() */ public function synchronizeAction() { + session_write_close(); + if (!isset($_REQUEST['storage'])) { return; } - session_write_close(); - $flag = $this->_getSyncFlag(); if ($flag && $flag->getState() == Mage_Core_Model_File_Storage_Flag::STATE_RUNNING && $flag->getLastUpdate() @@ -64,7 +74,9 @@ public function synchronizeAction() ) { return; } - $flag->setState(1)->save(); + + $flag->setState(Mage_Core_Model_File_Storage_Flag::STATE_RUNNING)->save(); + Mage::getSingleton('admin/session')->setSyncProcessStopWatch(false); $storage = array('type' => (int) $_REQUEST['storage']); if (isset($_REQUEST['connection']) && !empty($_REQUEST['connection'])) { @@ -72,11 +84,12 @@ public function synchronizeAction() } try { - Mage::getModel('core/file_storage')->synchronize($storage, $flag); + $this->_getSyncSingleton()->synchronize($storage); } catch (Exception $e) { Mage::logException($e); } - $flag->delete(); + + $flag->setState(Mage_Core_Model_File_Storage_Flag::STATE_FINISHED)->save(); } /** @@ -86,23 +99,83 @@ public function synchronizeAction() */ public function statusAction() { + $result = array(); $flag = $this->_getSyncFlag(); - if ($flag && $flag->getState() == Mage_Core_Model_File_Storage_Flag::STATE_RUNNING - && $flag->getLastUpdate() - && time() <= (strtotime($flag->getLastUpdate()) + Mage_Core_Model_File_Storage_Flag::FLAG_TTL) - ) { - $result = array('state' => Mage_Core_Model_File_Storage_Flag::STATE_RUNNING); - - $flagData = $flag->getFlagData(); - if (is_array($flagData) - && isset($flagData['source']) && !empty($flagData['source']) - && isset($flagData['destination']) && !empty($flagData['destination']) - ) { - $result['message'] = Mage::helper('adminhtml')->__('Synchronizing %s to %s', $flagData['source'], $flagData['destination']); + + if ($flag) { + $state = $flag->getState(); + + switch ($state) { + case Mage_Core_Model_File_Storage_Flag::STATE_INACTIVE: + $flagData = $flag->getFlagData(); + if (is_array($flagData)) { + if (isset($flagData['destination']) && !empty($flagData['destination'])) { + $result['destination'] = $flagData['destination']; + } + } + + $state = Mage_Core_Model_File_Storage_Flag::STATE_INACTIVE; + break; + case Mage_Core_Model_File_Storage_Flag::STATE_RUNNING: + if (!$flag->getLastUpdate() + || time() <= (strtotime($flag->getLastUpdate()) + Mage_Core_Model_File_Storage_Flag::FLAG_TTL) + ) { + $flagData = $flag->getFlagData(); + if (is_array($flagData) + && isset($flagData['source']) && !empty($flagData['source']) + && isset($flagData['destination']) && !empty($flagData['destination']) + ) { + $result['message'] = Mage::helper('adminhtml')->__('Synchronizing %s to %s', $flagData['source'], $flagData['destination']); + } else { + $result['message'] = Mage::helper('adminhtml')->__('Synchronizing...'); + } + + break; + } else { + $flagData = $flag->getFlagData(); + if (is_array($flagData) + && !(isset($flagData['timeout_reached']) && $flagData['timeout_reached']) + ) { + Mage::logException(new Mage_Exception( + Mage::helper('adminhtml')->__('Timeout limit for response from synchronize process was reached.') + )); + + $state = Mage_Core_Model_File_Storage_Flag::STATE_FINISHED; + + $flagData['has_errors'] = true; + $flagData['timeout_reached'] = true; + + $flag->setState($state) + ->setFlagData($flagData) + ->save(); + } + } + case Mage_Core_Model_File_Storage_Flag::STATE_FINISHED: + Mage::dispatchEvent('add_synchronize_message'); + + $state = Mage_Core_Model_File_Storage_Flag::STATE_NOTIFIED; + case Mage_Core_Model_File_Storage_Flag::STATE_NOTIFIED: + $block = Mage::getSingleton('core/layout') + ->createBlock('adminhtml/notification_toolbar') + ->setTemplate('notification/toolbar.phtml'); + $result['html'] = $block->toHtml(); + + $flagData = $flag->getFlagData(); + if (is_array($flagData)) { + if (isset($flagData['has_errors']) && $flagData['has_errors']) { + $result['has_errors'] = true; + } + } + + break; + default: + $state = Mage_Core_Model_File_Storage_Flag::STATE_INACTIVE; + break; } } else { - $result = array('state' => Mage_Core_Model_File_Storage_Flag::STATE_INACTIVE); + $state = Mage_Core_Model_File_Storage_Flag::STATE_INACTIVE; } + $result['state'] = $state; $result = Mage::helper('core')->jsonEncode($result); Mage::app()->getResponse()->setBody($result); diff --git a/app/code/core/Mage/Authorizenet/Helper/Data.php b/app/code/core/Mage/Authorizenet/Helper/Data.php index bb25a8cf09..544b5a604a 100755 --- a/app/code/core/Mage/Authorizenet/Helper/Data.php +++ b/app/code/core/Mage/Authorizenet/Helper/Data.php @@ -45,6 +45,24 @@ public function getAdminUrl($route, $params) return Mage::getModel('adminhtml/url')->getUrl($route, $params); } + /** + * Set secure url checkout is secure for current store. + * + * @param string $route + * @param array $params + * @return string + */ + protected function _getUrl($route, $params = array()) + { + $params['_type'] = Mage_Core_Model_Store::URL_TYPE_LINK; + if (isset($params['is_secure'])) { + $params['_secure'] = (bool)$params['is_secure']; + } elseif (Mage::app()->getStore()->isCurrentlySecure()) { + $params['_secure'] = true; + } + return parent::_getUrl($route, $params); + } + /** * Retrieve save order url params * @@ -118,7 +136,7 @@ public function getPlaceOrderFrontUrl() */ public function getPlaceOrderAdminUrl() { - return $this->_getUrl('*/authorizenet_directpost_payment/place'); + return $this->getAdminUrl('*/authorizenet_directpost_payment/place', array()); } /** diff --git a/app/code/core/Mage/Authorizenet/Model/Directpost.php b/app/code/core/Mage/Authorizenet/Model/Directpost.php index 1988c380c5..427e73247a 100644 --- a/app/code/core/Mage/Authorizenet/Model/Directpost.php +++ b/app/code/core/Mage/Authorizenet/Model/Directpost.php @@ -75,8 +75,138 @@ public function authorize(Varien_Object $payment, $amount) $payment->setAdditionalInformation('payment_type', $this->getConfigData('payment_action')); } - /** - * Refund the amount with transaction id. + /** + * Send capture request to gateway + * + * @param Varien_Object $payment + * @param decimal $amount + * @return Mage_Authorizenet_Model_Directpost + * @throws Mage_Core_Exception + */ + public function capture(Varien_Object $payment, $amount) + { + if ($amount <= 0) { + Mage::throwException(Mage::helper('paygate')->__('Invalid amount for capture.')); + } + + $payment->setAmount($amount); + + if ($payment->getParentTransactionId()) { + $payment->setAnetTransType(self::REQUEST_TYPE_PRIOR_AUTH_CAPTURE); + $payment->setXTransId($this->_getRealParentTransactionId($payment)); + } else { + $payment->setAnetTransType(self::REQUEST_TYPE_AUTH_CAPTURE); + } + + $request= $this->_buildRequest($payment); + $result = $this->_postRequest($request); + + switch ($result->getResponseCode()) { + case self::RESPONSE_CODE_APPROVED: + if ($result->getResponseReasonCode() == self::RESPONSE_REASON_CODE_APPROVED) { + if (!$payment->getParentTransactionId() || + $result->getTransactionId() != $payment->getParentTransactionId()) { + $payment->setTransactionId($result->getTransactionId()); + } + $payment + ->setIsTransactionClosed(0) + ->setTransactionAdditionalInfo($this->_realTransactionIdKey, $result->getTransactionId()); + return $this; + } + Mage::throwException($this->_wrapGatewayError($result->getResponseReasonText())); + case self::RESPONSE_CODE_DECLINED: + case self::RESPONSE_CODE_ERROR: + Mage::throwException($this->_wrapGatewayError($result->getResponseReasonText())); + default: + Mage::throwException(Mage::helper('paygate')->__('Payment capturing error.')); + } + } + + /** + * Check refund availability + * + * @return bool + */ + public function canRefund() + { + return $this->_canRefund; + } + + /** + * Check void availability + * + * @param Varien_Object $invoicePayment + * @return bool + */ + public function canVoid(Varien_Object $payment) + { + return $this->_canVoid; + } + + /** + * Void the payment through gateway + * + * @param Varien_Object $payment + * @return Mage_Authorizenet_Model_Directpost + * @throws Mage_Core_Exception + */ + public function void(Varien_Object $payment) + { + if (!$payment->getParentTransactionId()) { + Mage::throwException(Mage::helper('paygate')->__('Invalid transaction ID.')); + } + + $payment->setAnetTransType(self::REQUEST_TYPE_VOID); + $payment->setXTransId($this->_getRealParentTransactionId($payment)); + + $request = $this->_buildRequest($payment); + $result = $this->_postRequest($request); + + switch ($result->getResponseCode()) { + case self::RESPONSE_CODE_APPROVED: + if ($result->getResponseReasonCode() == self::RESPONSE_REASON_CODE_APPROVED) { + if ($result->getTransactionId() != $payment->getParentTransactionId()) { + $payment->setTransactionId($result->getTransactionId()); + } + $payment + ->setIsTransactionClosed(1) + ->setShouldCloseParentTransaction(1) + ->setTransactionAdditionalInfo($this->_realTransactionIdKey, $result->getTransactionId()); + return $this; + } + Mage::throwException($this->_wrapGatewayError($result->getResponseReasonText())); + case self::RESPONSE_CODE_DECLINED: + case self::RESPONSE_CODE_ERROR: + Mage::throwException($this->_wrapGatewayError($result->getResponseReasonText())); + default: + Mage::throwException(Mage::helper('paygate')->__('Payment voiding error.')); + } + } + + /** + * Set capture transaction ID to invoice for informational purposes + * @param Mage_Sales_Model_Order_Invoice $invoice + * @param Mage_Sales_Model_Order_Payment $payment + * @return Mage_Payment_Model_Method_Abstract + */ + public function processInvoice($invoice, $payment) + { + return Mage_Payment_Model_Method_Abstract::processInvoice($invoice, $payment); + } + + /** + * Set transaction ID into creditmemo for informational purposes + * @param Mage_Sales_Model_Order_Creditmemo $creditmemo + * @param Mage_Sales_Model_Order_Payment $payment + * @return Mage_Payment_Model_Method_Abstract + */ + public function processCreditmemo($creditmemo, $payment) + { + return Mage_Payment_Model_Method_Abstract::processCreditmemo($creditmemo, $payment); + } + + /** + * Refund the amount * Need to decode Last 4 digits for request. * * @param Varien_Object $payment @@ -89,7 +219,7 @@ public function refund(Varien_Object $payment, $amount) $last4 = $payment->getCcLast4(); $payment->setCcLast4($payment->decrypt($last4)); try { - parent::refund($payment, $amount); + $this->_refund($payment, $amount); } catch (Exception $e) { $payment->setCcLast4($last4); throw $e; @@ -98,6 +228,51 @@ public function refund(Varien_Object $payment, $amount) return $this; } + /** + * refund the amount with transaction id + * + * @param string $payment Varien_Object object + * @return Mage_Authorizenet_Model_Directpost + * @throws Mage_Core_Exception + */ + protected function _refund(Varien_Object $payment, $amount) + { + if ($amount <= 0) { + Mage::throwException(Mage::helper('paygate')->__('Invalid amount for refund.')); + } + + if (!$payment->getParentTransactionId()) { + Mage::throwException(Mage::helper('paygate')->__('Invalid transaction ID.')); + } + + $payment->setAnetTransType(self::REQUEST_TYPE_CREDIT); + $payment->setAmount($amount); + $payment->setXTransId($this->_getRealParentTransactionId($payment)); + + $request = $this->_buildRequest($payment); + $result = $this->_postRequest($request); + + switch ($result->getResponseCode()) { + case self::RESPONSE_CODE_APPROVED: + if ($result->getResponseReasonCode() == self::RESPONSE_REASON_CODE_APPROVED) { + if ($result->getTransactionId() != $payment->getParentTransactionId()) { + $payment->setTransactionId($result->getTransactionId()); + } + $payment + ->setIsTransactionClosed(1) + ->setShouldCloseParentTransaction(1) + ->setTransactionAdditionalInfo($this->_realTransactionIdKey, $result->getTransactionId()); + return $this; + } + Mage::throwException($this->_wrapGatewayError($result->getResponseReasonText())); + case self::RESPONSE_CODE_DECLINED: + case self::RESPONSE_CODE_ERROR: + Mage::throwException($this->_wrapGatewayError($result->getResponseReasonText())); + default: + Mage::throwException(Mage::helper('paygate')->__('Payment refunding error.')); + } + } + /** * Get CGI url * @@ -118,7 +293,7 @@ public function getCgiUrl() public function getRelayUrl($storeId = null) { return Mage::app()->getStore($storeId) - ->getBaseUrl(Mage_Core_Model_Store::URL_TYPE_WEB). + ->getBaseUrl(Mage_Core_Model_Store::URL_TYPE_LINK). 'authorizenet/directpost_payment/response'; } @@ -436,4 +611,16 @@ protected function _captureOrder(Mage_Sales_Model_Order $order) } } } + + /** + * Return additional information`s transaction_id value of parent transaction model + * + * @param Mage_Sales_Model_Order_Payment $payment + * @return string + */ + protected function _getRealParentTransactionId($payment) + { + $transaction = $payment->getTransaction($payment->getParentTransactionId()); + return $transaction->getAdditionalInformation($this->_realTransactionIdKey); + } } diff --git a/app/code/core/Mage/Authorizenet/Model/Directpost/Observer.php b/app/code/core/Mage/Authorizenet/Model/Directpost/Observer.php index 78459c7650..65f5eb7ef7 100644 --- a/app/code/core/Mage/Authorizenet/Model/Directpost/Observer.php +++ b/app/code/core/Mage/Authorizenet/Model/Directpost/Observer.php @@ -77,6 +77,7 @@ public function addAdditionalFieldsToResponseFrontend(Varien_Event_Observer $obs $session->setLastOrderIncrementId($order->getIncrementId()); $requestToPaygate = $payment->getMethodInstance()->generateRequestFromOrder($order); $requestToPaygate->setControllerActionName($controller->getRequest()->getControllerName()); + $requestToPaygate->setIsSecure((string)Mage::app()->getStore()->isCurrentlySecure()); $result['directpost'] = array('fields' => $requestToPaygate->getData()); diff --git a/app/code/core/Mage/Authorizenet/controllers/Directpost/PaymentController.php b/app/code/core/Mage/Authorizenet/controllers/Directpost/PaymentController.php index 1bce7b3022..e4ab650249 100644 --- a/app/code/core/Mage/Authorizenet/controllers/Directpost/PaymentController.php +++ b/app/code/core/Mage/Authorizenet/controllers/Directpost/PaymentController.php @@ -96,6 +96,7 @@ public function responseAction() $result['key'] = $data['key']; } $result['controller_action_name'] = $data['controller_action_name']; + $result['is_secure'] = isset($data['is_secure']) ? $data['is_secure'] : false; $params['redirect'] = Mage::helper('authorizenet')->getRedirectIframeUrl($result); } $block = $this->_getIframeBlock()->setParams($params); diff --git a/app/code/core/Mage/Bundle/Block/Adminhtml/Catalog/Product/Edit/Tab/Attributes.php b/app/code/core/Mage/Bundle/Block/Adminhtml/Catalog/Product/Edit/Tab/Attributes.php index 51dd16f62c..6d578500b0 100644 --- a/app/code/core/Mage/Bundle/Block/Adminhtml/Catalog/Product/Edit/Tab/Attributes.php +++ b/app/code/core/Mage/Bundle/Block/Adminhtml/Catalog/Product/Edit/Tab/Attributes.php @@ -58,6 +58,31 @@ protected function _prepareForm() ); } + if ($tax = $this->getForm()->getElement('tax_class_id')) { + $tax->setAfterElementHtml( + '' + ); + } + if ($weight = $this->getForm()->getElement('weight')) { $weight->setRenderer( $this->getLayout()->createBlock('bundle/adminhtml_catalog_product_edit_tab_attributes_extend') diff --git a/app/code/core/Mage/Bundle/Block/Catalog/Product/Price.php b/app/code/core/Mage/Bundle/Block/Catalog/Product/Price.php index 86e23b8c72..10e806aca5 100644 --- a/app/code/core/Mage/Bundle/Block/Catalog/Product/Price.php +++ b/app/code/core/Mage/Bundle/Block/Catalog/Product/Price.php @@ -47,4 +47,19 @@ public function isRatesGraterThenZero() return (floatval($defaultTax) > 0 || floatval($currentTax) > 0); } + /** + * Check if we have display prices including and excluding tax + * With corrections for Dynamic prices + * + * @return bool + */ + public function displayBothPrices() + { + $product = $this->getProduct(); + if ($product->getPriceType() == Mage_Bundle_Model_Product_Price::PRICE_TYPE_DYNAMIC && + $product->getPriceModel()->getIsPricesCalculatedByIndex() !== false) { + return false; + } + return $this->helper('tax')->displayBothPrices(); + } } diff --git a/app/code/core/Mage/Bundle/Block/Catalog/Product/View/Type/Bundle/Option.php b/app/code/core/Mage/Bundle/Block/Catalog/Product/View/Type/Bundle/Option.php index 46b29a566b..2fe47a328a 100644 --- a/app/code/core/Mage/Bundle/Block/Catalog/Product/View/Type/Bundle/Option.php +++ b/app/code/core/Mage/Bundle/Block/Catalog/Product/View/Type/Bundle/Option.php @@ -189,8 +189,12 @@ public function getSelectionQtyTitlePrice($_selection, $includeContainer = true) public function getSelectionPrice($_selection) { $price = 0; + $store = $this->getProduct()->getStore(); if ($_selection) { $price = $this->getProduct()->getPriceModel()->getSelectionPreFinalPrice($this->getProduct(), $_selection); + if (is_numeric($price)) { + $price = $this->helper('core')->currencyByStore($price, $store, false); + } } return is_numeric($price) ? $price : 0; } diff --git a/app/code/core/Mage/Bundle/Model/Mysql4/Indexer/Price.php b/app/code/core/Mage/Bundle/Model/Mysql4/Indexer/Price.php index 6c0e7a8e9c..cd108089eb 100644 --- a/app/code/core/Mage/Bundle/Model/Mysql4/Indexer/Price.php +++ b/app/code/core/Mage/Bundle/Model/Mysql4/Indexer/Price.php @@ -169,8 +169,12 @@ protected function _prepareBundlePriceByType($priceType, $entityIds = null) $statusCond = $write->quoteInto('=?', Mage_Catalog_Model_Product_Status::STATUS_ENABLED); $this->_addAttributeToSelect($select, 'status', 'e.entity_id', 'cs.store_id', $statusCond, true); - $taxClassId = $this->_addAttributeToSelect($select, 'tax_class_id', 'e.entity_id', 'cs.store_id'); - $select->columns(array('tax_class_id' => new Zend_Db_Expr("IF($taxClassId IS NOT NULL, $taxClassId, 0)"))); + if ($priceType == Mage_Bundle_Model_Product_Price::PRICE_TYPE_DYNAMIC) { + $select->columns(array('tax_class_id' => new Zend_Db_Expr('0'))); + } else { + $taxClassId = $this->_addAttributeToSelect($select, 'tax_class_id', 'e.entity_id', 'cs.store_id'); + $select->columns(array('tax_class_id' => new Zend_Db_Expr("IF($taxClassId IS NOT NULL, $taxClassId, 0)"))); + } $priceTypeCond = $write->quoteInto('=?', $priceType); $this->_addAttributeToSelect($select, 'price_type', 'e.entity_id', 'cs.store_id', $priceTypeCond); diff --git a/app/code/core/Mage/Bundle/Model/Mysql4/Selection/Collection.php b/app/code/core/Mage/Bundle/Model/Mysql4/Selection/Collection.php index 52505adf79..f6f7a30aa7 100644 --- a/app/code/core/Mage/Bundle/Model/Mysql4/Selection/Collection.php +++ b/app/code/core/Mage/Bundle/Model/Mysql4/Selection/Collection.php @@ -114,4 +114,20 @@ public function setPositionOrder() ->order('selection.selection_id asc'); return $this; } + + /** + * Set store id for each collection item when collection was loaded + * + * @return void + */ + public function _afterLoad() + { + parent::_afterLoad(); + if ($this->getStoreId() && $this->_items) { + foreach ($this->_items as $item) { + $item->setStoreId($this->getStoreId()); + } + } + return $this; + } } diff --git a/app/code/core/Mage/Bundle/Model/Product/Price.php b/app/code/core/Mage/Bundle/Model/Product/Price.php index ab4691a0d6..c960fc21f7 100644 --- a/app/code/core/Mage/Bundle/Model/Product/Price.php +++ b/app/code/core/Mage/Bundle/Model/Product/Price.php @@ -36,6 +36,23 @@ class Mage_Bundle_Model_Product_Price extends Mage_Catalog_Model_Product_Type_Pr const PRICE_TYPE_FIXED = 1; const PRICE_TYPE_DYNAMIC = 0; + /** + * Flag wich indicates - is min/max prices have been calculated by index + * + * @var bool + */ + protected $_isPricesCalculatedByIndex; + + /** + * Is min/max prices have been calculated by index + * + * @return bool + */ + public function getIsPricesCalculatedByIndex() + { + return $this->_isPricesCalculatedByIndex; + } + /** * Return product base price * @@ -152,6 +169,7 @@ public function getPricesDependingOnTax($product, $which = null, $includeTax = n $product->getData('max_price')) { $minimalPrice = Mage::helper('tax')->getPrice($product, $product->getData('min_price'), $includeTax); $maximalPrice = Mage::helper('tax')->getPrice($product, $product->getData('max_price'), $includeTax); + $this->_isPricesCalculatedByIndex = true; } else { /** * Check if product price is fixed @@ -257,6 +275,7 @@ public function getPricesDependingOnTax($product, $which = null, $includeTax = n } } } + $this->_isPricesCalculatedByIndex = false; } if ($which == 'max') { diff --git a/app/code/core/Mage/Bundle/Model/Product/Type.php b/app/code/core/Mage/Bundle/Model/Product/Type.php index 0f465f8328..91d197159f 100644 --- a/app/code/core/Mage/Bundle/Model/Product/Type.php +++ b/app/code/core/Mage/Bundle/Model/Product/Type.php @@ -82,6 +82,13 @@ class Mage_Bundle_Model_Product_Type extends Mage_Catalog_Model_Product_Type_Abs */ protected $_keyUsedOptionsIds = '_cache_instance_used_options_ids'; + /** + * Product is configurable + * + * @var bool + */ + protected $_canConfigure = true; + /** * Return relation info about used products * diff --git a/app/code/core/Mage/Bundle/etc/config.xml b/app/code/core/Mage/Bundle/etc/config.xml index 675c5cdc2f..34311d11ff 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.13 + 0.1.14 diff --git a/app/code/core/Mage/Bundle/sql/bundle_setup/mysql4-data-upgrade-0.1.13-0.1.14.php b/app/code/core/Mage/Bundle/sql/bundle_setup/mysql4-data-upgrade-0.1.13-0.1.14.php new file mode 100644 index 0000000000..db5aca9e25 --- /dev/null +++ b/app/code/core/Mage/Bundle/sql/bundle_setup/mysql4-data-upgrade-0.1.13-0.1.14.php @@ -0,0 +1,82 @@ +getAttribute('catalog_product', 'price_type'); +$taxClassAttribute = $installer->getAttribute('catalog_product', 'tax_class_id'); + +$productTable = $installer->getTable('catalog/product'); +$priceTypeTable = $productTable ."_". $priceTypeAttribute['backend_type']; +$taxClassTable = $productTable ."_". $taxClassAttribute['backend_type']; + +$db = $installer->getConnection(); +$db->beginTransaction(); +try { + // select bundle product ids with dynamic price + $select = $db->select() + ->from(array('attr' => $priceTypeTable), 'attr.entity_id') + ->joinLeft(array('e' => $productTable), 'attr.entity_id = e.entity_id', '') + ->where('attr.attribute_id = ?', $priceTypeAttribute['attribute_id']) + ->where('e.type_id = ?', 'bundle') + ->where('attr.value = ?', 0); + + $isDataChanged = false; + $stmt = $db->query($select); + // set "None" tax class attribute for bundles with dynamic price + while ($row = $stmt->fetch()) { + $data = array('value' => 0); + $where = array( + 'attribute_id = ?' => $taxClassAttribute['attribute_id'], + 'entity_id = ?' => $row['entity_id'] + ); + $count = $db->update($taxClassTable, $data, $where); + if ($count > 0) { + $isDataChanged = true; + } + } + + // set "Requere Reindex" status for some indexes if attributes data has been modified + if ($isDataChanged) { + $indexerCodes = array( + 'catalog_product_attribute', + 'catalog_product_price', + 'catalog_product_flat' + ); + + $indexer = Mage::getModel('index/process'); + foreach ($indexerCodes as $code) { + $indexer->load($code, 'indexer_code') + ->changeStatus(Mage_Index_Model_Process::STATUS_REQUIRE_REINDEX); + } + } + $db->commit(); + +} catch (Exception $e) { + $db->rollback(); + throw $e; +} diff --git a/app/code/core/Mage/Catalog/Block/Product/Abstract.php b/app/code/core/Mage/Catalog/Block/Product/Abstract.php index b67116ad59..434034d349 100644 --- a/app/code/core/Mage/Catalog/Block/Product/Abstract.php +++ b/app/code/core/Mage/Catalog/Block/Product/Abstract.php @@ -172,20 +172,34 @@ protected function _getPriceBlockTemplate($productTypeId) return $this->_priceBlockDefaultTemplate; } + + /** + * Prepares and returns block to render some product type + * + * @param string $productType + * @return Mage_Core_Block_Template + */ + public function _preparePriceRenderer($productType) + { + return $this->_getPriceBlock($productType) + ->setTemplate($this->_getPriceBlockTemplate($productType)) + ->setUseLinkForAsLowAs($this->_useLinkForAsLowAs); + } + /** * Returns product price block html * * @param Mage_Catalog_Model_Product $product * @param boolean $displayMinimalPrice + * @param string $idSuffix + * @return string */ - public function getPriceHtml($product, $displayMinimalPrice = false, $idSuffix='') + public function getPriceHtml($product, $displayMinimalPrice = false, $idSuffix = '') { - return $this->_getPriceBlock($product->getTypeId()) - ->setTemplate($this->_getPriceBlockTemplate($product->getTypeId())) + return $this->_preparePriceRenderer($product->getTypeId()) ->setProduct($product) ->setDisplayMinimalPrice($displayMinimalPrice) ->setIdSuffix($idSuffix) - ->setUseLinkForAsLowAs($this->_useLinkForAsLowAs) ->toHtml(); } diff --git a/app/code/core/Mage/Catalog/Block/Product/List.php b/app/code/core/Mage/Catalog/Block/Product/List.php index 4fbc86254f..1b0e937c68 100644 --- a/app/code/core/Mage/Catalog/Block/Product/List.php +++ b/app/code/core/Mage/Catalog/Block/Product/List.php @@ -158,7 +158,7 @@ protected function _beforeToHtml() $toolbar->setModes($modes); } - // set collection to tollbar and apply sort + // set collection to toolbar and apply sort $toolbar->setCollection($collection); $this->setChild('toolbar', $toolbar); diff --git a/app/code/core/Mage/Catalog/Block/Product/View/Options/Abstract.php b/app/code/core/Mage/Catalog/Block/Product/View/Options/Abstract.php index 26a678355f..ec589a3b21 100644 --- a/app/code/core/Mage/Catalog/Block/Product/View/Options/Abstract.php +++ b/app/code/core/Mage/Catalog/Block/Product/View/Options/Abstract.php @@ -162,4 +162,16 @@ public function getPrice($price, $includingTax = null) } return $price; } + + /** + * Returns price converted to current currency rate + * + * @param float $price + * @return float + */ + public function getCurrencyPrice($price) + { + $store = $this->getProduct()->getStore(); + return $this->helper('core')->currencyByStore($price, $store, false); + } } diff --git a/app/code/core/Mage/Catalog/Block/Product/View/Options/Type/Select.php b/app/code/core/Mage/Catalog/Block/Product/View/Options/Type/Select.php index 5a9b16039a..a10549c6c5 100644 --- a/app/code/core/Mage/Catalog/Block/Product/View/Options/Type/Select.php +++ b/app/code/core/Mage/Catalog/Block/Product/View/Options/Type/Select.php @@ -44,6 +44,7 @@ public function getValuesHtml() { $_option = $this->getOption(); $configValue = $this->getProduct()->getPreconfiguredValues()->getData('options/' . $_option->getId()); + $store = $this->getProduct()->getStore(); if ($_option->getType() == Mage_Catalog_Model_Product_Option::OPTION_TYPE_DROP_DOWN || $_option->getType() == Mage_Catalog_Model_Product_Option::OPTION_TYPE_MULTIPLE) { @@ -69,7 +70,7 @@ public function getValuesHtml() $select->addOption( $_value->getOptionTypeId(), $_value->getTitle() . ' ' . $priceStr . '', - array('price' => $_value->getPrice(true)) + array('price' => $this->helper('core')->currencyByStore($_value->getPrice(true), $store, false)) ); } if ($_option->getType() == Mage_Catalog_Model_Product_Option::OPTION_TYPE_MULTIPLE) { @@ -124,7 +125,7 @@ public function getValuesHtml() } $selectHtml .= '
  • ' . - 'getSkipJsReloadPrice() ? '' : ' onclick="opConfig.reloadPrice()"') . ' name="options['.$_option->getId().']'.$arraySign.'" id="options_'.$_option->getId().'_'.$count.'" value="' . $htmlValue . '" ' . $checked . ' price="' . $_value->getPrice(true) . '" />' . + 'getSkipJsReloadPrice() ? '' : ' onclick="opConfig.reloadPrice()"') . ' name="options['.$_option->getId().']'.$arraySign.'" id="options_'.$_option->getId().'_'.$count.'" value="' . $htmlValue . '" ' . $checked . ' price="' . $this->helper('core')->currencyByStore($_value->getPrice(true), $store, false) . '" />' . ''; if ($_option->getIsRequire()) { $selectHtml .= ' diff --git a/app/design/adminhtml/default/default/template/downloadable/product/composite/fieldset/downloadable.phtml b/app/design/adminhtml/default/default/template/downloadable/product/composite/fieldset/downloadable.phtml index 5599a47b4e..0193a2517d 100644 --- a/app/design/adminhtml/default/default/template/downloadable/product/composite/fieldset/downloadable.phtml +++ b/app/design/adminhtml/default/default/template/downloadable/product/composite/fieldset/downloadable.phtml @@ -40,7 +40,7 @@
  • - getLinkCheckedValue($_link); ?> price="getPrice(); ?>"/> + getLinkCheckedValue($_link); ?> price="getCurrencyPrice($_link->getPrice()); ?>"/>
  • diff --git a/app/design/frontend/base/default/template/giftmessage/inline.phtml b/app/design/frontend/base/default/template/giftmessage/inline.phtml index f28b5562c4..258bd8dc19 100644 --- a/app/design/frontend/base/default/template/giftmessage/inline.phtml +++ b/app/design/frontend/base/default/template/giftmessage/inline.phtml @@ -45,9 +45,18 @@ if(!window.toogleVisibilityOnObjects) { sitem.addClassName('validation-passed'); }); - $$('#' + item + ' .giftmessage-area').each(function(sitem) { + $$('#' + item + ' .giftmessage-area').each(function(sitem) { sitem.value = ''; }); + $$('#' + item + ' .checkbox').each(function(sitem) { + sitem.checked = false; + }); + $$('#' + item + ' .select').each(function(sitem) { + sitem.value = ''; + }); + $$('#' + item + ' .price-box').each(function(sitem) { + sitem.addClassName('no-display'); + }); }); } diff --git a/app/design/adminhtml/default/default/template/customer/edit/addlisttype.phtml b/app/design/frontend/base/default/template/pagecache/cookie.phtml similarity index 69% rename from app/design/adminhtml/default/default/template/customer/edit/addlisttype.phtml rename to app/design/frontend/base/default/template/pagecache/cookie.phtml index 994b07bf52..abb4278fb8 100644 --- a/app/design/adminhtml/default/default/template/customer/edit/addlisttype.phtml +++ b/app/design/frontend/base/default/template/pagecache/cookie.phtml @@ -19,19 +19,12 @@ * needs please refer to http://www.magentocommerce.com for more information. * * @category design - * @package default_default + * @package base_default * @copyright Copyright (c) 2010 Magento Inc. (http://www.magentocommerce.com) * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) */ - ?> +?> + + Mage.Cookies.set('', 1); + \ No newline at end of file diff --git a/app/design/frontend/base/default/template/wishlist/render/item/price.phtml b/app/design/frontend/base/default/template/wishlist/render/item/price.phtml new file mode 100644 index 0000000000..1a26072312 --- /dev/null +++ b/app/design/frontend/base/default/template/wishlist/render/item/price.phtml @@ -0,0 +1,39 @@ + + +getCleanProductPriceHtml(); ?> + + +getProduct(); ?> +getFinalPrice(1); ?> +canConfigure()): ?> +

    + __('Configured Price:') ?> + currency($finalPrice, true, false); ?> +

    + diff --git a/app/etc/modules/Mage_PageCache.xml b/app/etc/modules/Mage_PageCache.xml new file mode 100644 index 0000000000..3abd89dcdb --- /dev/null +++ b/app/etc/modules/Mage_PageCache.xml @@ -0,0 +1,38 @@ + + + + + + true + core + + + + + + diff --git a/app/locale/en_US/Mage_Adminhtml.csv b/app/locale/en_US/Mage_Adminhtml.csv index b4e4163955..e315ab683c 100644 --- a/app/locale/en_US/Mage_Adminhtml.csv +++ b/app/locale/en_US/Mage_Adminhtml.csv @@ -96,6 +96,7 @@ "All rates were fetched, please click on ""Save"" to apply","All rates were fetched, please click on ""Save"" to apply" "All valid rates have been saved.","All valid rates have been saved." "Amounts","Amounts" +"An error has occured while syncronizing media storages.","An error has occured while syncronizing media storages." "An error occurred while clearing the JavaScript/CSS cache.","An error occurred while clearing the JavaScript/CSS cache." "An error occurred while clearing the image cache.","An error occurred while clearing the image cache." "An error occurred while creating the backup.","An error occurred while creating the backup." @@ -380,11 +381,12 @@ "General Section","General Section" "Get Image Base64","Get Image Base64" "Get help for this page","Get help for this page" -"Gift Message","Gift Message" "Global Attribute","Global Attribute" "Global Record Search","Global Record Search" "Global Search","Global Search" "Go Today","Go Today" +"Go to messages inbox","Go to messages inbox" +"Go to notifications","Go to notifications" "Google Base","Google Base" "Google Base Items","Google Base Items" "Google Sitemaps","Google Sitemaps" @@ -522,6 +524,7 @@ "Max","Max" "Mb","Mb" "Media (.avi, .flv, .swf)","Media (.avi, .flv, .swf)" +"Media storage synchronization has completed!","Media storage synchronization has completed!" "Messages Inbox","Messages Inbox" "Min","Min" "Month","Month" @@ -606,6 +609,7 @@ "Old rate:","Old rate:" "On my website","On my website" "Once you log into your Payflow Link account, navigate to the Service Settings - Hosted Checkout Pages - Set Up menu and set the options described below","Once you log into your Payflow Link account, navigate to the Service Settings - Hosted Checkout Pages - Set Up menu and set the options described below" +"One or more media files failed to be synchronized during the media storages syncronization process. Refer to the log file for details.","One or more media files failed to be synchronized during the media storages syncronization process. Refer to the log file for details." "One or more of the Cache Types are invalidated:","One or more of the Cache Types are invalidated:" "Online Customers","Online Customers" "Only attributes with scope ""Global"", input type ""Dropdown"" and Use To Create Configurable Product ""Yes"" are available.","Only attributes with scope ""Global"", input type ""Dropdown"" and Use To Create Configurable Product ""Yes"" are available." @@ -892,8 +896,11 @@ "Switch/Solo/Maestro(UK Domestic) Only","Switch/Solo/Maestro(UK Domestic) Only" "Switch/Solo/Maestro(UK Domestic) card issue number: %s","Switch/Solo/Maestro(UK Domestic) card issue number: %s" "Switch/Solo/Maestro(UK Domestic) card start Date: %s/%s","Switch/Solo/Maestro(UK Domestic) card start Date: %s/%s" +"Synchronization is required.","Synchronization is required." +"Synchronization of media storages has been successfully completed.","Synchronization of media storages has been successfully completed." "Synchronize","Synchronize" "Synchronizing %s to %s","Synchronizing %s to %s" +"Synchronizing...","Synchronizing..." "System","System" "System Section","System Section" "System busy","System busy" @@ -1002,6 +1009,7 @@ "Time","Time" "Time selection:","Time selection:" "Time:","Time:" +"Timeout limit for response from synchronize process was reached.","Timeout limit for response from synchronize process was reached." "To","To" "To cancel pending authorizations and release amounts that have already been processed during this payment, click Cancel.","To cancel pending authorizations and release amounts that have already been processed during this payment, click Cancel." "To use Payflow Link, you must configure your Payflow Link account on the Paypal website.","To use Payflow Link, you must configure your Payflow Link account on the Paypal website." @@ -1127,7 +1135,7 @@ "Yes (302 Found)","Yes (302 Found)" "Yes (only price with tax)","Yes (only price with tax)" "You cannot delete your own account.","You cannot delete your own account." -"You have","You have" +"You have %s unread message(s).","You have %s unread message(s)." "You have logged out.","You have logged out." "You have not enough permissions to use this functionality.","You have not enough permissions to use this functionality." "You must have JavaScript enabled in your browser to utilize the functionality of this website.","You must have JavaScript enabled in your browser to utilize the functionality of this website." diff --git a/app/locale/en_US/Mage_AmazonCheckout.csv b/app/locale/en_US/Mage_AmazonCheckout.csv deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/app/locale/en_US/Mage_Api.csv b/app/locale/en_US/Mage_Api.csv index d3131ac424..0d61d20c68 100644 --- a/app/locale/en_US/Mage_Api.csv +++ b/app/locale/en_US/Mage_Api.csv @@ -128,9 +128,10 @@ "General Information","General Information" "General Settings","General Settings" "Get help for this page","Get help for this page" -"Gift Message","Gift Message" "Global Record Search","Global Record Search" "Go Today","Go Today" +"Go to messages inbox","Go to messages inbox" +"Go to notifications","Go to notifications" "Google Base Items","Google Base Items" "Group:","Group:" "Help Us Keep Magento Healthy - Report All Bugs","Help Us Keep Magento Healthy - Report All Bugs" @@ -308,6 +309,7 @@ "Switch/Solo/Maestro(UK Domestic) Only","Switch/Solo/Maestro(UK Domestic) Only" "Switch/Solo/Maestro(UK Domestic) card issue number: %s","Switch/Solo/Maestro(UK Domestic) card issue number: %s" "Switch/Solo/Maestro(UK Domestic) card start Date: %s/%s","Switch/Solo/Maestro(UK Domestic) card start Date: %s/%s" +"Synchronization is required.","Synchronization is required." "System busy","System busy" "Target","Target" "The card has failed verification with the issuer bank.","The card has failed verification with the issuer bank." @@ -359,7 +361,7 @@ "Web Services","Web Services" "What is this?","What is this?" "Yes","Yes" -"You have","You have" +"You have %s unread message(s).","You have %s unread message(s)." "You must have JavaScript enabled in your browser to utilize the functionality of this website.","You must have JavaScript enabled in your browser to utilize the functionality of this website." "Your account has been deactivated.","Your account has been deactivated." "Your server PHP settings allow you to upload files not more than %s at a time. Please modify post_max_size (currently is %s) and upload_max_filesize (currently is %s) values in php.ini if you want to upload larger files.","Your server PHP settings allow you to upload files not more than %s at a time. Please modify post_max_size (currently is %s) and upload_max_filesize (currently is %s) values in php.ini if you want to upload larger files." diff --git a/app/locale/en_US/Mage_Catalog.csv b/app/locale/en_US/Mage_Catalog.csv index 2111fa7578..7a6e4e5f74 100644 --- a/app/locale/en_US/Mage_Catalog.csv +++ b/app/locale/en_US/Mage_Catalog.csv @@ -414,6 +414,7 @@ "Please specify the product\'s required option(s).","Please specify the product\'s required option(s)." "Please specify the quantity of product(s).","Please specify the quantity of product(s)." "Please specify time required option(s).","Please specify time required option(s)." +"Please wait...","Please wait..." "Position","Position" "Position in Layered Navigation","Position in Layered Navigation" "Position of attribute in layered navigation block","Position of attribute in layered navigation block" @@ -523,6 +524,7 @@ "Roll Over for preview","Roll Over for preview" "Root","Root" "SKU","SKU" +"SKU length should be %s characters maximum.","SKU length should be %s characters maximum." "Save","Save" "Save Attribute","Save Attribute" "Save Attribute Set","Save Attribute Set" diff --git a/app/locale/en_US/Mage_Checkout.csv b/app/locale/en_US/Mage_Checkout.csv index 6f2bf88eb5..9bc85e1b4e 100644 --- a/app/locale/en_US/Mage_Checkout.csv +++ b/app/locale/en_US/Mage_Checkout.csv @@ -88,6 +88,7 @@ "Display Shopping Cart Sidebar","Display Shopping Cart Sidebar" "Display item quantities","Display item quantities" "Display number of items in cart","Display number of items in cart" +"Display number of items in wishlist","Display number of items in wishlist" "Easy access to your order history and status","Easy access to your order history and status" "Edit","Edit" "Edit Address","Edit Address" @@ -185,6 +186,7 @@ "Qty:","Qty:" "Quantity was recalculated from %d to %d","Quantity was recalculated from %d to %d" "Quote Lifetime (days)","Quote Lifetime (days)" +"Quote item does not exist.","Quote item does not exist." "Quote item is not found.","Quote item is not found." "Recently added item(s)","Recently added item(s)" "Register","Register" diff --git a/app/locale/en_US/Mage_Connect.csv b/app/locale/en_US/Mage_Connect.csv index e4c5dda549..87ffe528e5 100644 --- a/app/locale/en_US/Mage_Connect.csv +++ b/app/locale/en_US/Mage_Connect.csv @@ -37,6 +37,7 @@ "Package","Package" "Package Extensions","Package Extensions" "Package File Name","Package File Name" +"Package Format","Package Format" "Package Info","Package Info" "Packages","Packages" "Path","Path" @@ -53,3 +54,5 @@ "There was a problem saving package data","There was a problem saving package data" "Type","Type" "User","User" +"Version 1.x","Version 1.x" +"Version 2.x","Version 2.x" diff --git a/app/locale/en_US/Mage_Core.csv b/app/locale/en_US/Mage_Core.csv index 08620fa457..5d765b938f 100644 --- a/app/locale/en_US/Mage_Core.csv +++ b/app/locale/en_US/Mage_Core.csv @@ -309,6 +309,7 @@ "Unable to delete website. Please, try again later.","Unable to delete website. Please, try again later." "Unable to proceed. Please, try again","Unable to proceed. Please, try again" "Unable to proceed. Please, try again.","Unable to proceed. Please, try again." +"Unable to save file ""%s"" at ""%s""","Unable to save file ""%s"" at ""%s""" "Unable to save file: %s","Unable to save file: %s" "Unknown scope ""%s"".","Unknown scope ""%s""." "Unsecure","Unsecure" diff --git a/app/locale/en_US/Mage_Customer.csv b/app/locale/en_US/Mage_Customer.csv index 55ee8bb88e..9cb2e3fd5a 100644 --- a/app/locale/en_US/Mage_Customer.csv +++ b/app/locale/en_US/Mage_Customer.csv @@ -16,7 +16,8 @@ """%s"" is not a valid file.","""%s"" is not a valid file." """%s"" is not a valid hostname.","""%s"" is not a valid hostname." """%s"" is not a valid image format","""%s"" is not a valid image format" -"""%s"" length must be equal or greater than %s characters.","""%s"" length must be equal or greater than %s characters." +"""%s"" length must be equal to or greater than %s characters.","""%s"" length must be equal to or greater than %s characters." +"""%s"" length must be less than or equal to %s characters.","""%s"" length must be less than or equal to %s characters." """%s"" width exceeds allowed value of %s px.","""%s"" width exceeds allowed value of %s px." "* Required Fields","* Required Fields" "A new password has been sent.","A new password has been sent." @@ -156,6 +157,7 @@ "Entity collection is expected.","Entity collection is expected." "Entity instance is not defined","Entity instance is not defined" "Entity object is undefined","Entity object is undefined" +"Excel XML","Excel XML" "Failed to confirm customer account.","Failed to confirm customer account." "Fax","Fax" "First Name","First Name" @@ -399,7 +401,6 @@ "Wrong customer account specified.","Wrong customer account specified." "Wrong email.","Wrong email." "Wrong transactional account email type.","Wrong transactional account email type." -"XML","XML" "YYYY","YYYY" "Year","Year" "Yes","Yes" diff --git a/app/locale/en_US/Mage_GiftMessage.csv b/app/locale/en_US/Mage_GiftMessage.csv index d1e37e3c2a..08c68d5c13 100644 --- a/app/locale/en_US/Mage_GiftMessage.csv +++ b/app/locale/en_US/Mage_GiftMessage.csv @@ -7,16 +7,20 @@ "Allow Gift Messages on Order Level","Allow Gift Messages on Order Level" "An error occurred while saving the gift message.","An error occurred while saving the gift message." "Are you sure?","Are you sure?" +"Cancel","Cancel" "Do you have any gift items in your order?","Do you have any gift items in your order?" "Edit","Edit" "From","From" +"Gift Message","Gift Message" "Gift Options","Gift Options" +"Gift Options for","Gift Options for" "Gift Options for Individual Items","Gift Options for Individual Items" "Gift Options for the Entire Order.","Gift Options for the Entire Order." "Gift Options for this address.","Gift Options for this address." "Item %d of %d","Item %d of %d" "Message","Message" "No","No" +"OK","OK" "Save Gift Message","Save Gift Message" "The gift message has been removed","The gift message has been removed" "The gift message has been saved","The gift message has been saved" diff --git a/app/locale/en_US/Mage_PageCache.csv b/app/locale/en_US/Mage_PageCache.csv new file mode 100644 index 0000000000..79f380c0c6 --- /dev/null +++ b/app/locale/en_US/Mage_PageCache.csv @@ -0,0 +1,11 @@ +"An error occurred while clearing the external full page cache.","An error occurred while clearing the external full page cache." +"Cookie Lifetime (seconds)","Cookie Lifetime (seconds)" +"Enable External Cache","Enable External Cache" +"External Cache Control","External Cache Control" +"External Full Page Cache Settings","External Full Page Cache Settings" +"External full page cache.","External full page cache." +"Failed to load external cache control","Failed to load external cache control" +"Flush External Page Cache","Flush External Page Cache" +"If empty, default value will be used.","If empty, default value will be used." +"The external full page cache has been cleaned.","The external full page cache has been cleaned." +"Zend Full Page Cache","Zend Full Page Cache" diff --git a/app/locale/en_US/Mage_Paypal.csv b/app/locale/en_US/Mage_Paypal.csv index a7990750f5..75b7e2e92f 100644 --- a/app/locale/en_US/Mage_Paypal.csv +++ b/app/locale/en_US/Mage_Paypal.csv @@ -153,6 +153,7 @@ "Help","Help" "Hidden Virtual PayPal Debit Card Transaction","Hidden Virtual PayPal Debit Card Transaction" "Hold for Dispute Investigation","Hold for Dispute Investigation" +"Hosted Solution, which is available to merchants in the United Kingdom as part of Website Payments Pro, is a fast and easy way to add transaction processing to your website.","Hosted Solution, which is available to merchants in the United Kingdom as part of Website Payments Pro, is a fast and easy way to add transaction processing to your website." "IPN ""%s"".","IPN ""%s""." "If empty, a default value will be used. Custom URL may be provided by CardinalCommerce agreement.","If empty, a default value will be used. Custom URL may be provided by CardinalCommerce agreement." "If not specified, Default Country from General Config will be used","If not specified, Default Country from General Config will be used" @@ -258,7 +259,7 @@ "Payer ID","Payer ID" "Payer Status","Payer Status" "Payer is not identified.","Payer is not identified." -"Payflow Link","Payflow Link" +"Payflow Link (for USA and Canada)","Payflow Link (for USA and Canada)" "Payflow Link Settings","Payflow Link Settings" "Payflow Pro Gateway","Payflow Pro Gateway" "Payflow Pro Settings","Payflow Pro Settings" @@ -272,7 +273,7 @@ "Paypal Billing Agreement Settings","Paypal Billing Agreement Settings" "Pending PayPal","Pending PayPal" "Place Order","Place Order" -"Please do not refresh the page while the form loads.","Please do not refresh the page while the form loads." +"Please do not refresh the page until you complete payment.","Please do not refresh the page until you complete payment." "Please select a shipping method...","Please select a shipping method..." "Points Incentive Redemption","Points Incentive Redemption" "Postage Payment to either USPS or UPS","Postage Payment to either USPS or UPS" @@ -386,6 +387,8 @@ "We prefer PayPal (150 X 60)","We prefer PayPal (150 X 60)" "Website Payments Pro","Website Payments Pro" "Website Payments Pro (Payflow Edition) Settings","Website Payments Pro (Payflow Edition) Settings" +"Website Payments Pro Hosted Solution Settings","Website Payments Pro Hosted Solution Settings" +"Website Payments Pro Hosted Solution for EU & APAC","Website Payments Pro Hosted Solution for EU & APAC" "Website Payments Pro Payflow Edition (includes Express Checkout)","Website Payments Pro Payflow Edition (includes Express Checkout)" "Website Payments Pro Settings","Website Payments Pro Settings" "Website Payments Standard","Website Payments Standard" diff --git a/app/locale/en_US/Mage_Sales.csv b/app/locale/en_US/Mage_Sales.csv index e45b02b3d4..4a0b94d8c8 100644 --- a/app/locale/en_US/Mage_Sales.csv +++ b/app/locale/en_US/Mage_Sales.csv @@ -227,13 +227,11 @@ "Get Payment Update","Get Payment Update" "Get Update","Get Update" "Get shipping methods and rates","Get shipping methods and rates" -"Gift","Gift" "Gift Message","Gift Message" "Gift Message for This Order","Gift Message for This Order" "Gift Message for the Entire Order","Gift Message for the Entire Order" "Gift Message for this Order","Gift Message for this Order" "Gift Options","Gift Options" -"Gift Options for","Gift Options for" "Grand Total","Grand Total" "Grand Total to be Charged","Grand Total to be Charged" "Guest","Guest" @@ -422,6 +420,8 @@ "Order status with the same status code already exist.","Order status with the same status code already exist." "Order was placed using %s","Order was placed using %s" "Ordered","Ordered" +"Ordered amount of %s.","Ordered amount of %s." +"Ordering amount of %s is pending approval on gateway.","Ordering amount of %s is pending approval on gateway." "Orders","Orders" "Original Price","Original Price" "Original order item that recurring payment profile correspondss to.","Original order item that recurring payment profile correspondss to." @@ -693,6 +693,7 @@ "This operation requires an existing transaction object.","This operation requires an existing transaction object." "This order contains (%s) items and therefore cannot be edited through the admin interface at this time, if you wish to continue editing the (%s) items will be removed, the order will be canceled and a new order will be placed.","This order contains (%s) items and therefore cannot be edited through the admin interface at this time, if you wish to continue editing the (%s) items will be removed, the order will be canceled and a new order will be placed." "This order no longer exists.","This order no longer exists." +"This product does not have any configurable options.","This product does not have any configurable options." "This product has not been configured.","This product has not been configured." "This profile state cannot be changed to ""%s"".","This profile state cannot be changed to ""%s""." "This will create an offline refund. To create an online refund, open an invoice and create credit memo for it. Do you wish to proceed?","This will create an offline refund. To create an online refund, open an invoice and create credit memo for it. Do you wish to proceed?" diff --git a/app/locale/en_US/Mage_Tax.csv b/app/locale/en_US/Mage_Tax.csv index ad4951b8f3..75bd7aa64b 100644 --- a/app/locale/en_US/Mage_Tax.csv +++ b/app/locale/en_US/Mage_Tax.csv @@ -48,6 +48,7 @@ "Edit Class '%s'","Edit Class '%s'" "Edit Rule","Edit Rule" "Edit Tax Rate","Edit Tax Rate" +"Excel XML","Excel XML" "Excl. Tax","Excl. Tax" "Excl. Tax:","Excl. Tax:" "Excluding Tax","Excluding Tax" @@ -141,7 +142,6 @@ "Unit Price","Unit Price" "Whether catalog prices entered by admin include tax.","Whether catalog prices entered by admin include tax." "Whether shipping amounts entered by admin or obtained from gateways include tax.","Whether shipping amounts entered by admin or obtained from gateways include tax." -"XML","XML" "Yes","Yes" "You cannot delete this tax class as it is used for %d customer groups.","You cannot delete this tax class as it is used for %d customer groups." "You cannot delete this tax class as it is used for %d products.","You cannot delete this tax class as it is used for %d products." diff --git a/app/locale/en_US/Mage_Usa.csv b/app/locale/en_US/Mage_Usa.csv index 60e7dc3291..3eed43143a 100644 --- a/app/locale/en_US/Mage_Usa.csv +++ b/app/locale/en_US/Mage_Usa.csv @@ -88,8 +88,6 @@ "Invalid FedEx XML code type: %s","Invalid FedEx XML code type: %s" "Invalid UPS CGI code for type %s: %s","Invalid UPS CGI code for type %s: %s" "Invalid UPS CGI code type: %s","Invalid UPS CGI code type: %s" -"Invalid USPS XML code for type %s: %s","Invalid USPS XML code for type %s: %s" -"Invalid USPS XML code type: %s","Invalid USPS XML code type: %s" "Kilograms","Kilograms" "Large","Large" "Letter","Letter" diff --git a/app/locale/en_US/Mage_Wishlist.csv b/app/locale/en_US/Mage_Wishlist.csv index 05eeaa94ed..04ce5faeda 100644 --- a/app/locale/en_US/Mage_Wishlist.csv +++ b/app/locale/en_US/Mage_Wishlist.csv @@ -34,11 +34,13 @@ "Comment","Comment" "Comment:","Comment:" "Configure Wishlist Item","Configure Wishlist Item" +"Configured Price:","Configured Price:" "Customer My Account My Wishlist","Customer My Account My Wishlist" "Customer My Account Wishlist Sharing Form","Customer My Account Wishlist Sharing Form" "Customer Shared Wishlist View","Customer Shared Wishlist View" "Date Added","Date Added" "Days in Wishlist","Days in Wishlist" +"Display Wishlist Summary","Display Wishlist Summary" "Edit","Edit" "Email Sender","Email Sender" "Email Template","Email Template" @@ -54,6 +56,7 @@ "My Wishlist (%d item)","My Wishlist (%d item)" "My Wishlist (%d items)","My Wishlist (%d items)" "My Wishlist (%d)","My Wishlist (%d)" +"My Wishlist Link","My Wishlist Link" "Options Details","Options Details" "Out of stock","Out of stock" "Please enter a valid email addresses, separated by commas. For example johndoe@domain.com, johnsmith@domain.com.","Please enter a valid email addresses, separated by commas. For example johndoe@domain.com, johnsmith@domain.com." @@ -61,7 +64,6 @@ "Please, enter your comments...","Please, enter your comments..." "Product","Product" "Product(s) %s have required options. Each of them can be added to cart separately only.","Product(s) %s have required options. Each of them can be added to cart separately only." -"Quantity","Quantity" "RSS Feed","RSS Feed" "RSS link to %s's wishlist","RSS link to %s's wishlist" "Remove Item","Remove Item" diff --git a/app/locale/en_US/Phoenix_Moneybookers.csv b/app/locale/en_US/Phoenix_Moneybookers.csv index 9a9d12a649..8cec07e16f 100644 --- a/app/locale/en_US/Phoenix_Moneybookers.csv +++ b/app/locale/en_US/Phoenix_Moneybookers.csv @@ -5,18 +5,20 @@ "Dankort (powered by Moneybookers) - Denmark","Dankort (powered by Moneybookers) - Denmark" "EPS Online-Überweisung (powered by Moneybookers) - Austria","EPS Online-Überweisung (powered by Moneybookers) - Austria" "Enabled","Enabled" +"Find out more about Online Bank Transfer","Find out more about Online Bank Transfer" "Giropay (powered by Moneybookers) - Germany","Giropay (powered by Moneybookers) - Germany" "Laser (powered by Moneybookers) - Ireland","Laser (powered by Moneybookers) - Ireland" "Lastschrift (ELV) (powered by Moneybookers) - Germany","Lastschrift (ELV) (powered by Moneybookers) - Germany" "Loading secure payment page (SSL)","Loading secure payment page (SSL)" +"Maestro (powered by Moneybookers) - United Kingdom, Austria, Spain","Maestro (powered by Moneybookers) - United Kingdom, Austria, Spain" "Moneybookers","Moneybookers" -"Moneybookers Info URL","Moneybookers Info URL" "Moneybookers Settings","Moneybookers Settings" "Moneybookers Transaction ID: %s","Moneybookers Transaction ID: %s" "Moneybookers eWallet","Moneybookers eWallet" "More information about Moneybookers","More information about Moneybookers" "Nordea Solo (powered by Moneybookers) - Finland","Nordea Solo (powered by Moneybookers) - Finland" "Nordea Solo (powered by Moneybookers) - Sweden","Nordea Solo (powered by Moneybookers) - Sweden" +"Online Bank Transfer (powered by Moneybookers)","Online Bank Transfer (powered by Moneybookers)" "Order ID","Order ID" "POLi (powered by Moneybookers) - Australia","POLi (powered by Moneybookers) - Australia" "Payment failed.","Payment failed." @@ -27,6 +29,7 @@ "Pending bank transfer created.","Pending bank transfer created." "Please pay your order now","Please pay your order now" "Postepay (powered by Moneybookers) - Italy","Postepay (powered by Moneybookers) - Italy" +"Powered by Moneybookers","Powered by Moneybookers" "Przelewy24 (powered by Moneybookers) - Poland","Przelewy24 (powered by Moneybookers) - Poland" "Sofortüberweisung (powered by Moneybookers) - Germany","Sofortüberweisung (powered by Moneybookers) - Germany" "Sort Order","Sort Order" diff --git a/downloader/lib/Mage/Connect/Command/Registry.php b/downloader/lib/Mage/Connect/Command/Registry.php index 2875358296..0c9a024477 100644 --- a/downloader/lib/Mage/Connect/Command/Registry.php +++ b/downloader/lib/Mage/Connect/Command/Registry.php @@ -27,6 +27,7 @@ final class Mage_Connect_Command_Registry extends Mage_Connect_Command { + const PACKAGE_PEAR_DIR = 'pearlib/php/.registry'; /** * List-installed callback @@ -186,6 +187,9 @@ public function doSync($command, $options, $params) $this->cleanupParams($params); try { $packager = $this->getPackager(); + $cache = null; + $config = null; + $ftpObj = null; $ftp = empty($options['ftp']) ? false : $options['ftp']; if($ftp) { list($cache, $config, $ftpObj) = $packager->getRemoteConf($ftp); @@ -193,6 +197,9 @@ public function doSync($command, $options, $params) $config = $this->config(); $cache = $this->getSconfig(); } + if ($this->_checkPearData($config)) { + $this->doSyncPear($command, $options, $params); + } $packageDir = $config->magento_root . DS . Mage_Connect_Package::PACKAGE_XML_DIR; if (is_dir($packageDir)) { @@ -231,4 +238,129 @@ public function doSync($command, $options, $params) $this->doError($command, $e->getMessage()); } } + + /** + * Synchronize packages installed earlier (by pear installer) with local cache + * + * @param string $command + * @param array $options + * @param array $params + */ + public function doSyncPear($command, $options, $params) + { + $this->cleanupParams($params); + try { + $packager = $this->getPackager(); + $cache = null; + $config = null; + $ftpObj = null; + $ftp = empty($options['ftp']) ? false : $options['ftp']; + if($ftp) { + list($cache, $config, $ftpObj) = $packager->getRemoteConf($ftp); + } else { + $config = $this->config(); + $cache = $this->getSconfig(); + } + + $pkglist = array(); + if (!$this->_checkPearData($config)) { + return $pkglist; + } + + $pearStorage = $config->magento_root . DS . $config->downloader_path . DS . self::PACKAGE_PEAR_DIR; + $channels = array( + '.channel.connect.magentocommerce.com_community', + '.channel.connect.magentocommerce.com_core' + ); + foreach ($channels as $channel) { + $channelDirectory = $pearStorage . DS . $channel; + if (!file_exists($channelDirectory) || !is_dir($channelDirectory)) { + continue; + } + + $dp = opendir($channelDirectory); + if (!$dp) { + continue; + } + + while ($ent = readdir($dp)) { + if ($ent{0} == '.' || substr($ent, -4) != '.reg') { + continue; + } + $pkglist[] = array('file'=>$ent, 'channel'=>$channel); + } + closedir($dp); + } + + $package = new Mage_Connect_Package(); + foreach ($pkglist as $pkg) { + $pkgFilename = $pearStorage . DS . $pkg['channel'] . DS . $pkg['file']; + if (!file_exists($pkgFilename)) { + continue; + } + $data = file_get_contents($pkgFilename); + $data = unserialize($data); + + $package->importDataV1x($data); + $name = $package->getName(); + $channel = $package->getChannel(); + $version = $package->getVersion(); + if (!$cache->isChannel($channel) && $channel == $config->root_channel) { + $cache->addChannel($channel, $config->root_channel_uri); + } + if (!$cache->hasPackage($channel, $name, $version, $version)) { + $cache->addPackage($package); + + if($ftp) { + $localXml = tempnam(sys_get_temp_dir(),'package'); + @file_put_contents($localXml, $package->getPackageXml()); + + if (is_file($localXml)) { + $ftpDir = $ftp->getcwd(); + $remoteXmlPath = $ftpDir . '/' . Mage_Connect_Package::PACKAGE_XML_DIR; + $remoteXml = $package->getReleaseFilename() . '.xml'; + $ftp->mkdirRecursive($remoteXmlPath); + $ftp->upload($remoteXml, $localXml, 0777, 0666); + $ftp->chdir($ftpDir); + } + } else { + $destDir = rtrim($config->magento_root, "\\/") . DS . Mage_Connect_Package::PACKAGE_XML_DIR; + $destFile = $package->getReleaseFilename() . '.xml'; + $dest = $destDir . DS . $destFile; + + @mkdir($destDir, 0777, true); + @file_put_contents($dest, $package->getPackageXml()); + @chmod($dest, 0666); + } + + $this->ui()->output("Successfully added: {$channel}/{$name}-{$version}"); + } + + } + + $config->sync_pear = false; + if($ftp) { + $packager->writeToRemoteCache($cache, $ftpObj); + @unlink($config->getFilename()); + } + + + return true; + + } catch (Exception $e) { + $this->doError($command, $e->getMessage()); + } + } + + /** + * Check is need to sync old pear data + * + * @param Mage_Connect_Config $config + * @return boolean + */ + protected function _checkPearData($config) { + $pearStorage = $config->magento_root . DS . $config->downloader_path . DS . self::PACKAGE_PEAR_DIR; + return $config->sync_pear && file_exists($pearStorage) && is_dir($pearStorage); + } + } diff --git a/downloader/lib/Mage/Connect/Command/Registry_Header.php b/downloader/lib/Mage/Connect/Command/Registry_Header.php index f2a7013618..9fc6260672 100644 --- a/downloader/lib/Mage/Connect/Command/Registry_Header.php +++ b/downloader/lib/Mage/Connect/Command/Registry_Header.php @@ -72,5 +72,13 @@ 'options' => array(), 'doc' => ' Synchronize manually installed package info with local cache.' + ), + 'sync-pear' => array( + 'summary' => 'Synchronize already Installed Packages by pear', + 'function' => 'doSyncPear', + 'shortcut' => 'sncp', + 'options' => array(), + 'doc' => ' +Synchronize already Installed Packages by pear.' ) ); diff --git a/downloader/lib/Mage/Connect/Config.php b/downloader/lib/Mage/Connect/Config.php index c1182f9ef1..8adba4c29e 100644 --- a/downloader/lib/Mage/Connect/Config.php +++ b/downloader/lib/Mage/Connect/Config.php @@ -44,77 +44,85 @@ protected function initProperties() 'prompt' => 'location of php.ini', 'doc' => "It's a location of PHP.ini to use blah", 'possible' => '/path/php.ini', - ), + ), 'protocol' => array( 'type' => 'set', 'value' => 'http', 'prompt' => 'preffered protocol', 'doc' => 'preffered protocol', 'rules' => array('http', 'ftp') - ), + ), 'preferred_state' => array( 'type' => 'set', 'value' => 'stable', 'prompt' => 'preferred package state', 'doc' => 'preferred package state', 'rules' => array('beta','alpha','stable','devel') - ), + ), 'use_custom_permissions_mode' => array ( 'type' => 'bool', 'value' => false, 'prompt' => 'Use custom permissions for directory and file creation', 'doc' => 'Use custom permissions for directory and file creation', 'possible' => 'true, false', - ), + ), 'global_dir_mode' => array ( 'type' => 'octal', 'value' => 0777, 'prompt' => 'directory creation mode', 'doc' => 'directory creation mode', 'possible' => '0777, 0666 etc.', - ), + ), 'global_file_mode' => array ( 'type' => 'octal', 'value' => 0666, 'prompt' => 'file creation mode', 'doc' => 'file creation mode', 'possible' => '0777, 0666 etc.', - ), + ), 'downloader_path' => array( 'type' => 'dir', 'value' => 'downloader', 'prompt' => 'relative path, location of magento downloader', 'doc' => "relative path, location of magento downloader", 'possible' => 'path', - ), + ), 'magento_root' => array( 'type' => 'dir', 'value' => '', 'prompt' => 'location of magento root dir', 'doc' => "Location of magento", 'possible' => '/path', - ), + ), 'root_channel_uri' => array( 'type' => 'string', 'value' => 'connect20.magentocommerce.com/', 'prompt' => '', 'doc' => "", 'possible' => '', - ), + ), 'root_channel' => array( 'type' => 'string', 'value' => 'community', 'prompt' => '', 'doc' => "", 'possible' => '', - ), + ), 'remote_config' => array( 'type' => 'string', 'value' => '', 'prompt' => '', 'doc' => "", 'possible' => 'ftp://name:password@host.com:port/path/to/folder/', - )); + ), + 'sync_pear' => array( + 'type' => 'boolean', + 'value' => true, + 'prompt' => '', + 'doc' => "", + 'possible' => '', + ) + ); $this->properties = $this->defaultProperties; } diff --git a/downloader/lib/Mage/Connect/Package.php b/downloader/lib/Mage/Connect/Package.php index 75d0180c25..9fc008a79d 100644 --- a/downloader/lib/Mage/Connect/Package.php +++ b/downloader/lib/Mage/Connect/Package.php @@ -1323,4 +1323,171 @@ public function setConfig($config) { $this->_config = $config; } + + /** + * Import package information from previous version of Magento Connect Manager + * + * @param array $data + * + * @return Mage_Connect_Package + */ + public function importDataV1x(array $data) + { + $this->_packageXml = null; + $this->_init(); + // Import simple data + if (isset($data['name'])) { + $this->setName($data['name']); + } + if (isset($data['summary'])) { + $this->setSummary($data['summary']); + } + if (isset($data['description'])) { + $this->setDescription($data['description']); + } + if (isset($data['channel'])) { + $this->setChannel($this->convertChannelFromV1x($data['channel'])); + } + if (isset($data['license'])) { + if (is_array($data['license'])) { + $this->setLicense($data['license']['_content'], $data['license']['attribs']['uri']); + } else { + $this->setLicense($data['license']); + } + } + if (isset($data['version'])) { + $this->setVersion($data['version']['release']); + } + if (isset($data['stability'])) { + $this->setStability($data['stability']['release']); + } + if (isset($data['notes'])) { + $this->setNotes($data['notes']); + } + if (isset($data['date'])) { + $this->setDate($data['date']); + } + if (isset($data['time'])) { + $this->setTime($data['time']); + } + + // Import authors + $authors = array(); + $authorRoles = array('lead', 'developer', 'contributor', 'helper'); + foreach ($authorRoles as $authorRole) { + if (isset($data[$authorRole])) { + $authorList = $data[$authorRole]; + if (!is_array($authorList) || isset($authorList['name'])) { + $authorList = array($authorList); + } + foreach ($authorList as $authorRawData) { + $author = array(); + $author['name'] = $authorRawData['name']; + $author['user'] = $authorRawData['user']; + $author['email'] = $authorRawData['email']; + array_push($authors, $author); + } + } + } + $this->setAuthors($authors); + + // Import dependencies + $packages = array(); + $extensions = array(); + if (isset($data['dependencies']) && is_array($data['dependencies'])) { + $dependencySections = array('required', 'optional'); + $elementTypes = array('package', 'extension'); + foreach ($dependencySections as $dependencySection) { + if (isset($data['dependencies'][$dependencySection])) { + // Handle required PHP version + if ($dependencySection == 'required' && isset($data['dependencies']['required']['php'])) { + $this->setDependencyPhpVersion($data['dependencies']['required']['php']['min'], $data['dependencies']['required']['php']['max']); + } + // Handle extensions + if (isset($data['dependencies'][$dependencySection]['extension'])) { + $extensionList = $data['dependencies'][$dependencySection]['extension']; + if (!is_array($extensionList) || isset($extensionList['name'])) { + $extensionList = array($extensionList); + } + foreach ($extensionList as $extensionRawData) { + $extension = array(); + $extension['name'] = $extensionRawData['name']; + $extension['min_version'] = isset($extensionRawData['min']) ? $extensionRawData['min'] : null; + $extension['max_version'] = isset($extensionRawData['max']) ? $extensionRawData['max'] : null; + array_push($extensions, $extension); + } + } + // Handle packages + if (isset($data['dependencies'][$dependencySection]['package'])) { + $packageList = $data['dependencies'][$dependencySection]['package']; + if (!is_array($packageList) || isset($packageList['name'])) { + $packageList = array($packageList); + } + foreach ($packageList as $packageRawData) { + $package = array(); + $package['name'] = $packageRawData['name']; + $package['channel'] = $this->convertChannelFromV1x($packageRawData['channel']); + $package['min_version'] = isset($packageRawData['min']) ? $packageRawData['min'] : null; + $package['max_version'] = isset($packageRawData['max']) ? $packageRawData['max'] : null; + array_push($packages, $package); + } + } + } + } + } + $this->setDependencyPackages($packages); + $this->setDependencyPhpExtensions($extensions); + + // Import contents + if (isset($data['contents']) && is_array($data['contents']) && is_array($data['contents']['dir'])) { + // Handle files + $root = $data['contents']['dir']; + if (isset($data['contents']['dir']['file'])) { + $fileList = $data['contents']['dir']['file']; + if (!is_array($fileList) || isset($fileList['attribs'])) { + $fileList = array($fileList); + } + foreach ($fileList as $fileRawData) { + $targetName = $fileRawData['attribs']['role']; + $parentTargetNode = $this->_getNode('target', $this->_packageXml->contents, $targetName); + $filePath = $fileRawData['attribs']['name']; + $filePathParts = explode('/', $filePath); + $fileName = array_pop($filePathParts); + $parentDirNode = null; + if (!empty($filePathParts)) { + $parentDirNode = $parentTargetNode; + foreach ($filePathParts as $directoryName) { + $parentDirNode = $this->_getNode('dir', $parentDirNode, $directoryName); + } + } else { + $parentDirNode = $this->_getNode('dir', $parentTargetNode, '.'); + } + $fileNode = $parentDirNode->addChild('file'); + $fileNode->addAttribute('name', $fileName); + $fileNode->addAttribute('hash', $fileRawData['attribs']['md5sum']); + } + } + } + + return $this; + } + + /** + * Convert package channel in order for it to be compatible with current version of Magento Connect Manager + * + * @param string $channel + * + * @return string + */ + public function convertChannelFromV1x($channel) + { + $channelMap = array( + 'connect.magentocommerce.com/community' => 'community', + 'connect.magentocommerce.com/core' => 'community' + ); + if (!empty($channel) && isset($channelMap[$channel])) { + $channel = $channelMap[$channel]; + } + return $channel; + } } diff --git a/downloader/lib/Mage/Connect/Packager.php b/downloader/lib/Mage/Connect/Packager.php index 6555e49d22..46a7019993 100644 --- a/downloader/lib/Mage/Connect/Packager.php +++ b/downloader/lib/Mage/Connect/Packager.php @@ -668,7 +668,7 @@ public function getDependenciesList( $chanName, $package, $cache, $config, $vers if (!$releases || !count($releases)) { throw new Exception("No releases for '{$package}', skipping"); } - $state = $config->preffered_state ? $confg->preffered_state : 'devel'; + $state = $config->preferred_state ? $config->preferred_state : 'devel'; $version = $cache->detectVersionFromRestArray($releases, $versionMin, $versionMax, $state); if(!$version) { throw new Exception("Version for '{$package}' was not detected"); diff --git a/js/jscolor/arrow.gif b/js/jscolor/jscolor/arrow.gif similarity index 100% rename from js/jscolor/arrow.gif rename to js/jscolor/jscolor/arrow.gif diff --git a/js/jscolor/cross.gif b/js/jscolor/jscolor/cross.gif similarity index 100% rename from js/jscolor/cross.gif rename to js/jscolor/jscolor/cross.gif diff --git a/js/jscolor/demo.html b/js/jscolor/jscolor/demo.html similarity index 100% rename from js/jscolor/demo.html rename to js/jscolor/jscolor/demo.html diff --git a/js/jscolor/hs.png b/js/jscolor/jscolor/hs.png similarity index 100% rename from js/jscolor/hs.png rename to js/jscolor/jscolor/hs.png diff --git a/js/jscolor/hv.png b/js/jscolor/jscolor/hv.png similarity index 100% rename from js/jscolor/hv.png rename to js/jscolor/jscolor/hv.png diff --git a/js/jscolor/jscolor.js b/js/jscolor/jscolor/jscolor.js similarity index 100% rename from js/jscolor/jscolor.js rename to js/jscolor/jscolor/jscolor.js diff --git a/js/mage/adminhtml/product/composite/configure.js b/js/mage/adminhtml/product/composite/configure.js index 9561e3d5fd..d3928115aa 100644 --- a/js/mage/adminhtml/product/composite/configure.js +++ b/js/mage/adminhtml/product/composite/configure.js @@ -41,13 +41,14 @@ ProductConfigure.prototype = { blockMsg: null, blockMsgError: null, windowHeight: null, - сonfirmedCurrentId: null, + confirmedCurrentId: null, confirmCallback: {}, cancelCallback: {}, onLoadIFrameCallback: {}, showWindowCallback: {}, beforeSubmitCallback: {}, iFrameJSVarname: null, + _listTypeId: 1, /** * Initialize object @@ -74,6 +75,13 @@ ProductConfigure.prototype = { this.windowHeight = $('html-body').getHeight(); this.iFrameJSVarname = this.blockForm.select('input[name="as_js_varname"]')[0].value; }, + + /** + * Returns next unique list type id + */ + _generateListTypeId: function () { + return '_internal_lt_' + (this._listTypeId++); + }, /** * Add product list types as scope and their urls @@ -93,6 +101,24 @@ ProductConfigure.prototype = { Object.extend(this.listTypes[type], urls); return this; }, + + /** + * Adds complex list type - that is used to submit several list types at once + * Only urlSubmit is possible for this list type + * expamle: addComplexListType(['wishlist', 'product_list'], 'http://magento...') + * + * @param type types as scope + * @param urls obj can be + * - {urlSubmit: 'http://magento...'} for submit configured data through iFrame + * @return type string + */ + addComplexListType: function(types, urlSubmit) { + var type = this._generateListTypeId(); + this.listTypes[type] = {}; + this.listTypes[type].complexTypes = types; + this.listTypes[type].urlSubmit = urlSubmit; + return type; + }, /** * Add filter of items @@ -110,6 +136,30 @@ ProductConfigure.prototype = { this.itemsFilter[listType] = this.itemsFilter[listType].concat(itemsFilter); return this; }, + + /** + * Returns id of block where configuration for an item is stored + * + * @param listType scope name + * @param itemId + * @return string + */ + _getConfirmedBlockId: function (listType, itemId) { + return this.blockConfirmed.id + '[' + listType + '][' + itemId + ']'; + }, + + /** + * Checks whether item has some configuration fields + * + * @param listType scope name + * @param itemId + * @return bool + */ + itemConfigured: function (listType, itemId) { + var confirmedBlockId = this._getConfirmedBlockId(listType, itemId); + var itemBlock = $(confirmedBlockId); + return !!(itemBlock && itemBlock.innerHTML); + }, /** * Show configuration fields of item, if it not found then get it through ajax @@ -125,9 +175,9 @@ ProductConfigure.prototype = { this._initWindowElements(); this.current.listType = listType; this.current.itemId = itemId; - this.сonfirmedCurrentId = this.blockConfirmed.id+'['+listType+']['+itemId+']'; + this.confirmedCurrentId = this._getConfirmedBlockId(listType, itemId); - if (!$(this.сonfirmedCurrentId) || !$(this.сonfirmedCurrentId).innerHTML) { + if (!this.itemConfigured(listType, itemId)) { this._requestItemConfiguration(listType, itemId); } else { this._processFieldsData('item_restore'); @@ -204,7 +254,7 @@ ProductConfigure.prototype = { * * @param listType scope name */ - submit: function(listType) { + submit: function (listType) { // prepare data if (listType) { this.current.listType = listType; @@ -219,8 +269,42 @@ ProductConfigure.prototype = { this.blockForm.action = urlConfirm; this.addFields([new Element('input', {type: 'hidden', name: 'id', value: this.current.itemId})]); } else { - this._processFieldsData('current_confirmed_to_form'); this.blockForm.action = urlSubmit; + + var complexTypes = this.listTypes[this.current.listType].complexTypes; + if (complexTypes) { + this.addFields([new Element('input', {type: 'hidden', name: 'configure_complex_list_types', value: complexTypes.join(',')})]); + } + + this._processFieldsData('current_confirmed_to_form'); + + // Disable item controls that duplicate added fields (e.g. sometimes qty controls can intersect) + // so they won't be submitted + var tagNames = ['input', 'select', 'textarea']; + + var names = {}; // Map of added field names + for (var i = 0, len = tagNames.length; i < len; i++) { + var tagName = tagNames[i]; + var elements = this.blockFormAdd.getElementsByTagName(tagName); + for (var index = 0, elLen = elements.length; index < elLen; index++) { + names[elements[index].name] = true; + } + } + + for (var i = 0, len = tagNames.length; i < len; i++) { + var tagName = tagNames[i]; + var elements = this.blockFormConfirmed.getElementsByTagName(tagName); + for (var index = 0, elLen = elements.length; index < elLen; index++) { + var element = elements[index]; + if (names[element.name]) { + element.setAttribute('configure_disabled', 1); + element.setAttribute('configure_prev_disabled', element.disabled ? 1 : 0); + element.disabled = true; + } else { + element.setAttribute('configure_disabled', 0); + } + } + } } // do submit this.blockIFrame.setAttribute('onload', 'productConfigure.onLoadIFrame()'); @@ -249,7 +333,13 @@ ProductConfigure.prototype = { */ onLoadIFrame: function() { varienLoaderHandler.handler.onComplete(); + + this.blockFormConfirmed.select('[configure_disabled=1]').each(function (element) { + element.disabled = element.getAttribute('configure_prev_disabled') == '1'; + }); + this._processFieldsData('form_confirmed_to_confirmed'); + var response = this.blockIFrame.contentWindow[this.iFrameJSVarname]; if (response && "object" == typeof response) { if (this.listTypes[this.current.listType].urlConfirm) { @@ -286,7 +376,7 @@ ProductConfigure.prototype = { * Helper to find qty of currently confirmed item */ getCurrentConfirmedQtyElement: function() { - var elms = $(this.сonfirmedCurrentId).getElementsByTagName('input'); + var elms = $(this.confirmedCurrentId).getElementsByTagName('input'); for (var i = 0; i < elms.length; i++) { if (elms[i].name == 'qty') { return elms[i]; @@ -386,12 +476,21 @@ ProductConfigure.prototype = { clean: function(method) { switch (method) { case 'current': - var pattern = new RegExp(this.blockConfirmed.id+'\\['+this.current.listType+'\\]'); - this.blockConfirmed.childElements().each(function(elm) { - if (elm.id.match(pattern)) { - elm.remove(); - } - }.bind(this)); + var listInfo = this.listTypes[this.current.listType]; + var listTypes = [this.current.listType]; + if (listInfo.complexTypes) { + listTypes = listTypes.concat(listInfo.complexTypes); + } + + this.blockConfirmed.childElements().each(function(elm) { + for (var i = 0, len = listTypes.length; i < len; i++) { + var pattern = this.blockConfirmed.id + '[' + listTypes[i] + ']'; + if (elm.id.indexOf(pattern) == 0) { + elm.remove(); + break; + } + } + }.bind(this)); break; case 'window': this.blockFormFields.update(); @@ -426,12 +525,13 @@ ProductConfigure.prototype = { _processFieldsData: function(method) { /** - * Internal function for rename fields names of current list type + * Internal function for rename fields names of some list type + * if listType is not specified, then it won't be added as prefix to all names * * @param method can be 'current_confirmed_to_form', 'form_confirmed_to_confirmed' * @param blockItem */ - var _renameFields = function(method, blockItem) { + var _renameFields = function(method, blockItem, listType) { var pattern = null; var patternFlat = null; var replacement = null; @@ -441,11 +541,21 @@ ProductConfigure.prototype = { if (method == 'current_confirmed_to_form') { pattern = RegExp('(\\w+)(\\[?)'); patternFlat = RegExp('(\\w+)'); - replacement = 'item['+itemId+'][$1]$2'; - replacementFlat = 'item_'+itemId+'_$1'; + replacement = 'item[' + itemId + '][$1]$2'; + replacementFlat = 'item_' + itemId + '_$1'; + if (listType) { + replacement = 'list[' + listType + '][item][' + itemId + '][$1]$2'; + replacementFlat = 'list_' + listType + '_' + replacementFlat; + } } else if (method == 'form_confirmed_to_confirmed') { - pattern = new RegExp('item\\['+itemId+'\\]\\[(\\w+)\\](.*)'); - patternFlat = new RegExp('item_'+itemId+'_(\\w+)'); + var stPattern = 'item\\[' + itemId + '\\]\\[(\\w+)\\](.*)'; + var stPatternFlat = 'item_' + itemId + '_(\\w+)'; + if (listType) { + stPattern = 'list\\[' + listType + '\\]\\[item\\]\\[' + itemId + '\\]\\[(\\w+)\\](.*)'; + stPatternFlat = 'list_' + listType + '_' + stPatternFlat; + } + pattern = new RegExp(stPattern); + patternFlat = new RegExp(stPatternFlat); replacement = '$1$2'; replacementFlat = '$1'; } else { @@ -464,23 +574,23 @@ ProductConfigure.prototype = { rename(blockItem.getElementsByTagName('select')); rename(blockItem.getElementsByTagName('textarea')); }.bind(this); - + switch (method) { case 'item_confirm': - if (!$(this.сonfirmedCurrentId)) { - this.blockConfirmed.insert(new Element('div', {id: this.сonfirmedCurrentId})); + if (!$(this.confirmedCurrentId)) { + this.blockConfirmed.insert(new Element('div', {id: this.confirmedCurrentId})); } else { - $(this.сonfirmedCurrentId).update(); + $(this.confirmedCurrentId).update(); } this.blockFormFields.childElements().each(function(elm) { - $(this.сonfirmedCurrentId).insert(elm); + $(this.confirmedCurrentId).insert(elm); }.bind(this)); break; case 'item_restore': this.blockFormFields.update(); // clone confirmed to form - $(this.сonfirmedCurrentId).childElements().each(function(elm) { + $(this.confirmedCurrentId).childElements().each(function(elm) { var cloned = elm.cloneNode(true); this.blockFormFields.insert(cloned); }.bind(this)); @@ -505,9 +615,9 @@ ProductConfigure.prototype = { } } }.bind(this); - getConfirmedValues($(this.сonfirmedCurrentId).getElementsByTagName('input')); - getConfirmedValues($(this.сonfirmedCurrentId).getElementsByTagName('select')); - getConfirmedValues($(this.сonfirmedCurrentId).getElementsByTagName('textarea')); + getConfirmedValues($(this.confirmedCurrentId).getElementsByTagName('input')); + getConfirmedValues($(this.confirmedCurrentId).getElementsByTagName('select')); + getConfirmedValues($(this.confirmedCurrentId).getElementsByTagName('textarea')); // restore confirmed values var restoreConfirmedValues = function (elms) { @@ -532,21 +642,33 @@ ProductConfigure.prototype = { restoreConfirmedValues(this.blockFormFields.getElementsByTagName('textarea')); break; case 'current_confirmed_to_form': + var allowedListTypes = {}; + allowedListTypes[this.current.listType] = true; + var listInfo = this.listTypes[this.current.listType]; + if (listInfo.complexTypes) { + for (var i = 0, len = listInfo.complexTypes.length; i < len; i++) { + allowedListTypes[listInfo.complexTypes[i]] = true; + } + } + this.blockFormConfirmed.update(); this.blockConfirmed.childElements().each(function(blockItem) { var scopeArr = blockItem.id.match(/.*\[(\w+)\]\[(\w+)\]$/); var listType = scopeArr[1]; var itemId = scopeArr[2]; - if (listType == this.current.listType && (!this.itemsFilter[this.current.listType] - || this.itemsFilter[this.current.listType].indexOf(itemId) != -1)) { - _renameFields(method, blockItem); + if (allowedListTypes[listType] && (!this.itemsFilter[listType] + || this.itemsFilter[listType].indexOf(itemId) != -1)) { + _renameFields(method, blockItem, listInfo.complexTypes ? listType : null); this.blockFormConfirmed.insert(blockItem); } }.bind(this)); break; case 'form_confirmed_to_confirmed': + var listInfo = this.listTypes[this.current.listType]; this.blockFormConfirmed.childElements().each(function(blockItem) { - _renameFields(method, blockItem); + var scopeArr = blockItem.id.match(/.*\[(\w+)\]\[(\w+)\]$/); + var listType = scopeArr[1]; + _renameFields(method, blockItem, listInfo.complexTypes ? listType : null); this.blockConfirmed.insert(blockItem); }.bind(this)); break; diff --git a/js/mage/adminhtml/sales.js b/js/mage/adminhtml/sales.js index a63e34e437..7564a899d0 100644 --- a/js/mage/adminhtml/sales.js +++ b/js/mage/adminhtml/sales.js @@ -30,7 +30,7 @@ AdminOrder.prototype = { this.customerId = data.customer_id ? data.customer_id : false; this.storeId = data.store_id ? data.store_id : false; this.currencyId = false; - this.currencySymbol = data.currency_symbol ? data.currency_symbol : false; + this.currencySymbol = data.currency_symbol ? data.currency_symbol : ''; this.addresses = data.addresses ? data.addresses : $H({}); this.shippingAsBilling = data.shippingAsBilling ? data.shippingAsBilling : false; this.gridProducts = $H({}); @@ -367,7 +367,7 @@ AdminOrder.prototype = { for (var i = 0; i < inputs.length; i++) { var input = inputs[i]; input.checkboxElement = checkbox; - + var product = this.gridProducts.get(checkbox.value); if (product) { var defaultValue = product[input.name]; @@ -379,9 +379,9 @@ AdminOrder.prototype = { } } } - + input.disabled = !checkbox.checked || input.hasClassName('input-inactive'); - + Event.observe(input,'keyup', this.productGridRowInputChange.bind(this)); Event.observe(input,'change',this.productGridRowInputChange.bind(this)); } @@ -436,13 +436,13 @@ AdminOrder.prototype = { qtyElement.value = confirmedCurrentQty.value; } // calc and set product price - var productPrice = this._calcProductPrice(); - priceColl.innerHTML = this.currencySymbol + (productPrice + this.productPriceBase[productId]); + var productPrice = parseFloat(this._calcProductPrice() + this.productPriceBase[productId]); + priceColl.innerHTML = this.currencySymbol + productPrice.toFixed(2); // and set checkbox checked grid.setCheckboxChecked(checkbox, true); }.bind(this)); productConfigure.setCancelCallback(listType, function() { - if (!$(productConfigure.сonfirmedCurrentId) || !$(productConfigure.сonfirmedCurrentId).innerHTML) { + if (!$(productConfigure.confirmedCurrentId) || !$(productConfigure.confirmedCurrentId).innerHTML) { grid.setCheckboxChecked(checkbox, false); } }); @@ -468,7 +468,7 @@ AdminOrder.prototype = { var getPriceFields = function (elms) { var productPrice = 0; var getPrice = function (elm) { - if (elm.hasAttribute('price')) { + if (elm.hasAttribute('price') && !elm.disabled) { if (elm.hasAttribute('qtyId') && $(elm.getAttribute('qtyId')).value) { optQty = parseFloat($(elm.getAttribute('qtyId')).value); } @@ -493,10 +493,10 @@ AdminOrder.prototype = { } return productPrice; }.bind(this); - productPrice += getPriceFields($(productConfigure.сonfirmedCurrentId).getElementsByTagName('input')); - productPrice += getPriceFields($(productConfigure.сonfirmedCurrentId).getElementsByTagName('select')); - productPrice += getPriceFields($(productConfigure.сonfirmedCurrentId).getElementsByTagName('textarea')); - return Math.round(productPrice*100)/100; + productPrice += getPriceFields($(productConfigure.confirmedCurrentId).getElementsByTagName('input')); + productPrice += getPriceFields($(productConfigure.confirmedCurrentId).getElementsByTagName('select')); + productPrice += getPriceFields($(productConfigure.confirmedCurrentId).getElementsByTagName('textarea')); + return productPrice; }, productGridCheckboxCheck : function(grid, element, checked){ @@ -512,7 +512,7 @@ AdminOrder.prototype = { input.value = 1; } } - + if (input.checked || input.name != 'giftmessage') { product[input.name] = input.value; } else if (product[input.name]) { @@ -632,7 +632,7 @@ AdminOrder.prototype = { if (params[i] === null) { unset(params[i]); } else if (typeof(params[i]) == 'boolean') { - params[i] = params[i] ? 1 : 0; + params[i] = params[i] ? 1 : 0; } } var fields = []; @@ -820,7 +820,7 @@ AdminOrder.prototype = { } } }, - + loadArea : function(area, indicator, params){ var url = this.loadBaseUrl; if (area) { @@ -845,7 +845,9 @@ AdminOrder.prototype = { else { new Ajax.Request(url, {parameters:params,loaderArea: indicator}); } - productConfigure.clean(); + if (typeof productConfigure != 'undefined') { + productConfigure.clean(); + } }, loadAreaResponseHandler : function (response){ @@ -866,7 +868,9 @@ AdminOrder.prototype = { var id = this.loadingAreas[i]; if($(this.getAreaId(id))){ if ('message' != id || response[id]) { - $(this.getAreaId(id)).update(response[id] ? response[id] : ''); + var wrapper = new Element('div'); + wrapper.update(response[id] ? response[id] : ''); + $(this.getAreaId(id)).update(wrapper); } if ($(this.getAreaId(id)).callback) { this[$(this.getAreaId(id)).callback](); @@ -878,7 +882,7 @@ AdminOrder.prototype = { prepareArea : function(area){ if (this.giftMessageDataChanged) { return area.without('giftmessage'); - } + } return area; }, diff --git a/lib/Mage/Connect/Package.php b/lib/Mage/Connect/Package.php index 16575d6752..27769fbf9b 100644 --- a/lib/Mage/Connect/Package.php +++ b/lib/Mage/Connect/Package.php @@ -33,6 +33,15 @@ */ class Mage_Connect_Package { + /* + * Current version of magento connect package format + */ + const PACKAGE_VERSION_2X = '2'; + + /* + * Previous version of magento connect package format + */ + const PACKAGE_VERSION_1X = '1'; /** * Contain SimpleXMLElement for composing document. @@ -214,6 +223,20 @@ public function save($path) return $this; } + /** + * Creates a package that is compatible with the previous version of Magento Connect Manager and saves it + * + * @param string $path + * @return Mage_Connect_Package + */ + public function saveV1x($path) + { + $this->validate(); + $path = rtrim($path, "\\/") . DS; + $this->_savePackageV1x($path); + return $this; + } + /** * Creates a package archive and saves it to specified path * @@ -233,6 +256,151 @@ protected function _savePackage($path) return $this; } + /** + * Creates a package archive and saves it to specified path + * Package is compatible with the previous version of magento Connect Manager + * + * @param string $path + * @return Mage_Connect_Package + */ + protected function _savePackageV1x($path) + { + $fileName = $this->getReleaseFilename(); + $writer = new Mage_Connect_Package_Writer($this->getContents(), $path.$fileName); + $writer->composePackageV1x($this->getContentsV1x()) + ->addPackageXml($this->_getPackageXmlV1x()) + ->archivePackage(); + return $this; + } + + /** + * Generate package xml that is compatible with first version of Magento Connect Manager + * Function uses already generated package xml to import data + * + * @return string + */ + protected function _getPackageXmlV1x() + { + $newPackageXml = $this->_packageXml; + $packageXmlV1xStub = << + +END; + $packageXmlV1x = simplexml_load_string($packageXmlV1xStub); + // Note: The previous version of MCM requires precise node order in package.xml file + $packageXmlV1x->addChild('name', (string)$newPackageXml->name); + $packageXmlV1x->addChild('channel', Mage::helper('connect')->convertChannelToV1x((string)$newPackageXml->channel)); + $packageXmlV1x->addChild('summary', (string)$newPackageXml->summary); + $packageXmlV1x->addChild('description', (string)$newPackageXml->description); + // Import authors + foreach ($newPackageXml->authors->author as $author) { + $leadNode = $packageXmlV1x->addChild('lead'); + $leadNode->addChild('name', (string)$author->name); + $leadNode->addChild('user', (string)$author->user); + $leadNode->addChild('email', (string)$author->email); + $leadNode->addChild('active', 'yes'); + } + // Import date and time + $packageXmlV1x->addChild('date', (string)$newPackageXml->date); + $packageXmlV1x->addChild('time', (string)$newPackageXml->time); + // Import version + $versionNode = $packageXmlV1x->addChild('version'); + $versionNode->addChild('release', (string)$newPackageXml->version); + $versionNode->addChild('api', (string)$newPackageXml->version); + // Import stability + $stabilityNode = $packageXmlV1x->addChild('stability'); + $stabilityNode->addChild('release', (string)$newPackageXml->stability); + $stabilityNode->addChild('api', (string)$newPackageXml->stability); + // Import license + $licenseNode = $packageXmlV1x->addChild('license', (string)$newPackageXml->license); + if ($newPackageXml->license['uri']) { + $licenseNode->addAttribute('uri', (string)$newPackageXml->license['uri']); + } + $packageXmlV1x->addChild('notes', (string)$newPackageXml->notes); + // Import content + $conentsRootDirNode = $packageXmlV1x->addChild('contents')->addChild('dir'); + $conentsRootDirNode->addAttribute('name', '/'); + foreach ($newPackageXml->contents->target as $target) { + $role = (string)$target['name']; + $this->_mergeContentsToV1x($conentsRootDirNode, $target, $role); + } + // Import dependencies + $requiredDependenciesNode = $packageXmlV1x->addChild('dependencies')->addChild('required'); + $requiredDependenciesPhpNode = $requiredDependenciesNode->addChild('php'); + $requiredDependenciesPhpNode->addChild('min', (string)$newPackageXml->dependencies->required->php->min); + $requiredDependenciesPhpNode->addChild('max', (string)$newPackageXml->dependencies->required->php->max); + $requiredDependenciesNode->addChild('pearinstaller')->addChild('min','1.6.2'); + // Handle packages + foreach ($newPackageXml->dependencies->required->package as $package) { + $packageNode = $requiredDependenciesNode->addChild('package'); + $packageNode->addChild('name', (string)$package->name); + // Convert channel to previous version format + $channel = (string)$package->channel; + $channel = Mage::helper('connect')->convertChannelToV1x($channel); + $packageNode->addChild('channel', $channel); + $minVersion = (string)$package->min; + if ($minVersion) { + $packageNode->addChild('min', $minVersion); + } + $maxVersion = (string)$package->max; + if ($maxVersion) { + $packageNode->addChild('max', $maxVersion); + } + } + // Handle extensions + foreach ($newPackageXml->dependencies->required->extension as $extension) { + $extensionNode = $requiredDependenciesNode->addChild('extension'); + $extensionNode->addChild('name', (string)$extension->name); + $minVersion = (string)$extension->min; + if ($minVersion) { + $extensionNode->addChild('min', $minVersion); + } + $maxVersion = (string)$extension->max; + if ($maxVersion) { + $extensionNode->addChild('max', $maxVersion); + } + } + $packageXmlV1x->addChild('phprelease'); + + return $packageXmlV1x->asXML(); + } + + /** + * Merge contents of source element into destination element + * Function converts and nodes into format that is compatible + * with previous version of Magento Connect Manager + * + * @param SimpleXMLElement $destination + * @param SimpleXMLElement $source + * @param string $role + * @return Mage_Connect_Package + */ + protected function _mergeContentsToV1x($destination, $source, $role) + { + foreach ($source->children() as $child) { + if ($child->getName() == 'dir') { + $newDestination = $destination; + if ($child['name'] != '.') { + $directoryElement = $destination->addChild('dir'); + $directoryElement->addAttribute('name', $child['name']); + $newDestination = $directoryElement; + } + $this->_mergeContentsToV1x($newDestination, $child, $role); + } elseif ($child->getName() == 'file') { + $fileElement = $destination->addChild('file'); + $fileElement->addAttribute('name', $child['name']); + $fileElement->addAttribute('md5sum', $child['hash']); + $fileElement->addAttribute('role', $role); + } + } + return $this; + } + /** * Retrieve Target object * @@ -870,6 +1038,28 @@ public function getContents() return $this->_contents; } + /** + * Create list of all files from package.xml compatible with previous version of Magento Connect Manager + * + * @return array + */ + public function getContentsV1x() + { + $currentContents = $this->_contents; + $this->_contents = array(); + + if(!isset($this->_packageXml->contents->target)) { + return $this->_contents; + } + foreach($this->_packageXml->contents->target as $target) { + $this->_getList($target, ''); + } + $contents = $this->_contents; + + $this->_contents = $currentContents; + return $contents; + } + /** * Helper for getContents(). Create recursively list. * diff --git a/lib/Mage/Connect/Package/Writer.php b/lib/Mage/Connect/Package/Writer.php index 8697f8bd35..374a6b112f 100644 --- a/lib/Mage/Connect/Package/Writer.php +++ b/lib/Mage/Connect/Package/Writer.php @@ -135,6 +135,38 @@ public function composePackage() return $this; } + /** + * Create dir in PATH_TO_TEMPORARY_DIRECTORY and move all files + * to this dir. + * This dir has a structure compatible with previous version of Magento Connact Manager + * + * @param arra $destinationFiles + * @return Mage_Connect_Package_Writer + */ + public function composePackageV1x(array $destinationFiles) + { + @mkdir(self::PATH_TO_TEMPORARY_DIRECTORY, 0777, true); + $root = self::PATH_TO_TEMPORARY_DIRECTORY . basename($this->_namePackage); + @mkdir($root, 0777, true); + $packageFilesDir = $root . DS . basename($this->_namePackage); + @mkdir($packageFilesDir, 0777, true); + foreach ($this->_files as $index => $file) { + $destinationFile = $destinationFiles[$index]; + if (is_dir($file) || is_file($file)) { + $fileName = basename($destinationFile); + $filePath = dirname($destinationFile); + @mkdir($packageFilesDir . DS . $filePath, 0777, true); + if (is_file($file)) { + copy($file, $packageFilesDir . DS . $filePath . DS . $fileName); + } else { + @mkdir($packageFilesDir . DS . $filePath . $fileName, 0777); + } + } + } + $this->_temporaryPackageDir = $root; + return $this; + } + /** * Add package.xml to temporary package directory. * diff --git a/lib/Varien/Data/Collection/Db.php b/lib/Varien/Data/Collection/Db.php index 351f0e24da..6ddcd05d5e 100644 --- a/lib/Varien/Data/Collection/Db.php +++ b/lib/Varien/Data/Collection/Db.php @@ -414,19 +414,22 @@ protected function _getMapper() * If non matched - sequential array is expected and OR conditions * will be built using above mentioned structure * - * @param string $fieldName + * @param string|array $fieldName * @param integer|string|array $condition * @return string */ protected function _getConditionSql($fieldName, $condition) { if (is_array($fieldName)) { - foreach ($fieldName as $f) { - $orSql = array(); - foreach ($condition as $orCondition) { - $orSql[] = '('.$this->_getConditionSql($f[0], $f[1]).')'; + $orSql = array(); + foreach ($fieldName as $key=>$name) { + if (isset($condition[$key])) { + $orSql[] = '('.$this->_getConditionSql($name, $condition[$key]).')'; + } else { + //if nothing passed as condition adding empty condition to avoid sql error + $orSql[] = $this->getConnection()->quoteInto("$name = ?", ''); } - $sql = '('. join(' or ', $orSql) .')'; } + $sql = '('. join(' or ', $orSql) .')'; return $sql; } diff --git a/skin/adminhtml/default/default/boxes.css b/skin/adminhtml/default/default/boxes.css index 428f36d01d..776db11c75 100644 --- a/skin/adminhtml/default/default/boxes.css +++ b/skin/adminhtml/default/default/boxes.css @@ -1315,6 +1315,9 @@ ul.super-product-attributes { padding-left:15px; } /*table.mceLayout { width:100% !important; }*/ +.cms-revision-preview { height:100%; } +.cms-revision-preview iframe { width:100%; height:91%; border:0; } + /* CMS Widgets Instance */ .options-box .option-box { border:1px solid #cddddd; padding:1em; background:#e7efef; margin:1.5em 0; } .options-box .option-title { padding:0 0 10px; border-bottom:1px solid #cddddd; } diff --git a/skin/frontend/default/blank/css/styles.css b/skin/frontend/default/blank/css/styles.css index 6c3cbc2a1c..0f4b2247c1 100644 --- a/skin/frontend/default/blank/css/styles.css +++ b/skin/frontend/default/blank/css/styles.css @@ -711,6 +711,11 @@ tr.summary-details-excluded { font-style:italic; } .price-including-tax .label { white-space:nowrap; } .price-including-tax .price { font-weight:bold; } +/* Configured price */ +.configured-price {} +.configured-price .price-label { font-weight:bold; white-space:nowrap; } +.configured-price .price { font-weight:bold; } + /* FPT */ .weee { display:block; font-size:11px; color:#444; } .weee .price { font-size:11px; font-weight:normal; } diff --git a/skin/frontend/default/blue/css/styles.css b/skin/frontend/default/blue/css/styles.css index 3f4bc142e5..cef7e20c2e 100644 --- a/skin/frontend/default/blue/css/styles.css +++ b/skin/frontend/default/blue/css/styles.css @@ -845,6 +845,11 @@ tr.summary-details-excluded { font-style:italic; } .price-including-tax .label { white-space:nowrap; color:#999; } .price-including-tax .price { font-size:13px; font-weight:bold; } +/* Configured price */ +.configured-price {} +.configured-price .price-label { font-weight:bold; white-space:nowrap; } +.configured-price .price { font-weight:bold; } + /* FPT */ .weee { display:block; font-size:11px; color:#444; } .weee .price { font-size:11px; font-weight:normal; } diff --git a/skin/frontend/default/default/css/styles.css b/skin/frontend/default/default/css/styles.css index c33d5aec55..9c7415dbab 100644 --- a/skin/frontend/default/default/css/styles.css +++ b/skin/frontend/default/default/css/styles.css @@ -882,6 +882,11 @@ tr.summary-details-excluded { font-style:italic; } .price-including-tax .label { white-space:nowrap; color:#999; } .price-including-tax .price { font-size:13px; font-weight:bold; color:#c76200; } +/* Configured price */ +.configured-price { margin:0; } +.configured-price .price-label { font-weight:bold; white-space:nowrap; } +.configured-price .price { font-weight:bold; } + /* FPT */ .weee { display:block; font-size:11px; color:#444; } .weee .price { font-size:11px; font-weight:normal; } diff --git a/skin/frontend/default/iphone/css/iphone.css b/skin/frontend/default/iphone/css/iphone.css index c72c8c6fb5..228f635957 100644 --- a/skin/frontend/default/iphone/css/iphone.css +++ b/skin/frontend/default/iphone/css/iphone.css @@ -271,6 +271,8 @@ p { padding:0; margin:5px 0; } .product-bundle-price { margin:5px 0; font:bold 12px/14px Arial; } .price-box .price { font-weight:bold; white-space:nowrap; } .old-price { text-decoration:line-through; } +.configured-price .price-label { font-weight:bold; white-space:nowrap; } +.configured-price .price { font-weight:bold; } /* Product review */ .review-product-list .product-view { font-size:12px; } diff --git a/skin/frontend/default/modern/css/styles.css b/skin/frontend/default/modern/css/styles.css index 8b30d93bf5..f7b762d924 100644 --- a/skin/frontend/default/modern/css/styles.css +++ b/skin/frontend/default/modern/css/styles.css @@ -822,6 +822,11 @@ tr.summary-details-excluded { font-style:italic; } .price-excluding-tax .label { font-size:10px; text-transform:uppercase; white-space:nowrap; color:#888; } .price-excluding-tax .price { font-size:12px; font-weight:normal; color:#396f00; } +/* Configured price */ +.configured-price { margin:0; } +.configured-price .price-label { font-weight:bold; white-space:nowrap; } +.configured-price .price { font-size:13px; font-weight:bold; } + /* Incl tax (for order tables) */ .price-incl-tax { display:block; } .price-incl-tax .label { display:block; white-space:nowrap; }