diff --git a/.htaccess b/.htaccess old mode 100644 new mode 100755 diff --git a/.htaccess.sample b/.htaccess.sample old mode 100644 new mode 100755 diff --git a/RELEASE_NOTES.txt b/RELEASE_NOTES.txt index 3cd2dacab4..658c509c09 100644 --- a/RELEASE_NOTES.txt +++ b/RELEASE_NOTES.txt @@ -1,3 +1,37 @@ +==== 1.5.0.0-rc2 ===== + +== Changes == +Paypal HSS payment method label, comment and default title + +== Fixes == +Fixed User cannot place order using Paypal payment methods with 3d secure +Fixed iPhone product list preview +Fixed App locations (countries) do not match iTunes App Stores countries available +Fixed Added parent quote items to discount calculation to prevent skipping of configurable products. +Fixed Rounding issue on front end if discount with fixed amount is applied and no tax rules applies to the order. +- added rounding item discount before take away from total discount +Fixed Fatal error after deleting one of the shipping addresses during checkout with multiple addresses +Fixed Merged CSS files with selected native Database as media storage are not applied with Chrome and FF +- first trying to detect MIME type manually, and only after by native php function +Fixed The buttons "Accept Payment" and "Deny Payment" do not appear in orders with status 'Payment Review' +Fixed issue when Simple products not visible individually (part of grouped) are moved to Wishlist +Fixed Impossible to delete product from Items Ordered (backend Order creation) using "remove" in Action dropdown +Fixed Fatal error after deleting one of the shipping addresses during checkout with multiple addresses +Fixed Qty for simple products (part of grouped) is incorrect when moved from order to Wishlist +- additional fixture for other testcase +Fixed Grouped product is added to Items Ordered as grouped, when any of buttons in sideblocks is pressed after product configuration in a product grid (backend Order creation) +- prevent to add unconfigured grouped product on server side +- in sales.js, do productConfigure.clean('quote_items') only if "Items Ordered" block is going to update +- in sales.js, hide "Search" block only when product added to qoute from "Search" block +- in configure.js, added ability to cleaning by list type scope +Fixed Incorrect behavior of Partial Authorization process, when admin user cancels authorizations (Authorize.net) +- added reloading block 'totals' after canceling partial authorization +Fixed Google Checkout Issue - Transactions not appearing +- adding transaction (transaction id = google order id) for googlecheckout payment +- fixed usage of Mage_GoogleCheckout_Model_Api_Xml_Callback::_getTaxClassForShipping() method according to it's interface +- fixed usage of Mage_GoogleCheckout_Model_Api_Xml_Abstract::_getTaxClassForShipping() method according to it's interface +- creating transactions for refund and chargeback + ==== 1.5.0.0-rc1 ===== === Fixes === diff --git a/app/Mage.php b/app/Mage.php index bbaccef366..68a3c20d9a 100644 --- a/app/Mage.php +++ b/app/Mage.php @@ -155,7 +155,7 @@ public static function getVersionInfo() 'revision' => '0', 'patch' => '0', 'stability' => 'rc', - 'number' => '1', + 'number' => '2', ); } 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 793d0289fb..70fd8b228e 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 @@ -331,4 +331,15 @@ public function getItemExtraInfo($item) ->getBlock('order_item_extra_info') ->setItem($item); } + + /** + * Returns whether moving to wishlist is allowed for this item + * + * @param Mage_Sales_Model_Quote_Item $item + * @return bool + */ + public function isMoveToWishlistAllowed($item) + { + return $item->getProduct()->isVisibleInSiteVisibility(); + } } 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 ed000b0466..79b042a8ac 100644 --- a/app/code/core/Mage/Adminhtml/Model/Sales/Order/Create.php +++ b/app/code/core/Mage/Adminhtml/Model/Sales/Order/Create.php @@ -505,6 +505,7 @@ public function moveQuoteItem($item, $moveTo, $qty) { $item = $this->_getQuoteItem($item); if ($item) { + $removeItem = false; switch ($moveTo) { case 'order': $info = $item->getBuyRequest(); @@ -554,26 +555,27 @@ public function moveQuoteItem($item, $moveTo, $qty) } $cartItem->setPrice($item->getProduct()->getPrice()); $this->_needCollectCart = true; + $removeItem = true; } break; case 'wishlist': $wishlist = $this->getCustomerWishlist(); - if ($wishlist) { - $info = $item->getOptionByCode('info_buyRequest'); - if ($info) { - $info = new Varien_Object( - unserialize($info->getValue()) - ); - $info->setOptions($this->_prepareOptionsForRequest($item)); - $info->setStoreId($this->getSession()->getStoreId()); - } + if ($wishlist && $item->getProduct()->isVisibleInSiteVisibility()) { + $info = $item->getBuyRequest(); + $info->setOptions($this->_prepareOptionsForRequest($item)) + ->setQty($qty) + ->setStoreId($this->getSession()->getStoreId()); $wishlist->addNewItem($item->getProduct(), $info); + $removeItem = true; } break; + case 'remove': + $removeItem = true; + break; default: break; } - if ($moveTo != 'order') { + if ($removeItem) { $this->getQuote()->removeItem($item->getId()); } $this->setRecollect(true); @@ -719,11 +721,13 @@ public function addProduct($product, $config = 1) 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_LITE - ); + if ($product->getTypeId() != Mage_Catalog_Model_Product_Type_Grouped::TYPE_CODE) { + $item = $this->getQuote()->addProductAdvanced( + $product, + $config, + Mage_Catalog_Model_Product_Type_Abstract::PROCESS_MODE_LITE + ); + } if (is_string($item)) { Mage::throwException($item); } diff --git a/app/code/core/Mage/Catalog/Model/Product.php b/app/code/core/Mage/Catalog/Model/Product.php index e9391a733f..458a26a166 100644 --- a/app/code/core/Mage/Catalog/Model/Product.php +++ b/app/code/core/Mage/Catalog/Model/Product.php @@ -1789,8 +1789,8 @@ public function prepareCustomOptions() */ protected function _clearReferences() { - $this->_clearStockItem(); $this->_clearOptionReferences(); + return $this; } /** @@ -1830,23 +1830,10 @@ protected function _clearOptionReferences() if (!empty($this->_options)) { foreach ($this->_options as $key => $option) { $option->setProduct(); - $option->clear(); + $option->clearInstance(); } } return $this; } - - /** - * Clearing references to product from product's stock item - * - * @return Mage_Catalog_Model_Product - */ - protected function _clearStockItem() - { - if ($this->hasStockItem()){ - $this->getStockItem()->reset(); - } - return $this; - } } diff --git a/app/code/core/Mage/CatalogInventory/Model/Observer.php b/app/code/core/Mage/CatalogInventory/Model/Observer.php index f58d6542f8..33d2af10b4 100644 --- a/app/code/core/Mage/CatalogInventory/Model/Observer.php +++ b/app/code/core/Mage/CatalogInventory/Model/Observer.php @@ -247,7 +247,8 @@ public function checkQuoteItemQty($observer) { $quoteItem = $observer->getEvent()->getItem(); /* @var $quoteItem Mage_Sales_Model_Quote_Item */ - if (!$quoteItem || !$quoteItem->getProductId() || $quoteItem->getQuote()->getIsSuperMode()) { + if (!$quoteItem || !$quoteItem->getProductId() || !$quoteItem->getQuote() + || $quoteItem->getQuote()->getIsSuperMode()) { return $this; } diff --git a/app/code/core/Mage/GoogleCheckout/Model/Api/Xml/Callback.php b/app/code/core/Mage/GoogleCheckout/Model/Api/Xml/Callback.php index dd02ca634f..2adfe87527 100644 --- a/app/code/core/Mage/GoogleCheckout/Model/Api/Xml/Callback.php +++ b/app/code/core/Mage/GoogleCheckout/Model/Api/Xml/Callback.php @@ -161,7 +161,6 @@ protected function _responseMerchantCalculationCallback() $merchantCalculations = new GoogleMerchantCalculations($this->getCurrency()); $quote = $this->_loadQuote(); - $storeId = $quote->getStoreId(); $billingAddress = $quote->getBillingAddress(); $address = $quote->getShippingAddress(); @@ -207,6 +206,7 @@ protected function _responseMerchantCalculationCallback() ->setLimitCarrier($limitCarrier); $billingAddress->collectTotals(); + $shippingTaxClass = $this->_getTaxClassForShipping($quote); $gRequestMethods = $this->getData('root/calculate/shipping/method'); if ($gRequestMethods) { @@ -239,7 +239,7 @@ protected function _responseMerchantCalculationCallback() ->setCollectShippingRates(true) ->collectTotals(); $shippingRate = $address->getBaseShippingAmount() - $address->getBaseShippingDiscountAmount(); - $result->SetShippingDetails($methodName, $shippingRate, "true"); + $result->SetShippingDetails($methodName, $shippingRate, 'true'); if ($this->getData('root/calculate/tax/VALUE') == 'true') { $taxAmount = $address->getBaseTaxAmount(); @@ -247,7 +247,6 @@ protected function _responseMerchantCalculationCallback() $result->setTaxDetails($taxAmount); } } else { - $shippingTaxClass = $this->_getTaxClassForShipping($quote->getStoreId()); if ($shippingTaxClass && $this->getData('root/calculate/tax/VALUE') == 'true') { $i = 1; @@ -261,24 +260,24 @@ protected function _responseMerchantCalculationCallback() $address->setShippingAmount( $this->_reCalculateToStoreCurrency($price, $quote) ); - $this->_applyShippingTaxClass($address); + $this->_applyShippingTaxClass($address, $shippingTaxClass); $taxAmount = $address->getBaseTaxAmount(); $taxAmount += $billingAddress->getBaseTaxAmount(); - $result->SetShippingDetails($methodName, $price - $address->getBaseShippingDiscountAmount(), "true"); + $result->SetShippingDetails($methodName, $price - $address->getBaseShippingDiscountAmount(), 'true'); $result->setTaxDetails($taxAmount); $i++; } else { - $result->SetShippingDetails($methodName, 0, "false"); + $result->SetShippingDetails($methodName, 0, 'false'); } } $merchantCalculations->AddResult($result); } - } else if ($this->getData('root/calculate/tax/VALUE')=='true') { + } else if ($this->getData('root/calculate/tax/VALUE') == 'true') { $address->setShippingMethod(null); $address->setCollectShippingRates(true)->collectTotals(); $billingAddress->setCollectShippingRates(true)->collectTotals(); - $this->_applyShippingTaxClass($address); + $this->_applyShippingTaxClass($address, $shippingTaxClass); $taxAmount = $address->getBaseTaxAmount(); $taxAmount += $billingAddress->getBaseTaxAmount(); @@ -399,8 +398,16 @@ protected function _responseNewOrderNotification() $order->addItem($orderItem); } - $payment = Mage::getModel('sales/order_payment')->setMethod('googlecheckout'); + /* + * Adding transaction for correct transaction information displaying on order view at back end. + * It has no influence on api interaction logic. + */ + $payment = Mage::getModel('sales/order_payment') + ->setMethod('googlecheckout') + ->setTransactionId($this->getGoogleOrderNumber()) + ->setIsTransactionClosed(false); $order->setPayment($payment); + $payment->addTransaction(Mage_Sales_Model_Order_Payment_Transaction::TYPE_AUTH); $order->setCanShipPartiallyItem(false); $emailAllowed = ($this->getData('root/buyer-marketing-preferences/email-allowed/VALUE')==='true'); @@ -485,7 +492,7 @@ protected function _applyCustomTax($qAddress) } /** - * Import address data from goole request to address object + * Import address data from google request to address object * * @param array | Varien_Object $gAddress * @param Varien_Object $qAddress @@ -782,11 +789,12 @@ protected function _responseChargeAmountNotification() $msg .= '
'.$this->__('Invoice Auto-Created: %s', ''.$invoice->getIncrementId().''); } + $this->_addChildTransaction(Mage_Sales_Model_Order_Payment_Transaction::TYPE_CAPTURE); + + $open = Mage_Sales_Model_Order_Invoice::STATE_OPEN; foreach ($order->getInvoiceCollection() as $orderInvoice) { - $open = Mage_Sales_Model_Order_Invoice::STATE_OPEN; - $paid = Mage_Sales_Model_Order_Invoice::STATE_PAID; if ($orderInvoice->getState() == $open && $orderInvoice->getBaseGrandTotal() == $latestCharged) { - $orderInvoice->setState($paid) + $orderInvoice->setState(Mage_Sales_Model_Order_Invoice::STATE_PAID) ->setTransactionId($this->getGoogleOrderNumber()) ->save(); break; @@ -795,17 +803,17 @@ protected function _responseChargeAmountNotification() $order->addStatusToHistory($order->getStatus(), $msg); $order->save(); - } protected function _createInvoice() { $order = $this->getOrder(); - $invoice = $order->prepareInvoice(); - $invoice->addComment(Mage::helper('googlecheckout')->__('Auto-generated from GoogleCheckout Charge')); - $invoice->register(); - $invoice->pay(); + $invoice = $order->prepareInvoice() + ->setTransactionId($this->getGoogleOrderNumber()) + ->addComment(Mage::helper('googlecheckout')->__('Auto-generated from GoogleCheckout Charge')) + ->register() + ->pay(); $transactionSave = Mage::getModel('core/resource_transaction') ->addObject($invoice) @@ -859,6 +867,9 @@ protected function _responseChargebackAmountNotification() $msg .= '
'.$this->__('Latest Chargeback: %s', '' . $this->_formatAmount($latestChargeback) . ''); $msg .= '
'.$this->__('Total Chargeback: %s', '' . $this->_formatAmount($totalChargeback) . ''); + $this->_addChildTransaction(Mage_Sales_Model_Order_Payment_Transaction::TYPE_REFUND, + Mage_Sales_Model_Order_Payment_Transaction::TYPE_CAPTURE); + $order->addStatusToHistory($order->getStatus(), $msg); $order->save(); } @@ -898,6 +909,9 @@ protected function _responseRefundAmountNotification() $msg .= '
'.$this->__('Latest Refund: %s', '' . $this->_formatAmount($latestRefunded) . ''); $msg .= '
'.$this->__('Total Refunded: %s', '' . $this->_formatAmount($totalRefunded) . ''); + $this->_addChildTransaction(Mage_Sales_Model_Order_Payment_Transaction::TYPE_REFUND, + Mage_Sales_Model_Order_Payment_Transaction::TYPE_CAPTURE); + $order->addStatusToHistory($order->getStatus(), $msg); $order->save(); } @@ -933,6 +947,39 @@ protected function _responseOrderStateChangeNotification() } } + /** + * Add transaction to payment with defined type + * + * @param string $typeTarget + * @param string $typeParent + * @return Mage_GoogleCheckout_Model_Api_Xml_Callback + */ + protected function _addChildTransaction($typeTarget, $typeParent = Mage_Sales_Model_Order_Payment_Transaction::TYPE_AUTH) + { + $payment = $this->getOrder()->getPayment(); + $googleOrderId = $this->getGoogleOrderNumber(); + $parentTransactionId = $googleOrderId; + + if ($typeParent != Mage_Sales_Model_Order_Payment_Transaction::TYPE_AUTH) { + $parentTransactionId .= '-' . $typeParent; + } else { + $payment->setIsTransactionClosed(false); + } + + $parentTransaction = $payment->getTransaction($parentTransactionId); + + if ($parentTransaction) { + $payment->setParentTransactionId($parentTransactionId) + ->setTransactionId($googleOrderId . '-' . $typeTarget) + ->addTransaction($typeTarget); + + $parentTransaction->setIsClosed(true) + ->save(); + } + + return $this; + } + protected function _orderStateChangeFinancialReviewing() { diff --git a/app/code/core/Mage/Paypal/Model/Pro.php b/app/code/core/Mage/Paypal/Model/Pro.php index 7d86f116f1..4b07777dff 100644 --- a/app/code/core/Mage/Paypal/Model/Pro.php +++ b/app/code/core/Mage/Paypal/Model/Pro.php @@ -274,7 +274,7 @@ public function cancel(Varien_Object $payment) */ public function canReviewPayment(Mage_Payment_Model_Info $payment) { - return Mage_Paypal_Model_Info::isFraudReviewAllowed($payment); + return Mage_Paypal_Model_Info::isPaymentReviewRequired($payment); } /** diff --git a/app/code/core/Mage/Paypal/etc/system.xml b/app/code/core/Mage/Paypal/etc/system.xml index a19c395374..49f4dcda42 100644 --- a/app/code/core/Mage/Paypal/etc/system.xml +++ b/app/code/core/Mage/Paypal/etc/system.xml @@ -164,8 +164,8 @@ 1 - - 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. + + Contact PayPal before activating]]> payment/hosted_pro/active checkbox diff --git a/app/code/core/Mage/Sales/Model/Order/Payment.php b/app/code/core/Mage/Sales/Model/Order/Payment.php index f4196eaaf2..0fb24d71c7 100644 --- a/app/code/core/Mage/Sales/Model/Order/Payment.php +++ b/app/code/core/Mage/Sales/Model/Order/Payment.php @@ -258,7 +258,7 @@ public function capture($invoice) } $this->_isCaptureFinal($paidWorkaround); - if (!$this->getParentTransactionId) { + if (!$this->getParentTransactionId()) { $orderingTransaction = $this->_lookupTransaction(false, Mage_Sales_Model_Order_Payment_Transaction::TYPE_ORDER); if ($orderingTransaction) { $this->setParentTransactionId($orderingTransaction->getTxnId()); diff --git a/app/code/core/Mage/SalesRule/Model/Validator.php b/app/code/core/Mage/SalesRule/Model/Validator.php index 095805d2cc..a920db0881 100644 --- a/app/code/core/Mage/SalesRule/Model/Validator.php +++ b/app/code/core/Mage/SalesRule/Model/Validator.php @@ -250,7 +250,7 @@ public function reset(Mage_Sales_Model_Quote_Address $address) $address->getQuote()->setAppliedRuleIds(''); $this->_isFirstTimeResetRun = false; } - + return $this; } @@ -348,7 +348,6 @@ public function process(Mage_Sales_Model_Quote_Item_Abstract $item) if ($cartRules[$rule->getId()] > 0) { if ($this->_rulesItemTotals[$rule->getId()]['items_count'] <= 1) { $quoteAmount = $quote->getStore()->convertPrice($cartRules[$rule->getId()]); - $baseDiscountAmount = min($baseItemPrice * $qty, $cartRules[$rule->getId()]); } else { $discountRate = $baseItemPrice * $qty / $this->_rulesItemTotals[$rule->getId()]['base_items_price']; @@ -360,6 +359,8 @@ public function process(Mage_Sales_Model_Quote_Item_Abstract $item) } $discountAmount = min($itemPrice * $qty, $quoteAmount); + $discountAmount = $quote->getStore()->roundPrice($discountAmount); + $baseDiscountAmount = $quote->getStore()->roundPrice($baseDiscountAmount); $cartRules[$rule->getId()] -= $baseDiscountAmount; } $address->setCartFixedRules($cartRules); @@ -608,8 +609,8 @@ public function initTotals($items, Mage_Sales_Model_Quote_Address $address) $validItemsCount = 0; foreach ($items as $item) { - // For complex product handle only its child items - if ($item->getHasChildren()) { + //Skipping child items to avoid double calculations + if ($item->getParentItemId()) { continue; } if (!$rule->getActions()->validate($item)) { @@ -628,6 +629,7 @@ public function initTotals($items, Mage_Sales_Model_Quote_Address $address) ); } } + return $this; } diff --git a/app/code/core/Mage/XmlConnect/Block/Adminhtml/Mobile/Edit/Tab/Notification.php b/app/code/core/Mage/XmlConnect/Block/Adminhtml/Mobile/Edit/Tab/Notification.php index 4e41e9a005..439475952d 100755 --- a/app/code/core/Mage/XmlConnect/Block/Adminhtml/Mobile/Edit/Tab/Notification.php +++ b/app/code/core/Mage/XmlConnect/Block/Adminhtml/Mobile/Edit/Tab/Notification.php @@ -168,6 +168,7 @@ public function isHidden() /** * Append helper above form + * * @return string */ protected function _toHtml() diff --git a/app/code/core/Mage/XmlConnect/Block/Adminhtml/Mobile/Submission/Form.php b/app/code/core/Mage/XmlConnect/Block/Adminhtml/Mobile/Submission/Form.php index df1653f0a8..9c3b26ae8a 100644 --- a/app/code/core/Mage/XmlConnect/Block/Adminhtml/Mobile/Submission/Form.php +++ b/app/code/core/Mage/XmlConnect/Block/Adminhtml/Mobile/Submission/Form.php @@ -32,7 +32,12 @@ class Mage_XmlConnect_Block_Adminhtml_Mobile_Submission_Form extends Mage_Adminh */ protected function _prepareForm() { - $form = new Varien_Data_Form(array('id' => 'edit_form', 'action' => $this->getUrl('*/mobile/submission'), 'method' => 'post', 'enctype' => 'multipart/form-data')); + $form = new Varien_Data_Form(array( + 'id' => 'edit_form', + 'action' => $this->getUrl('*/mobile/submission'), + 'method' => 'post', + 'enctype' => 'multipart/form-data' + )); $form->setUseContainer(true); $this->setForm($form); return parent::_prepareForm(); diff --git a/app/code/core/Mage/XmlConnect/Block/Catalog/Product.php b/app/code/core/Mage/XmlConnect/Block/Catalog/Product.php index 071081ac57..2e86b35688 100644 --- a/app/code/core/Mage/XmlConnect/Block/Catalog/Product.php +++ b/app/code/core/Mage/XmlConnect/Block/Catalog/Product.php @@ -150,9 +150,11 @@ protected function _toHtml() } } - $productXmlObj->appendChild($this->getChild('xmlconnect.catalog.product.options') - ->getProductOptionsXmlObject($product) - ); + $productOptions = $this->getChild('xmlconnect.catalog.product.options') + ->getProductOptionsXmlObject($product); + if ($productOptions instanceof Mage_XmlConnect_Model_Simplexml_Element) { + $productXmlObj->appendChild($productOptions); + } return $productXmlObj->asNiceXml(); } diff --git a/app/code/core/Mage/XmlConnect/Helper/Data.php b/app/code/core/Mage/XmlConnect/Helper/Data.php index d51172d1da..ccc1ac14f2 100644 --- a/app/code/core/Mage/XmlConnect/Helper/Data.php +++ b/app/code/core/Mage/XmlConnect/Helper/Data.php @@ -102,15 +102,8 @@ class Mage_XmlConnect_Helper_Data extends Mage_Core_Helper_Abstract */ public function getDeviceHelper($application = null) { - $deviceType = null; - if (empty($application)) { - $deviceType = (string) $this->getApplication()->getType(); - } elseif ($application instanceof Mage_XmlConnect_Model_Application) { - $deviceType = (string) $application->getType(); - } - if (empty($deviceType)) { - $deviceType = self::DEVICE_TYPE_DEFAULT; - } + $deviceType = $this->getDeviceType($application); + switch ($deviceType) { case self::DEVICE_TYPE_IPHONE: case self::DEVICE_TYPE_IPAD: @@ -124,6 +117,26 @@ public function getDeviceHelper($application = null) return $helper; } + /** + * Get device tipe from application + * + * @param Mage_XmlConnect_Model_Application $application + * @return string + */ + public function getDeviceType($application = null) + { + $deviceType = null; + if (empty($application) && Mage::registry('current_app') !== null) { + $deviceType = (string) $this->getApplication()->getType(); + } elseif ($application instanceof Mage_XmlConnect_Model_Application) { + $deviceType = (string) $application->getType(); + } + if (empty($deviceType)) { + $deviceType = self::DEVICE_TYPE_DEFAULT; + } + return $deviceType; + } + /** * Getter for current loaded application model * @@ -177,24 +190,42 @@ public function getUrl($route, $params = array()) return $this->_getUrl($route, $params); } - /** * Retrieve country options array * + * @param bool $isItunes * @return array */ - public function getCountryOptionsArray() + public function getCountryOptionsArray($isItunes = false) { Varien_Profiler::start('TEST: '.__METHOD__); + switch ($this->getDeviceType()) { + case self::DEVICE_TYPE_IPHONE: + case self::DEVICE_TYPE_IPAD: + $cacheKey = 'XMLCONNECT_COUNTRY_ITUNES_SELECT_STORE_'.Mage::app()->getStore()->getCode(); + $itunesCountries = $this->getDeviceHelper()->getItunesCountriesArray(); + break; + case self::DEVICE_TYPE_ANDROID: + default: + $cacheKey = 'XMLCONNECT_COUNTRY_SELECT_STORE_'.Mage::app()->getStore()->getCode(); + break; + } - $cacheKey = 'XMLCONNECT_COUNTRY_SELECT_STORE_'.Mage::app()->getStore()->getCode(); - if (Mage::app()->useCache('config') && $cache = Mage::app()->loadCache($cacheKey)) { + if (false && Mage::app()->useCache('config') && $cache = Mage::app()->loadCache($cacheKey)) { $options = unserialize($cache); } else { - $options = Mage::getModel('directory/country') - ->getResourceCollection() - ->loadByStore() - ->toOptionArray(); + if (isset($itunesCountries)) { + $options = Mage::getModel('directory/country') + ->getResourceCollection() + ->addFieldToFilter('country_id', array('in' => $itunesCountries)) + ->loadByStore() + ->toOptionArray(); + } else { + $options = Mage::getModel('directory/country') + ->getResourceCollection() + ->loadByStore() + ->toOptionArray(); + } if (Mage::app()->useCache('config')) { Mage::app()->saveCache(serialize($options), $cacheKey, array('config')); } diff --git a/app/code/core/Mage/XmlConnect/Helper/Ipad.php b/app/code/core/Mage/XmlConnect/Helper/Ipad.php index e8a462ae5e..b72ade105a 100755 --- a/app/code/core/Mage/XmlConnect/Helper/Ipad.php +++ b/app/code/core/Mage/XmlConnect/Helper/Ipad.php @@ -439,4 +439,15 @@ public function getFontSizes() } return $result; } + + /** + * Get list of coutries that allowed in Ituens by Apple Store for Ipad + * (get info from Iphone helper) + * + * @return array + */ + public function getItunesCountriesArray() + { + return Mage::helper('xmlconnect/iphone')->getItunesCountriesArray(); + } } diff --git a/app/code/core/Mage/XmlConnect/Helper/Iphone.php b/app/code/core/Mage/XmlConnect/Helper/Iphone.php index 890e9d2ae5..e3e93d81f4 100644 --- a/app/code/core/Mage/XmlConnect/Helper/Iphone.php +++ b/app/code/core/Mage/XmlConnect/Helper/Iphone.php @@ -26,6 +26,107 @@ class Mage_XmlConnect_Helper_Iphone extends Mage_Core_Helper_Abstract { + /** + * List of coutries that allowed in Ituens by Apple Store + * + * array( + * 'country name' => 'country id at directory model' + * ) + * + * @var array + */ + protected $_allowedCounrties = array( + 'Argentina' => 'AR', + 'Armenia' => 'AM', + 'Australia' => 'AU', + 'Austria' => 'AT', + 'Belgium' => 'BE', + 'Botswana' => 'BW', + 'Brazil' =>'BR', + 'Bulgaria' => 'BG', + 'Canada' => 'CA', + 'Chile' => 'CL', + 'China' => 'CN', + 'Colombia' => 'CO', + 'Costa Rica' => 'CR', + 'Croatia' => 'HR', + 'Czech Republic' => 'CZ', + 'Denmark' => 'DK', + 'Dominican Republic' => 'DO', + 'Ecuador' => 'EC', + 'Egypt' => 'EG', + 'El Salvador' => 'SV', + 'Estonia' => 'EE', + 'Finland' => 'FI', + 'France' => 'FR', + 'Germany' => 'DE', + 'Greece' => 'GR', + 'Guatemala' => 'GT', + 'Honduras' => 'HN', + 'Hong Kong SAR China' => 'HK', + 'Hungary' => 'HU', + 'India' => 'IN', + 'Indonesia' => 'ID', + 'Ireland' => 'IE', + 'Israel' => 'IL', + 'Italy' => 'IT', + 'Jamaica' => 'JM', + 'Japan' => 'JP', + 'Jordan' => 'JO', + 'Kazakstan' => 'KZ', + 'Kenya' => 'KE', + 'South Korea' => 'KR', + 'Kuwait' => 'KW', + 'Latvia' => 'LW', + 'Lebanon' => 'LB', + 'Lithuania' => 'LT', + 'Luxembourg' => 'LU', + 'Macau SAR China' => 'MO', + 'Macedonia' => 'MK', + 'Madagascar' => 'MG', + 'Malaysia' => 'MY', + 'Mali' => 'ML', + 'Malta' => 'MT', + 'Mauritius' => 'MU', + 'Mexico' => 'MX', + 'Moldova' => 'MD', + 'Netherlands' => 'NL', + 'New Zealand' => 'NZ', + 'Nicaragua' => 'NI', + 'Niger' => 'NE', + 'Norway' => 'NO', + 'Pakistan' => 'PK', + 'Panama' => 'PA', + 'Paraguay' => 'PY', + 'Peru'=> 'PE', + 'Philippines' => 'PH', + 'Poland' => 'PL', + 'Portugal' => 'PT', + 'Qatar' => 'QA', + 'Romania' => 'RO', + 'Russia' => 'RU', + 'Saudi Arabia' => 'SA', + 'Senegal' => 'SN', + 'Singapore' => 'SG', + 'Slovakia' => 'SK', + 'Slovenia' => 'SI', + 'South Africa' => 'ZA', + 'Spain' => 'ES', + 'Sri Lanka' => 'LK', + 'Sweden' => 'SE', + 'Switzerland' => 'CH', + 'Taiwan' => 'TW', + 'Thailand' => 'TH', + 'Tunisia' => 'TN', + 'Turkey' => 'TR', + 'Uganda' => 'UG', + 'United Arab Emirates' => 'AE', + 'United Kingdom' => 'GB', + 'United States' => 'US', + 'Uruguay' => 'UY', + 'Venezuela' => 'VE', + 'Vietnam' => 'VN', + ); /** * Get default application tabs @@ -389,4 +490,14 @@ public function getFontSizes() } return $result; } + + /** + * Get list of coutries that allowed in Ituens by Apple Store for Iphone + * + * @return array + */ + public function getItunesCountriesArray() + { + return $this->_allowedCounrties; + } } diff --git a/app/code/core/Mage/XmlConnect/Model/Payment/Method/Paypal/Mep.php b/app/code/core/Mage/XmlConnect/Model/Payment/Method/Paypal/Mep.php index eac72efb4b..f902f73993 100644 --- a/app/code/core/Mage/XmlConnect/Model/Payment/Method/Paypal/Mep.php +++ b/app/code/core/Mage/XmlConnect/Model/Payment/Method/Paypal/Mep.php @@ -79,7 +79,7 @@ public function isAvailable($quote = null) if (!$storeId) { $storeId = $quote ? $quote->getStoreId() : Mage::app()->getStore()->getId(); } - + return Mage::getModel('paypal/config') ->setStoreId($storeId) ->isMethodAvailable(Mage_Paypal_Model_Config::METHOD_WPP_EXPRESS); diff --git a/app/design/adminhtml/default/default/layout/xmlconnect.xml b/app/design/adminhtml/default/default/layout/xmlconnect.xml index f67dd9096a..e2c0478c7f 100644 --- a/app/design/adminhtml/default/default/layout/xmlconnect.xml +++ b/app/design/adminhtml/default/default/layout/xmlconnect.xml @@ -150,7 +150,6 @@ - submission_sectionmobile_submission_tab_container diff --git a/app/design/adminhtml/default/default/template/paygate/form/cc.phtml b/app/design/adminhtml/default/default/template/paygate/form/cc.phtml index 4d5c33d532..6238d7a907 100644 --- a/app/design/adminhtml/default/default/template/paygate/form/cc.phtml +++ b/app/design/adminhtml/default/default/template/paygate/form/cc.phtml @@ -51,7 +51,7 @@ } if (response.success) { - order.loadArea(['billing_method'], true, []); + order.loadArea(['billing_method','totals'], true, []); } else { var msg = response.error_message; if (msg) { diff --git a/app/design/adminhtml/default/default/template/sales/order/create/items/grid.phtml b/app/design/adminhtml/default/default/template/sales/order/create/items/grid.phtml index 0461b65e9c..8e6583e63c 100644 --- a/app/design/adminhtml/default/default/template/sales/order/create/items/grid.phtml +++ b/app/design/adminhtml/default/default/template/sales/order/create/items/grid.phtml @@ -396,8 +396,10 @@ getCustomerId() && $this->getMoveToCustomerStorage()): ?> - - + + isMoveToWishlistAllowed($_item)): ?> + + diff --git a/app/design/adminhtml/default/default/template/xmlconnect/edit/tab/design/preview/catalog.phtml b/app/design/adminhtml/default/default/template/xmlconnect/edit/tab/design/preview/catalog.phtml index a6f7d6766b..9052610217 100644 --- a/app/design/adminhtml/default/default/template/xmlconnect/edit/tab/design/preview/catalog.phtml +++ b/app/design/adminhtml/default/default/template/xmlconnect/edit/tab/design/preview/catalog.phtml @@ -51,6 +51,7 @@ $text2color = $this->getConfigFontInfo('Text2/color'); $naviBarTintColor = $this->getData('conf/navigationBar/tintColor'); $primaryColor = $this->getData('conf/body/primaryColor'); +$secondaryColor = $this->getData('conf/body/secondaryColor'); $activeStartImage = $this->getPreviewImagesUrl('star-active.png'); $inactiveStartImage = $this->getPreviewImagesUrl('star-inactive.png'); @@ -115,8 +116,10 @@ $productImage = $this->getPreviewImagesUrl('t-shirt.png');
__('SORT BY:'); ?>
-
- Filter Settings +
+ Position + Name + Price
@@ -130,8 +133,10 @@ $productImage = $this->getPreviewImagesUrl('t-shirt.png'); $39.99
- - (4) + + ffffc + + (2)
In Stock @@ -148,8 +153,10 @@ $productImage = $this->getPreviewImagesUrl('t-shirt.png'); $39.99
- - (4) + + ffffc + + (2)
__('In Stock'); ?> @@ -157,7 +164,7 @@ $productImage = $this->getPreviewImagesUrl('t-shirt.png');
 
-
+
@@ -199,8 +206,10 @@ $productImage = $this->getPreviewImagesUrl('t-shirt.png'); $39.99
- - (4) + + ffffc + + (4)
__('In Stock'); ?> diff --git a/app/design/adminhtml/default/default/template/xmlconnect/mobile/notification_helper.phtml b/app/design/adminhtml/default/default/template/xmlconnect/mobile/notification_helper.phtml index 7a56c68ae1..94aad48175 100644 --- a/app/design/adminhtml/default/default/template/xmlconnect/mobile/notification_helper.phtml +++ b/app/design/adminhtml/default/default/template/xmlconnect/mobile/notification_helper.phtml @@ -24,10 +24,6 @@ * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) */ ?> - -getId()):?> -loadConfiguration(); ?> -getAppKey()):?>
-
- - +
\ No newline at end of file diff --git a/app/design/frontend/base/default/template/checkout/multishipping/addresses.phtml b/app/design/frontend/base/default/template/checkout/multishipping/addresses.phtml index 83beb4ada6..6092f62eea 100644 --- a/app/design/frontend/base/default/template/checkout/multishipping/addresses.phtml +++ b/app/design/frontend/base/default/template/checkout/multishipping/addresses.phtml @@ -61,12 +61,14 @@ getItems() as $_index => $_item): ?> + getQuoteItem()) :?> getItemHtml($_item->getQuoteItem())?> getProduct()->getIsVirtual()): echo $this->__('Shipping selection is not applicable.'); else: echo $this->getAddressesHtmlSelect($_item, $_index); endif; ?> __('Remove Item') ?> + diff --git a/app/locale/en_US/Mage_Paypal.csv b/app/locale/en_US/Mage_Paypal.csv index 75b7e2e92f..24089dfa35 100644 --- a/app/locale/en_US/Mage_Paypal.csv +++ b/app/locale/en_US/Mage_Paypal.csv @@ -153,7 +153,6 @@ "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" @@ -270,6 +269,7 @@ "Payment has been declined. Please try again.","Payment has been declined. Please try again." "Payments by PayPal (150 X 40)","Payments by PayPal (150 X 40)" "Payments by PayPal (150 X 60)","Payments by PayPal (150 X 60)" +"Payments by cards + seller protection - Contact PayPal before activating","Payments by cards + seller protection - Contact PayPal before activating" "Paypal Billing Agreement Settings","Paypal Billing Agreement Settings" "Pending PayPal","Pending PayPal" "Place Order","Place Order" @@ -387,8 +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 (Website Payments Plus (JP) - Integral Evolution (FR) - PayPal Pro (IT) - Pasarela integral (ES))","Website Payments Pro Hosted Solution (Website Payments Plus (JP) - Integral Evolution (FR) - PayPal Pro (IT) - Pasarela integral (ES))" "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/downloader/Maged/Controller.php b/downloader/Maged/Controller.php index 4aca250376..4197d54e2c 100755 --- a/downloader/Maged/Controller.php +++ b/downloader/Maged/Controller.php @@ -937,7 +937,7 @@ public static function getVersionInfo() 'revision' => '0', 'patch' => '0', 'stability' => 'rc', - 'number' => '1', + 'number' => '2', ); } diff --git a/get.php b/get.php index ab5e8e86d0..1a692bfde0 100644 --- a/get.php +++ b/get.php @@ -51,8 +51,8 @@ $appPath = implode($ps, $paths); set_include_path($appPath . $ps . get_include_path()); -include_once "Mage/Core/functions.php"; -include_once "Varien/Autoload.php"; +include_once 'Mage/Core/functions.php'; +include_once 'Varien/Autoload.php'; Varien_Autoload::register(); @@ -74,7 +74,7 @@ $mageFilename = 'app/Mage.php'; if (!file_exists($mageFilename)) { - echo $mageFilename." was not found"; + echo $mageFilename . ' was not found'; } require_once $mageFilename; @@ -98,7 +98,7 @@ mkdir($directory, 0777, true); } - $fp = fopen($filePath, "w"); + $fp = fopen($filePath, 'w'); if (flock($fp, LOCK_EX | LOCK_NB)) { ftruncate($fp, 0); fwrite($fp, $databaseFileSotrage->getContent()); diff --git a/js/mage/adminhtml/product/composite/configure.js b/js/mage/adminhtml/product/composite/configure.js index 0308c5fbd9..80a4015cd1 100644 --- a/js/mage/adminhtml/product/composite/configure.js +++ b/js/mage/adminhtml/product/composite/configure.js @@ -506,23 +506,28 @@ ProductConfigure.prototype = { * @param method can be 'all' or 'current' */ clean: function(method) { + var listInfo = null; + var listTypes = null; + var removeConfirmed = function (listTypes) { + 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)); + }.bind(this); + switch (method) { case 'current': - var listInfo = this.listTypes[this.current.listType]; - var listTypes = [this.current.listType]; + listInfo = this.listTypes[this.current.listType]; + 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)); + removeConfirmed(listTypes); break; case 'window': this.blockFormFields.update(); @@ -531,12 +536,23 @@ ProductConfigure.prototype = { this.blockCancelBtn.show(); break; default: - this.current = $H({}); - this.blockConfirmed.update(); - this.blockFormFields.update(); - this.blockMsg.hide(); - this.blockMsgError.update(); - this.blockCancelBtn.show(); + // search in list types for its cleaning + if (this.listTypes[method]) { + listInfo = this.listTypes[method]; + listTypes = [method]; + if (listInfo.complexTypes) { + listTypes = listTypes.concat(listInfo.complexTypes); + } + removeConfirmed(listTypes); + // clean all + } else if (!method) { + this.current = $H({}); + this.blockConfirmed.update(); + this.blockFormFields.update(); + this.blockMsg.hide(); + this.blockMsgError.update(); + this.blockCancelBtn.show(); + } break; } this._getIFrameContent().body.innerHTML = ''; diff --git a/js/mage/adminhtml/sales.js b/js/mage/adminhtml/sales.js index edf1b626a1..4f4b02b2fe 100644 --- a/js/mage/adminhtml/sales.js +++ b/js/mage/adminhtml/sales.js @@ -554,6 +554,8 @@ AdminOrder.prototype = { } } this.productConfigureSubmit('product_to_add', area, fieldsPrepare, itemsFilter); + productConfigure.clean('quote_items'); + this.hideArea('search'); this.gridProducts = $H({}); }, @@ -704,7 +706,6 @@ AdminOrder.prototype = { */ productConfigureSubmit : function(listType, area, fieldsPrepare, itemsFilter) { // prepare loading areas and build url - this.hideArea('search'); area = this.prepareArea(area); this.loadingAreas = area; var url = this.loadBaseUrl + 'block/' + area + '?isAjax=true'; @@ -849,8 +850,8 @@ AdminOrder.prototype = { else { new Ajax.Request(url, {parameters:params,loaderArea: indicator}); } - if (typeof productConfigure != 'undefined') { - productConfigure.clean(); + if (typeof productConfigure != 'undefined' && area instanceof Array && area.indexOf('items' != -1)) { + productConfigure.clean('quote_items'); } }, diff --git a/lib/Varien/File/Transfer/Adapter/Http.php b/lib/Varien/File/Transfer/Adapter/Http.php index cec7052ff2..091127a386 100644 --- a/lib/Varien/File/Transfer/Adapter/Http.php +++ b/lib/Varien/File/Transfer/Adapter/Http.php @@ -121,7 +121,7 @@ public function send($options = null) * Internal method to detect the mime type of a file * * @param array $value File infos - * @return string Mimetype of given file + * @return string Mime type of given file */ protected function _detectMimeType($value) { @@ -133,17 +133,14 @@ protected function _detectMimeType($value) return null; } - if (empty($result) && (function_exists('mime_content_type') - && ini_get('mime_magic.magicfile'))) { - $result = mime_content_type($file); + $parts = explode('.', $file); + $extention = strtolower(array_pop($parts)); + if (isset($this->_mimeTypes[$extention])) { + $result = $this->_mimeTypes[$extention]; } - if (empty($result)) { - $parts = explode('.', $file); - $extention = strtolower(array_pop($parts)); - if (isset($this->_mimeTypes[$extention])) { - $result = $this->_mimeTypes[$extention]; - } + if (empty($result) && (function_exists('mime_content_type') && ini_get('mime_magic.magicfile'))) { + $result = mime_content_type($file); } if (empty($result)) { diff --git a/skin/adminhtml/default/default/images/xmlconnect/mobile_preview/sort_buttons/bg_button.png b/skin/adminhtml/default/default/images/xmlconnect/mobile_preview/sort_buttons/bg_button.png new file mode 100644 index 0000000000..eced68ab25 Binary files /dev/null and b/skin/adminhtml/default/default/images/xmlconnect/mobile_preview/sort_buttons/bg_button.png differ diff --git a/skin/adminhtml/default/default/images/xmlconnect/mobile_preview/sort_buttons/button_up.gif b/skin/adminhtml/default/default/images/xmlconnect/mobile_preview/sort_buttons/button_up.gif new file mode 100644 index 0000000000..9fb0c25548 Binary files /dev/null and b/skin/adminhtml/default/default/images/xmlconnect/mobile_preview/sort_buttons/button_up.gif differ diff --git a/skin/adminhtml/default/default/xmlconnect/mobile-catalog.css b/skin/adminhtml/default/default/xmlconnect/mobile-catalog.css index 44a1061e09..18602e891c 100644 --- a/skin/adminhtml/default/default/xmlconnect/mobile-catalog.css +++ b/skin/adminhtml/default/default/xmlconnect/mobile-catalog.css @@ -22,6 +22,14 @@ */ body { margin: 0; padding: 0 } +@font-face { + font-family: 'stars'; + src: url('fonts/stars-webfont.eot'); + src: local('O'), url('fonts/stars-webfont.woff') format('woff'), url('fonts/stars-webfont.ttf') format('truetype'), url('fonts/stars-webfont.svg#webfontyMStiDRV') format('svg'); + font-weight: normal; + font-style: normal; +} + .main-frame { background:url(../images/xmlconnect/mobile_preview/mm-frame.gif) 0 0 no-repeat; @@ -253,13 +261,72 @@ body { margin: 0; padding: 0 } .sort-buttons { text-align:center; - font:bold 11px/11px arial; + font:bold 11px/11px Helvetica, "Helvetica Neue", Verdana, sans-serif; padding:0 5px 0 0; width:234px; height:26px; margin-top:8px } +.buttons-holder +{ + float:left; + margin:5px 0 0 5px; + -moz-border-radius:5px; + -webkit-border-radius:5px; + border-radius:5px; + -moz-box-shadow:0 1px 1px #bbb; + -webkit-box-shadow:0 1px 1px #bbb; + box-shadow:0 1px 1px #bbb; +} + +.sort-block .button +{ + background:url(../images/xmlconnect/mobile_preview/sort_buttons/bg_button.png) no-repeat 0 0 #8c8c8c; + border:1px solid #606060; + display:inline; + float:left; + color:#fefefe; + font:bold 14px/16px Helvetica, "Helvetica Neue", Verdana, sans-serif; + padding:6px 9px 5px; + text-shadow:0 -1px 1px #222; + -moz-box-shadow:inset 0 1px 1px #777; + -webkit-box-shadow:inset 0 1px 1px #777; + box-shadow:inset 0 1px 1px #777; +} + +.sort-block .button-pos +{ + padding-right:2px; + text-shadow:0 -1px 1px #666; + -moz-border-radius:5px 0 0 5px; + -webkit-border-radius:5px 0 0 5px; + border-radius:5px 0 0 5px; +} + +.sort-block .button-name, +.sort-block .button-price +{ + padding:6px 19px 5px; +} + +.sort-block .button-name +{ + border-width:1px 0; +} + +.sort-block .button-price +{ + -moz-border-radius:0 5px 5px 0; + -webkit-border-radius:0 5px 5px 0; + border-radius:0 5px 5px 0; +} + +.sort-block .button img +{ + vertical-align:middle; +} + .active { color: #e9e9e9; @@ -376,18 +443,25 @@ body { margin: 0; padding: 0 } padding:5px 0; } -.item-rate img +.item-rate { + padding:4px 0 0; +} + +.item-rate .stars { - margin:0 !important; padding:0 !important; + font-family:stars; + vertical-align:middle; } -.item-rate span +.item-rate .star { - position: relative; - top: -2px; - left: 0px; - font: bold 12px arial; - color: #333; + vertical-align:top; +} + +.item-rate strong +{ + font-size:10px; + vertical-align:text-top; } .item-rate