diff --git a/app/Mage.php b/app/Mage.php index 6fb64b205c..fc2ffd8ff4 100644 --- a/app/Mage.php +++ b/app/Mage.php @@ -82,7 +82,7 @@ final class Mage { public static function getVersion() { - return '1.1.5'; + return '1.1.6'; } /** diff --git a/app/code/core/Mage/Adminhtml/Block/Catalog/Category/Tree.php b/app/code/core/Mage/Adminhtml/Block/Catalog/Category/Tree.php index 61e7c12946..e8fc5fbb69 100644 --- a/app/code/core/Mage/Adminhtml/Block/Catalog/Category/Tree.php +++ b/app/code/core/Mage/Adminhtml/Block/Catalog/Category/Tree.php @@ -188,8 +188,45 @@ public function getRootIds() return $ids; } - protected function _getNodeJson($node, $level=0) + /** + * Get JSON of array of categories, that are breadcrumbs for specified category path + * + * @param string $path + * @param string $javascriptVarName + * @return string + */ + public function getBreadcrumbsJavascript($path, $javascriptVarName) { + if (empty($path)) { + return ''; + } + $categories = Mage::getResourceSingleton('catalog/category_tree')->loadBreadcrumbsArray($path); + if (empty($categories)) { + return ''; + } + foreach ($categories as $key => $category) { + $categories[$key] = $this->_getNodeJson($category); + } + return + ''; + } + + /** + * Get JSON of a tree node or an associative array + * + * @param Varien_Data_Tree_Node|array $node + * @param int $level + * @return string + */ + protected function _getNodeJson($node, $level = 0) + { + // create a node from data array + if (is_array($node)) { + $node = new Varien_Data_Tree_Node($node, 'entity_id', new Varien_Data_Tree); + } + $item = array(); $item['text']= $this->htmlEscape($node->getName()); diff --git a/app/code/core/Mage/Adminhtml/Block/Customer/Online/Grid.php b/app/code/core/Mage/Adminhtml/Block/Customer/Online/Grid.php index 95294f69b3..f31e7f2a52 100644 --- a/app/code/core/Mage/Adminhtml/Block/Customer/Online/Grid.php +++ b/app/code/core/Mage/Adminhtml/Block/Customer/Online/Grid.php @@ -123,8 +123,8 @@ protected function _beforeToHtml() 'index'=>'type', 'type' => 'options', 'options' => array( - 'c' => Mage::helper('customer')->__('Customer'), - 'v' => Mage::helper('customer')->__('Visitor'), + Mage_Log_Model_Visitor::VISITOR_TYPE_CUSTOMER => Mage::helper('customer')->__('Customer'), + Mage_Log_Model_Visitor::VISITOR_TYPE_VISITOR => Mage::helper('customer')->__('Visitor'), ), 'renderer'=>'adminhtml/customer_online_grid_renderer_type', )); @@ -146,15 +146,4 @@ public function getRowUrl($row) { return ( intval($row->getCustomerId()) > 0 ) ? $this->getUrl('*/customer/edit', array('id' => $row->getCustomerId())) : ''; } - - protected function _addColumnFilterToCollection($column) - { - if($column->getId()=='type') { - $this->getCollection()->addFieldToFilter($column->getIndex(), $column->getFilter()->getValue()); - } else { - $this->getCollection()->addFieldToFilter($column->getIndex(), $column->getFilter()->getCondition()); - } - return $this; - } - } diff --git a/app/code/core/Mage/Adminhtml/Block/Extensions/Custom/Edit/Tab/Grid.php b/app/code/core/Mage/Adminhtml/Block/Extensions/Custom/Edit/Tab/Grid.php index aef3f3189a..bea3007649 100644 --- a/app/code/core/Mage/Adminhtml/Block/Extensions/Custom/Edit/Tab/Grid.php +++ b/app/code/core/Mage/Adminhtml/Block/Extensions/Custom/Edit/Tab/Grid.php @@ -31,9 +31,10 @@ * @package Mage_Adminhtml * @author Magento Core Team */ -class Mage_Adminhtml_Block_Extensions_Custom_Edit_Tab_Grid - extends Mage_Adminhtml_Block_Widget_Grid +class Mage_Adminhtml_Block_Extensions_Custom_Edit_Tab_Grid extends Mage_Adminhtml_Block_Widget_Grid { + protected $_defaultLimit = 200; + public function __construct() { parent::__construct(); @@ -68,9 +69,6 @@ public function getCurrentUrl($params=array()) public function getRowUrl($row) { - return $this->getUrl('*/*/load', array( - 'id' => $row->getFilenameId(), - )); + return $this->getUrl('*/*/load') . '?id=' . urlencode($row->getFilenameId()); } - } diff --git a/app/code/core/Mage/Adminhtml/Helper/Dashboard/Visitor.php b/app/code/core/Mage/Adminhtml/Helper/Dashboard/Visitor.php deleted file mode 100644 index 50d885585b..0000000000 --- a/app/code/core/Mage/Adminhtml/Helper/Dashboard/Visitor.php +++ /dev/null @@ -1,102 +0,0 @@ - - */ -class Mage_Adminhtml_Helper_Dashboard_Visitor extends Mage_Adminhtml_Helper_Dashboard_Abstract -{ - - protected $_onlineDataCache = null; - - protected function _initCollection() - { - $range = $this->_getRangeAndPeriod($this->getParam('range')); - $this->_collection = Mage::getResourceSingleton('log/visitor_collection'); - if($this->getParam('store')) { - $this->_collection = $this->_collection->addFieldToFilter('store_id', $this->getParam('store')); - } - $this->_collection->getAggregatedData($range['period'], $range['range'], $this->getParam('custom_from'), $this->getParam('custom_to')); - } - - protected function _getRangeAndPeriod($type) - { - switch ($type) { - case "24h": - $period = 24; - $range = 'hour'; - break; - case "7d": - $period = 7; - $range = 'day'; - break; - case "1m": - $period = 30; - $range = 'day'; - break; - case "2m": - $period = 60; - $range = 'day'; - break; - case "1y": - $period = 12; - $range = 'month'; - break; - default: - $range = 0; - $range = 'month'; - break; - } - - return array('range'=>$range, 'period'=>$period); - } - - protected function _initOnlineData() - { - $this->_onlineDataCache = array(); - $customersCollection = Mage::getResourceModel('log/visitor_collection')->useOnlineFilter()->addFieldToFilter('type', '1'); - $visitorsCollection = Mage::getResourceModel('log/visitor_collection')->useOnlineFilter()->addFieldToFilter('type', 'v'); - $this->_onlineDataCache['customers'] = $customersCollection->getSize(); - $this->_onlineDataCache['visitors'] = $visitorsCollection->getSize(); - $this->_onlineDataCache['total'] = $this->_onlineDataCache['customers'] + $this->_onlineDataCache['visitors']; - - } - - public function getOnlineData($part) - { - if(is_null($this->_onlineDataCache)) { - $this->_initOnlineData(); - } - - return isset($this->_onlineDataCache[$part]) ? $this->_onlineDataCache[$part] : null; - } - -} diff --git a/app/code/core/Mage/Adminhtml/Model/Extension.php b/app/code/core/Mage/Adminhtml/Model/Extension.php index 8bab8a7696..ac964c58c9 100644 --- a/app/code/core/Mage/Adminhtml/Model/Extension.php +++ b/app/code/core/Mage/Adminhtml/Model/Extension.php @@ -267,6 +267,10 @@ public function savePackage() $fileName = $this->getName(); } + if (!preg_match('/^[a-z0-9]+[a-z0-9\-\_\.]*(\/[a-z0-9]+[a-z0-9\-\_\.]*)*$/i', $fileName)) { + return false; + } + if (!$this->getPackageXml()) { $this->generatePackageXml(); } @@ -285,7 +289,17 @@ public function savePackage() $this->unsRoles(); $xml = Mage::helper('core')->assocToXml($this->getData()); - if (!@file_put_contents($dir.DS.$fileName.'.xml', $xml->asXML())) { + // prepare dir to save + $parts = explode('/', $fileName); + array_pop($parts); + $newDir = implode(DS, $parts); + if ((!empty($newDir)) && (!is_dir($dir . DS . $newDir))) { + if (!@mkdir($dir . DS . $newDir, 0777, true)) { + return false; + } + } + + if (!@file_put_contents($dir . DS . $fileName . '.xml', $xml->asXML())) { return false; } diff --git a/app/code/core/Mage/Adminhtml/Model/Extension/Collection.php b/app/code/core/Mage/Adminhtml/Model/Extension/Collection.php index 93d012b17e..24810e4e61 100644 --- a/app/code/core/Mage/Adminhtml/Model/Extension/Collection.php +++ b/app/code/core/Mage/Adminhtml/Model/Extension/Collection.php @@ -1,23 +1,105 @@ $_file, - 'filename_id' => $_file + $baseDir = Mage::getBaseDir('var') . DS . 'pear'; + $files = array(); + $this->_collectRecursive($baseDir, $files); + $result = array(); + foreach ($files as $file) { + $file = preg_replace(array('/^' . preg_quote($baseDir . DS, '/') . '/', '/\.(xml|ser)$/'), '', $file); + $result[] = array( + 'filename' => $file, + 'filename_id' => $file ); } + return $result; + } - return $_items; + /** + * Get package files from directory recursively + * + * @param string $dir + * @param array &$result + * @param bool $dirsFirst + */ + protected function _collectRecursive($dir, &$result, $dirsFirst = true) + { + $_result = glob($dir . DS . '*'); + if (!$dirsFirst) { + // collect all the stuff recursively + foreach ($_result as $item) { + if (is_dir($item) && preg_match(self::$allowDirs, basename($item))) { + $this->_collectRecursive($item, $result, $dirsFirst); + } + elseif (is_file($item) + && preg_match(self::$allowFiles, basename($item)) + && !preg_match(self::$disallowFiles, basename($item))) { + $result[] = $item; + } + } + } + else { + // collect directories first + $dirs = array(); + $files = array(); + foreach ($_result as $item) { + if (is_dir($item) && preg_match(self::$allowDirs, basename($item))) { + $dirs[] = $item; + } + elseif (is_file($item) + && preg_match(self::$allowFiles, basename($item)) + && !preg_match(self::$disallowFiles, basename($item))) { + $files[] = $item; + } + } + // search directories recursively + foreach ($dirs as $item) { + $this->_collectRecursive($item, $result, $dirsFirst); + } + // add files + foreach ($files as $item) { + $result[] = $item; + } + } } -} \ No newline at end of file +} diff --git a/app/code/core/Mage/Adminhtml/Model/System/Config/Source/Product/Options/Type.php b/app/code/core/Mage/Adminhtml/Model/System/Config/Source/Product/Options/Type.php index ef3d15d228..e181ede11f 100644 --- a/app/code/core/Mage/Adminhtml/Model/System/Config/Source/Product/Options/Type.php +++ b/app/code/core/Mage/Adminhtml/Model/System/Config/Source/Product/Options/Type.php @@ -33,40 +33,33 @@ */ class Mage_Adminhtml_Model_System_Config_Source_Product_Options_Type { + const PRODUCT_OPTIONS_GROUPS_PATH = 'global/catalog/product/options/custom/groups'; + public function toOptionArray() { - return array( - array('value' => '', 'label' => Mage::helper('adminhtml')->__('-- Please select --')), - array( - 'label' => Mage::helper('adminhtml')->__('Text'), - 'value' => array( - array('value' => 'field', 'label' => Mage::helper('adminhtml')->__('Field')), - array('value' => 'area', 'label' => Mage::helper('adminhtml')->__('Area')), - ) - ), -// array( -// 'label' => Mage::helper('adminhtml')->__('File'), -// 'value' => array( -// array('value' => 'file', 'label' => Mage::helper('adminhtml')->__('File')), -// ) -// ), - array( - 'label' => Mage::helper('adminhtml')->__('Select'), - 'value' => array( - array('value' => 'drop_down', 'label' => Mage::helper('adminhtml')->__('Drop-down')), - array('value' => 'radio', 'label' => Mage::helper('adminhtml')->__('Radio Buttons')), - array('value' => 'checkbox', 'label' => Mage::helper('adminhtml')->__('Checkbox')), - array('value' => 'multiple', 'label' => Mage::helper('adminhtml')->__('Multiple Select')), - ) - ), -// array( -// 'label' => Mage::helper('adminhtml')->__('Date'), -// 'value' => array( -// array('value' => 'date', 'label' => Mage::helper('adminhtml')->__('Date')), -// array('value' => 'date_time', 'label' => Mage::helper('adminhtml')->__('Date & Time')), -// array('value' => 'time', 'label' => Mage::helper('adminhtml')->__('Time')) -// ) -// ) + $groups = array( + array('value' => '', 'label' => Mage::helper('adminhtml')->__('-- Please select --')) ); + + foreach (Mage::getConfig()->getNode(self::PRODUCT_OPTIONS_GROUPS_PATH)->children() as $group) { + $types = array(); + $typesPath = self::PRODUCT_OPTIONS_GROUPS_PATH . '/' . $group->getName() . '/types'; + foreach (Mage::getConfig()->getNode($typesPath)->children() as $type) { + $labelPath = self::PRODUCT_OPTIONS_GROUPS_PATH . '/' . $group->getName() . '/types/' . $type->getName() . '/label'; + $types[] = array( + 'label' => (string) Mage::getConfig()->getNode($labelPath), + 'value' => $type->getName() + ); + } + + $labelPath = self::PRODUCT_OPTIONS_GROUPS_PATH . '/' . $group->getName() . '/label'; + + $groups[] = array( + 'label' => (string) Mage::getConfig()->getNode($labelPath), + 'value' => $types + ); + } + + return $groups; } } \ No newline at end of file diff --git a/app/code/core/Mage/Adminhtml/controllers/Catalog/CategoryController.php b/app/code/core/Mage/Adminhtml/controllers/Catalog/CategoryController.php index d5e10709ae..b6ae81fa7c 100644 --- a/app/code/core/Mage/Adminhtml/controllers/Catalog/CategoryController.php +++ b/app/code/core/Mage/Adminhtml/controllers/Catalog/CategoryController.php @@ -126,15 +126,34 @@ public function editAction() } if ($this->getRequest()->getQuery('isAjax')) { + // prepare breadcrumbs of selected category, if any + $breadcrumbsPath = $category->getPath(); + if (empty($breadcrumbsPath)) { + // but if no category, and it is deleted - prepare breadcrumbs from path, saved in session + $breadcrumbsPath = Mage::getSingleton('admin/session')->getDeletedPath(true); + if (!empty($breadcrumbsPath)) { + $breadcrumbsPath = explode('/', $breadcrumbsPath); + // no need to get parent breadcrumbs if deleting category level 1 + if (count($breadcrumbsPath) <= 1) { + $breadcrumbsPath = ''; + } + else { + array_pop($breadcrumbsPath); + $breadcrumbsPath = implode('/', $breadcrumbsPath); + } + } + } + Mage::getSingleton('admin/session') ->setLastViewedStore($this->getRequest()->getParam('store')); Mage::getSingleton('admin/session') ->setLastEditedCategory($category->getId()); $this->_initLayoutMessages('adminhtml/session'); $this->getResponse()->setBody( - $this->getLayout()->getMessagesBlock()->getGroupedHtml(). - $this->getLayout()->createBlock('adminhtml/catalog_category_edit_form') - ->toHtml() + $this->getLayout()->getMessagesBlock()->getGroupedHtml() + . $this->getLayout()->createBlock('adminhtml/catalog_category_edit_form')->toHtml() + . $this->getLayout()->getBlockSingleton('adminhtml/catalog_category_tree') + ->getBreadcrumbsJavascript($breadcrumbsPath, 'editingCategoryBreadcrumbs') ); return; } @@ -242,11 +261,8 @@ public function saveAction() return; } } - $name = $category->getName().'('.$category->getProductCount().')'; - $url = $this->getUrl('*/*/edit', array('_current'=> true, 'id'=>$category->getId())); - echo ''; - - // $this->getResponse()->setRedirect($this->getUrl('*/*/edit', array('_current'=> true, 'id'=>$category->getId()))); + $url = $this->getUrl('*/*/edit', array('_current' => true, 'id' => $category->getId())); + $this->getResponse()->setBody(''); } /** @@ -297,6 +313,8 @@ public function deleteAction() $category = Mage::getModel('catalog/category')->load($id); Mage::dispatchEvent('catalog_controller_category_delete', array('category'=>$category)); + Mage::getSingleton('admin/session')->setDeletedPath($category->getPath()); + $category->delete(); Mage::getSingleton('adminhtml/session')->addSuccess(Mage::helper('catalog')->__('Category deleted')); } diff --git a/app/code/core/Mage/Adminhtml/controllers/DashboardController.php b/app/code/core/Mage/Adminhtml/controllers/DashboardController.php index 6673a7db60..46781629a7 100644 --- a/app/code/core/Mage/Adminhtml/controllers/DashboardController.php +++ b/app/code/core/Mage/Adminhtml/controllers/DashboardController.php @@ -68,212 +68,6 @@ public function ajaxBlockAction() return; } -/** - public function configureAction() - { - $section = $this->getRequest()->getParam('section'); - $data = Mage::getSingleton('adminhtml/session')->getDashboardData(); - $data[$section] = $this->getRequest()->getPost(); - Mage::getSingleton('adminhtml/session')->setDashboardData($data); - - $this->_redirectReferer(); - } - - public function onlineAction() - { - $collection = Mage::getResourceSingleton('log/visitor_collection') - ->useOnlineFilter() - ->load(); - - foreach( $collection -> getItems() as $item ) { - $item->setLocation(long2ip($item->getRemoteAddr())) - ->addCustomerData($item); - - if( $item->getCustomerId() > 0 ) { - //print_r( $item ); - $item->setFullName( $item->getCustomerData()->getName() ); - - // Not needed yet... - // $adresses = $item->getCustomerData()->getAddressCollection()->getPrimaryAddresses(); - } else { - $item->setFullName('Guest'); - } - } - - $this->getResponse()->setBody( $collection->toXml() ); - } - - - public function visitorsAction() - { - $range = $this->getRequest()->getParam('range'); - - $start = strtotime($range['start']); - $end = strtotime($range['end']); - $period = $end - $start; - - $detailPeriod = 60*60; - - if( $period > 2*24*60*60 ) { - $detailPeriod = 24*60*60; - } - - if( $period > 28*24*60*60 ) { - $detailPeriod = 7*24*60*60; - } - - if( $period > 365*24*60*60 ) { - $detailPeriod = 30*24*60*60; - } - - $allData = new Varien_Object(); - $allData->setMinimum(date('Y/m/d H:i', $start )); - $allData->setMaximum(date('Y/m/d H:i', $end )); - - $logItem = new Varien_Object(); - - $logXML = ''; - - for($i = $start; $i < $end; $i += $detailPeriod) { - $visitors = rand( 1, 100000 ); - $customers = rand( 0, $visitors); - $logItem->addData(array( - 'time' => date('Y/m/d H:i', $i), - 'customers' => $customers, - 'visitors' => $visitors - )); - - $logXML.= $logItem->toXml(array(), 'item', false, true); - } - - $allData->setItems($logXML); - - $this->getResponse()->setBody($allData->toXml(array(),'dataSource',true,false)); - - /* - $collection = Mage::getResourceSingleton('log/visitor_collection') - ->getStatistics('d') - ->applyDateRange($range['start'], $range['end']) - ->load(); - - - $this->getResponse()->setBody($collection->toXml()); - * / - } - - public function visitorsLiveAction() - { - $minimum = time() - 12 * 60 * 60; - $maximum = time() + 15 * 60; - - $allData = new Varien_Object(); - $allData->setMinimum(date('Y/m/d H:i', $minimum )); - $allData->setMaximum(date('Y/m/d H:i', $maximum )); - - $logItem = new Varien_Object(); - - $logXML = ''; - - /* // Last 11 hours by hours - for($i = $minimum; $i < $maximum - ( 15*60 + 60*60 ); $i += 60*60) { - $visitors = rand( 1, 100000 ); - $customers = rand( 0, $visitors); - $logItem->addData(array( - 'time' => date('Y/m/d H:i', $i), - 'customers' => $customers, - 'visitors' => $visitors - )); - - $logXML.= $logItem->toXml(array(), 'item', false, true); - }* / - - // Last 12 hours by 5 minutes - for($i = $minimum; $i < time(); $i += 5*60) { - $visitors = rand( 1, 100000 ); - $customers = rand( 0, $visitors); - $logItem->addData(array( - 'time' => date('Y/m/d H:i', $i), - 'customers' => $customers, - 'visitors' => $visitors - )); - - $logXML.= $logItem->toXml(array(), 'item', false, true); - } - - $allData->setItems($logXML); - - $this->getResponse()->setBody($allData->toXml(array(),'dataSource',true,false)); - } - - public function visitorsReportAction() - { - // Not implemented yet - $this->getResponse()->setBody( 'Not implemented yet' ); - } - - public function visitorsLiveUpdateAction() - { - $minimum = time() - 12 * 60 * 60; - $maximum = time() + 15 * 60; - - $visitors = rand( 1, 100000 ); - $customers = rand( 0, $visitors); - - $updateData = new Varien_Object(); - $updateData->setMinimum(date('Y/m/d H:i', $minimum )); - $updateData->setMaximum(date('Y/m/d H:i', $maximum )); - $updateData->setTime(date('Y/m/d H:i', time() )); - $updateData->setCustomers($customers); - $updateData->setVisitors($visitors); - - $this->getResponse()->setBody($updateData->toXml(array(),'update',true,false)); - } - - public function quoteAction() - { - $quote = Mage::getModel('sales/quote') - ->load($this->getRequest()->getParam('quoteId',0)); - - - - $itemsFilter = new Varien_Filter_Object_Grid(); - $itemsFilter->addFilter(new Varien_Filter_Sprintf('%d'), 'qty'); - $itemsFilter->addFilter(Mage::app()->getStore()->getPriceFilter(), 'price'); - $itemsFilter->addFilter(Mage::app()->getStore()->getPriceFilter(), 'row_total'); - $cartItems = $itemsFilter->filter($quote->getItems()); - - $totalsFilter = new Varien_Filter_Array_Grid(); - $totalsFilter->addFilter(Mage::app()->getStore()->getPriceFilter(), 'value'); - $cartTotals = $totalsFilter->filter($quote->getTotals()); - - // Creating XML response. - // In future would be good if it will be in some collection. - $itemsXML = ""; - - $itemObject = new Varien_Object(); - $xmlObject = new Varien_Object(); - - foreach( $cartItems as $cartItem ) { - $itemObject->addData($cartItem); - $itemObject->setUrl($this->getUrl('catalog/product/view', array('id'=>$itemObject->getProductId()))); - $itemsXML.= $itemObject->toXml(array('price', 'qty', 'row_total', 'name', 'url'), "item", false, true); - } - - $xmlObject->setItems( $itemsXML ); - - $totalXML = ""; - $totalObject = new Varien_Object(); - - foreach( $cartTotals as $cartTotal ) { - $totalObject->addData( $cartTotal ); - $totalXML.= $totalObject->toXml(array('title','value'), 'total', false, true); - } - - $xmlObject->setTotals( $totalXML ); - $this->getResponse()->setBody( $xmlObject->toXml(array(), 'dataSource', true, false) ); - } -*/ - public function tunnelAction() { $httpClient = new Varien_Http_Client(); diff --git a/app/code/core/Mage/Adminhtml/controllers/Sales/Order/InvoiceController.php b/app/code/core/Mage/Adminhtml/controllers/Sales/Order/InvoiceController.php index 4426f8563f..ad819bc3f6 100644 --- a/app/code/core/Mage/Adminhtml/controllers/Sales/Order/InvoiceController.php +++ b/app/code/core/Mage/Adminhtml/controllers/Sales/Order/InvoiceController.php @@ -296,6 +296,8 @@ public function saveAction() $invoice->setEmailSent(true); } + $invoice->getOrder()->setIsInProcess(true); + $transactionSave = Mage::getModel('core/resource_transaction') ->addObject($invoice) ->addObject($invoice->getOrder()); diff --git a/app/code/core/Mage/Adminhtml/etc/config.xml b/app/code/core/Mage/Adminhtml/etc/config.xml index 8a3e17764c..72a190d85b 100644 --- a/app/code/core/Mage/Adminhtml/etc/config.xml +++ b/app/code/core/Mage/Adminhtml/etc/config.xml @@ -302,6 +302,10 @@ Sales Emails Section 65 + + PDF Print-outs + 66 + Checkout Section 70 diff --git a/app/code/core/Mage/Bundle/Model/Source/Option/Type.php b/app/code/core/Mage/Bundle/Model/Source/Option/Type.php index 21bc2f5d25..71716bd646 100644 --- a/app/code/core/Mage/Bundle/Model/Source/Option/Type.php +++ b/app/code/core/Mage/Bundle/Model/Source/Option/Type.php @@ -33,13 +33,20 @@ */ class Mage_Bundle_Model_Source_Option_Type { + const BUNDLE_OPTIONS_TYPES_PATH = 'global/catalog/product/options/bundle/types'; + public function toOptionArray() { - return array( - array('value' => 'select', 'label' => Mage::helper('bundle')->__('Drop-down')), - array('value' => 'radio', 'label' => Mage::helper('bundle')->__('Radio Buttons')), - array('value' => 'checkbox', 'label' => Mage::helper('bundle')->__('Checkbox')), - array('value' => 'multi', 'label' => Mage::helper('bundle')->__('Multiple Select')) - ); + $types = array(); + + foreach (Mage::getConfig()->getNode(self::BUNDLE_OPTIONS_TYPES_PATH)->children() as $type) { + $labelPath = self::BUNDLE_OPTIONS_TYPES_PATH . '/' . $type->getName() . '/label'; + $types[] = array( + 'label' => (string) Mage::getConfig()->getNode($labelPath), + 'value' => $type->getName() + ); + } + + return $types; } } \ No newline at end of file diff --git a/app/code/core/Mage/Bundle/etc/config.xml b/app/code/core/Mage/Bundle/etc/config.xml index 956141bde1..f64ba75823 100644 --- a/app/code/core/Mage/Bundle/etc/config.xml +++ b/app/code/core/Mage/Bundle/etc/config.xml @@ -91,6 +91,24 @@ bundle/catalogIndex_data_bundle + + + + + + + + + + + + + + + + diff --git a/app/code/core/Mage/Catalog/Model/Category.php b/app/code/core/Mage/Catalog/Model/Category.php index 9449c8688a..a7f1d60efe 100644 --- a/app/code/core/Mage/Catalog/Model/Category.php +++ b/app/code/core/Mage/Catalog/Model/Category.php @@ -357,7 +357,13 @@ private function _getAttribute($attributeCode) ->getAttribute($attributeCode); } - public function getAllChildren() + /** + * Get all children categories IDs + * + * @param boolean $asArray return resul as array instead of comma-separated list of IDs + * @return array|string + */ + public function getAllChildren($asArray = false) { $this->getTreeModelInstance()->load(); $children = $this->getTreeModelInstance()->getChildren($this->getId()); @@ -368,7 +374,11 @@ public function getAllChildren() } else { $children = $myId; } - return implode(',', $children); + if ($asArray) { + return $children; + } else { + return implode(',', $children); + } } public function getChildren() diff --git a/app/code/core/Mage/Catalog/Model/Product.php b/app/code/core/Mage/Catalog/Model/Product.php index 803cce1949..57210aa9f1 100644 --- a/app/code/core/Mage/Catalog/Model/Product.php +++ b/app/code/core/Mage/Catalog/Model/Product.php @@ -1243,6 +1243,18 @@ public function getAvailableInCategories() return $this->getData('_available_in_categories'); } + + /** + * Retrieve default attribute set id + * + * @return int + */ + public function getDefaultAttributeSetId() + { + return $this->getResource()->getEntityType()->getDefaultAttributeSetId(); + } + + /** * Deprecated since 1.1.5 */ @@ -1266,4 +1278,5 @@ public function getThumbnailUrl($width = 75, $height = 75) { return (string)Mage::helper('catalog/image')->init($this, 'thumbnail')->resize($width, $height); } + } \ No newline at end of file diff --git a/app/code/core/Mage/Catalog/Model/Resource/Eav/Mysql4/Category/Collection.php b/app/code/core/Mage/Catalog/Model/Resource/Eav/Mysql4/Category/Collection.php index b3bb93403a..bf9c3b2ebe 100644 --- a/app/code/core/Mage/Catalog/Model/Resource/Eav/Mysql4/Category/Collection.php +++ b/app/code/core/Mage/Catalog/Model/Resource/Eav/Mysql4/Category/Collection.php @@ -157,11 +157,24 @@ public function load($printQuery = false, $logQuery = false) * @return Mage_Catalog_Model_Resource_Eav_Mysql4_Category_Collection */ protected function _loadProductCount() + { + $this->loadProductCount($this->_items, true, true); + } + + /** + * Load product count for specified items + * + * @param array $items + * @param boolean $countRegular get product count for regular (non-anchor) categories + * @param boolean $countAnchor get product count for anchor categories + * @return Mage_Catalog_Model_Resource_Eav_Mysql4_Category_Collection + */ + public function loadProductCount($items, $countRegular = true, $countAnchor = true) { $anchor = array(); $regular = array(); - foreach ($this->_items as $item) { + foreach ($items as $item) { if ($item->getIsAnchor()) { $anchor[$item->getId()] = $item; } else { @@ -169,39 +182,43 @@ protected function _loadProductCount() } } - // Retrieve regular categories product counts - $regularIds = array_keys($regular); - if (!empty($regularIds)) { - $select = $this->_conn->select(); - $select->from( - array('main_table'=>$this->_productTable), - array('category_id', new Zend_Db_Expr('COUNT(main_table.product_id)')) - ) - ->where($this->_conn->quoteInto('main_table.category_id IN(?)', $regularIds)) - ->group('main_table.category_id'); - $counts = $this->_conn->fetchPairs($select); - foreach ($regular as $item) { - if (isset($counts[$item->getId()])) { - $item->setProductCount($counts[$item->getId()]); - } else { - $item->setProductCount(0); - } - } - } - - // Retrieve Anchor categories product counts - foreach ($anchor as $item) { - if ($allChildren = $item->getAllChildren()) { + if ($countRegular) { + // Retrieve regular categories product counts + $regularIds = array_keys($regular); + if (!empty($regularIds)) { $select = $this->_conn->select(); $select->from( array('main_table'=>$this->_productTable), - new Zend_Db_Expr('COUNT( DISTINCT main_table.product_id)') + array('category_id', new Zend_Db_Expr('COUNT(main_table.product_id)')) ) - ->where($this->_conn->quoteInto('main_table.category_id IN(?)', explode(',', $item->getAllChildren()))); + ->where($this->_conn->quoteInto('main_table.category_id IN(?)', $regularIds)) + ->group('main_table.category_id'); + $counts = $this->_conn->fetchPairs($select); + foreach ($regular as $item) { + if (isset($counts[$item->getId()])) { + $item->setProductCount($counts[$item->getId()]); + } else { + $item->setProductCount(0); + } + } + } + } - $item->setProductCount((int) $this->_conn->fetchOne($select)); - } else { - $item->setProductCount(0); + if ($countAnchor) { + // Retrieve Anchor categories product counts + foreach ($anchor as $item) { + if ($allChildren = $item->getAllChildren()) { + $select = $this->_conn->select(); + $select->from( + array('main_table'=>$this->_productTable), + new Zend_Db_Expr('COUNT( DISTINCT main_table.product_id)') + ) + ->where($this->_conn->quoteInto('main_table.category_id IN(?)', explode(',', $allChildren))); + + $item->setProductCount((int) $this->_conn->fetchOne($select)); + } else { + $item->setProductCount(0); + } } } return $this; diff --git a/app/code/core/Mage/Catalog/Model/Resource/Eav/Mysql4/Category/Tree.php b/app/code/core/Mage/Catalog/Model/Resource/Eav/Mysql4/Category/Tree.php index 855584b7b8..460a4a27ba 100644 --- a/app/code/core/Mage/Catalog/Model/Resource/Eav/Mysql4/Category/Tree.php +++ b/app/code/core/Mage/Catalog/Model/Resource/Eav/Mysql4/Category/Tree.php @@ -288,8 +288,7 @@ public function loadByIds($ids, $addCollectionData = true) foreach ($this->_conn->fetchAll($select) as $item) { $path = explode('/', $item['path']); $level = (int)$item['level']; - while ($level > 0) - { + while ($level > 0) { $path[count($path) - 1] = '%'; $where[sprintf("`level`=%d AND `path` LIKE '%s'", $level, implode('/', $path))] = true; array_pop($path); @@ -300,26 +299,7 @@ public function loadByIds($ids, $addCollectionData = true) // get all required records if ($addCollectionData) { - $select = $this->_getDefaultCollection($this->_orderField) - ->getSelect(); - // add attributes to select - foreach (array('name', 'url_key', 'is_active') as $attributeCode) { - $attribute = Mage::getResourceSingleton('catalog/category')->getAttribute($attributeCode); - $tableAs = "_$attributeCode"; - $select->joinLeft( - array($tableAs => $attribute->getBackend()->getTable()), - sprintf('`%1$s`.entity_id=e.entity_id AND `%1$s`.attribute_id=%2$d AND `%1$s`.entity_type_id=e.entity_type_id', - $tableAs, $attribute->getData('attribute_id') - ), - array($attributeCode => 'value') - ); - } - // count products qty - $select->joinLeft(array('_category_product' => Mage::getSingleton('core/resource')->getTableName('catalog/category_product')), - 'e.entity_id=_category_product.category_id', - array('product_count' => 'COUNT(_category_product.product_id)') - ) - ->group('e.entity_id'); + $select = $this->_createCollectionDataSelect(); } else { $select = clone $this->_select; @@ -332,8 +312,9 @@ public function loadByIds($ids, $addCollectionData = true) if (!$arrNodes) { return false; } + $this->_updateAnchorProductCount($arrNodes); $childrenItems = array(); - foreach ($arrNodes as $nodeInfo) { + foreach ($arrNodes as $key => $nodeInfo) { $pathToParent = explode('/', $nodeInfo[$this->_pathField]); array_pop($pathToParent); $pathToParent = implode('/', $pathToParent); @@ -344,4 +325,96 @@ public function loadByIds($ids, $addCollectionData = true) return $this; } + /** + * Load array of category parents + * + * @param string $path + * @param bool $addCollectionData + * @param bool $withRootNode + * @return array + */ + public function loadBreadcrumbsArray($path, $addCollectionData = true, $withRootNode = false) + { + $path = explode('/', $path); + if (!$withRootNode) { + array_shift($path); + } + $result = array(); + if (!empty($path)) { + if ($addCollectionData) { + $select = $this->_createCollectionDataSelect(false); + } + else { + $select = clone $this->_select; + } + $select->where(sprintf('e.entity_id IN (%s)', implode(', ', $path))) + ->order(new Zend_Db_Expr('LENGTH(e.path) ASC')); + $result = $this->_conn->fetchAll($select); + $this->_updateAnchorProductCount($result); + } + return $result; + } + + /** + * Replace products count with self products count, if category is non-anchor + * + * @param array $data + */ + protected function _updateAnchorProductCount(&$data) + { + foreach ($data as $key => $row) { + if (0 === (int)$row['is_anchor']) { + $data[$key]['product_count'] = $row['self_product_count']; + } + } + } + + /** + * Obtain select for categories with attributes. + * + * By default everything from entity table is selected + * + name, is_active and is_anchor + * + * Also the correct product_count is selected, depending on is the category anchor or not. + * + * @param bool $sorted + * @param array $optionalAttributes + * @return Zend_Db_Select + */ + protected function _createCollectionDataSelect($sorted = true, $optionalAttributes = array()) + { + $select = $this->_getDefaultCollection($sorted ? $this->_orderField : false) + ->getSelect(); + // add attributes to select + $attributes = array('name', 'is_active', 'is_anchor'); + if ($optionalAttributes) { + $attributes = array_unique(array_merge($attributes, $optionalAttributes)); + } + foreach ($attributes as $attributeCode) { + $attribute = Mage::getResourceSingleton('catalog/category')->getAttribute($attributeCode); + $tableAs = "_$attributeCode"; + $select->joinLeft( + array($tableAs => $attribute->getBackend()->getTable()), + sprintf('`%1$s`.entity_id=e.entity_id AND `%1$s`.attribute_id=%2$d AND `%1$s`.entity_type_id=e.entity_type_id AND `%1$s`.store_id=%3$d', + $tableAs, $attribute->getData('attribute_id'), Mage_Core_Model_App::ADMIN_STORE_ID + ), + array($attributeCode => 'value') + ); + } + + // count children products qty plus self products qty + $categoriesTable = Mage::getSingleton('core/resource')->getTableName('catalog/category'); + $categoriesProductsTable = Mage::getSingleton('core/resource')->getTableName('catalog/category_product'); + $select->joinLeft(array('_category_product' => $categoriesProductsTable), + 'e.entity_id=_category_product.category_id', + array( + 'self_product_count' => new Zend_Db_Expr('COUNT(_category_product.product_id)'), + 'product_count' => new Zend_Db_Expr('(SELECT COUNT(DISTINCT cp.product_id) FROM ' . $categoriesTable . ' ee + LEFT JOIN ' . $categoriesProductsTable . ' cp ON ee.entity_id=cp.category_id + WHERE ee.entity_id=e.entity_id OR ee.path like CONCAT(e.path, \'/%\'))' + ))) + ->group('e.entity_id'); + + return $select; + } } diff --git a/app/code/core/Mage/Catalog/etc/config.xml b/app/code/core/Mage/Catalog/etc/config.xml index 1261b5cd2f..31a18b2006 100644 --- a/app/code/core/Mage/Catalog/etc/config.xml +++ b/app/code/core/Mage/Catalog/etc/config.xml @@ -248,6 +248,40 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/code/core/Mage/CatalogIndex/Model/Mysql4/Data/Grouped.php b/app/code/core/Mage/CatalogIndex/Model/Mysql4/Data/Grouped.php index 0712d3292c..1b89d786a5 100644 --- a/app/code/core/Mage/CatalogIndex/Model/Mysql4/Data/Grouped.php +++ b/app/code/core/Mage/CatalogIndex/Model/Mysql4/Data/Grouped.php @@ -56,6 +56,7 @@ public function getMinimalPrice($products, $priceAttributes, $store) foreach ($groups as $group) { $resultMinimal = null; $resultTaxClassId = 0; + $taxClassId = 0; $customerGroup = $group->getId(); $storeObject = $stores->getItemById($store); diff --git a/app/code/core/Mage/Checkout/Model/Type/Onepage.php b/app/code/core/Mage/Checkout/Model/Type/Onepage.php index 5a894a077e..667f56cc7b 100644 --- a/app/code/core/Mage/Checkout/Model/Type/Onepage.php +++ b/app/code/core/Mage/Checkout/Model/Type/Onepage.php @@ -192,7 +192,9 @@ public function saveBilling($data, $customerAddressId) $this->getQuote()->setPasswordHash($customer->encryptPassword($address->getCustomerPassword())); } - $this->getQuote()->setCustomerDob(Mage::app()->getLocale()->date($address->getDob(), null, null, false)->toString('yyyy-MM-dd')); + if ($address->getDob()) { + $this->getQuote()->setCustomerDob(Mage::app()->getLocale()->date($address->getDob(), null, null, false)->toString('yyyy-MM-dd')); + } $this->getQuote()->collectTotals(); $this->getQuote()->save(); diff --git a/app/code/core/Mage/Core/sql/core_setup/mysql4-upgrade-0.8.10-0.8.11.php b/app/code/core/Mage/Core/sql/core_setup/mysql4-upgrade-0.8.10-0.8.11.php index eb2b6f8231..aa058a67dc 100644 --- a/app/code/core/Mage/Core/sql/core_setup/mysql4-upgrade-0.8.10-0.8.11.php +++ b/app/code/core/Mage/Core/sql/core_setup/mysql4-upgrade-0.8.10-0.8.11.php @@ -29,10 +29,11 @@ $installer->startSetup(); -$installer->run(" -ALTER TABLE `{$installer->getTable('design_change')}` DROP FOREIGN KEY `FK_DESIGN_CHANGE_STORE`; -ALTER TABLE `{$installer->getTable('design_change')}` - ADD CONSTRAINT `FK_DESIGN_CHANGE_STORE` FOREIGN KEY (`store_id`) REFERENCES `{$installer->getTable('core_store')}` (`store_id`) ON DELETE CASCADE ON UPDATE CASCADE; -"); +$installer->getConnection()->dropForeignKey($installer->getTable('design_change'), 'FK_DESIGN_CHANGE_STORE'); +$installer->getConnection()->addConstraint( + 'FK_DESIGN_CHANGE_STORE', + $installer->getTable('design_change'), 'store_id', + $installer->getTable('core_store'), 'store_id' +); -$installer->endSetup(); +$installer->endSetup(); \ No newline at end of file diff --git a/app/code/core/Mage/Directory/etc/config.xml b/app/code/core/Mage/Directory/etc/config.xml index f5ea175a5d..0123f4b5a6 100644 --- a/app/code/core/Mage/Directory/etc/config.xml +++ b/app/code/core/Mage/Directory/etc/config.xml @@ -28,7 +28,7 @@ - 0.8.1 + 0.8.2 diff --git a/app/code/core/Mage/Adminhtml/Helper/Dashboard/Product.php b/app/code/core/Mage/Directory/sql/directory_setup/mysql4-upgrade-0.8.1-0.8.2.php similarity index 55% rename from app/code/core/Mage/Adminhtml/Helper/Dashboard/Product.php rename to app/code/core/Mage/Directory/sql/directory_setup/mysql4-upgrade-0.8.1-0.8.2.php index 1bbc8b0ff7..5db208e2ce 100644 --- a/app/code/core/Mage/Adminhtml/Helper/Dashboard/Product.php +++ b/app/code/core/Mage/Directory/sql/directory_setup/mysql4-upgrade-0.8.1-0.8.2.php @@ -19,31 +19,23 @@ * needs please refer to http://www.magentocommerce.com for more information. * * @category Mage - * @package Mage_Adminhtml + * @package Mage_Directory * @copyright Copyright (c) 2008 Irubin Consulting Inc. DBA Varien (http://www.varien.com) * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ /** - * Adminhtml dashboard helper for products + * Directory upgrade - adding regions of France (#6068) * * @category Mage - * @package Mage_Adminhtml - * @author Magento Core Team + * @package Mage_Directory + * @author Magento Core Team */ -class Mage_Adminhtml_Helper_Dashboard_Product extends Mage_Adminhtml_Helper_Dashboard_Abstract -{ - - protected function _initCollection() - { - $this->_collection = array( - array('name'=>'Product 1', 'avarage'=>263, 'salary'=>3666), - array('name'=>'Product 2', 'avarage'=>263, 'salary'=>266), - array('name'=>'Product 3', 'avarage'=>263, 'salary'=>366), - array('name'=>'Product 4', 'avarage'=>203, 'salary'=>6866), - array('name'=>'Product 5', 'avarage'=>263, 'salary'=>566) - ); - } - -} - // Class Mage_Adminhtml_Helper_Dashboard_Product end \ No newline at end of file +$installer = $this; +/* @var $installer Mage_Core_Model_Resource_Setup */ +$installer->startSetup(); +$installer->run(" +REPLACE INTO `{$installer->getTable('directory_country_region_name')}` (`locale`, `region_id`, `name`) +SELECT 'en_US', `region_id`, `default_name` FROM `{$installer->getTable('directory_country_region')}` WHERE `country_id` = 'FR'; +"); +$installer->endSetup(); 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 2af1d5bd14..7bd53cefa4 100644 --- a/app/code/core/Mage/GoogleCheckout/Model/Api/Xml/Callback.php +++ b/app/code/core/Mage/GoogleCheckout/Model/Api/Xml/Callback.php @@ -152,6 +152,7 @@ protected function _responseMerchantCalculationCallback() if ($gRequestMethods = $this->getData('root/calculate/shipping/method')) { $carriers = array(); + $errors = array(); foreach (Mage::getStoreConfig('carriers') as $carrierCode=>$carrierConfig) { if (!isset($carrierConfig['title'])) { continue; @@ -161,6 +162,7 @@ protected function _responseMerchantCalculationCallback() $methodName = is_array($method) ? $method['name'] : $method; if ($title && $method && strpos($methodName, $title)===0) { $carriers[$carrierCode] = $title; + $errors[$title] = true; } } } @@ -169,7 +171,6 @@ protected function _responseMerchantCalculationCallback() ->collectRatesByAddress($address, array_keys($carriers)) ->getResult(); - $errors = array(); $rates = array(); $rateCodes = array(); foreach ($result->getAllRates() as $rate) { @@ -184,6 +185,7 @@ protected function _responseMerchantCalculationCallback() $rates[$k] = $price; $rateCodes[$k] = $rate->getCarrier() . '_' . $rate->getMethod(); + unset($errors[$rate->getCarrierTitle()]); } } diff --git a/app/code/core/Mage/Log/Model/Mysql4/Visitor/Collection.php b/app/code/core/Mage/Log/Model/Mysql4/Visitor/Collection.php index eb0c460849..7b96ae543d 100644 --- a/app/code/core/Mage/Log/Model/Mysql4/Visitor/Collection.php +++ b/app/code/core/Mage/Log/Model/Mysql4/Visitor/Collection.php @@ -258,17 +258,24 @@ protected function _getRangeByType($type_code) return $range; } - public function addFieldToFilter($fieldName, $fieldValue=null) + /** + * Filter by customer ID, as 'type' field does not exist + * + * @param string $fieldName + * @param array $condition + * @return Mage_Log_Model_Mysql4_Visitor_Collection + */ + public function addFieldToFilter($fieldName, $condition=null) { - if( $fieldName == 'type' ) { - if ($fieldValue == 'v') { - return parent::addFieldToFilter('customer_table.customer_id', array('null' => 1)); + if ($fieldName == 'type' && is_array($condition) && isset($condition['eq'])) { + $fieldName = 'customer_id'; + if ($condition['eq'] === Mage_Log_Model_Visitor::VISITOR_TYPE_VISITOR) { + $condition = array('null' => 1); } else { - return parent::addFieldToFilter('customer_table.customer_id', array('moreq' => 1)); + $condition = array('moreq' => 1); } - } else { - return parent::addFieldToFilter($this->_getFieldMap($fieldName), $fieldValue); } + return parent::addFieldToFilter($this->_getFieldMap($fieldName), $condition); } protected function _getFieldMap($fieldName) diff --git a/app/code/core/Mage/Log/Model/Visitor.php b/app/code/core/Mage/Log/Model/Visitor.php index 5d8527f3b9..ec34d8818e 100644 --- a/app/code/core/Mage/Log/Model/Visitor.php +++ b/app/code/core/Mage/Log/Model/Visitor.php @@ -28,6 +28,8 @@ class Mage_Log_Model_Visitor extends Mage_Core_Model_Abstract { const DEFAULT_ONLINE_MINUTES_INTERVAL = 15; + const VISITOR_TYPE_CUSTOMER = 'c'; + const VISITOR_TYPE_VISITOR = 'v'; protected function _construct() { diff --git a/app/code/core/Mage/Sales/Model/Order.php b/app/code/core/Mage/Sales/Model/Order.php index 8975564a7b..f02217adf4 100644 --- a/app/code/core/Mage/Sales/Model/Order.php +++ b/app/code/core/Mage/Sales/Model/Order.php @@ -578,7 +578,9 @@ public function sendNewOrderEmail() $copyTo = $this->_getEmails(self::XML_PATH_EMAIL_COPY_TO); $copyMethod = Mage::getStoreConfig(self::XML_PATH_EMAIL_COPY_METHOD, $this->getStoreId()); if ($copyTo && $copyMethod == 'bcc') { - $mailTemplate->addBcc($copyTo); + foreach ($copyTo as $email) { + $mailTemplate->addBcc($email); + } } if ($this->getCustomerIsGuest()) { @@ -666,7 +668,9 @@ public function sendOrderUpdateEmail($notifyCustomer=true, $comment='') 'email' => $this->getCustomerEmail() ); if ($copyTo && $copyMethod == 'bcc') { - $mailTemplate->addBcc($copyTo); + foreach ($copyTo as $email) { + $mailTemplate->addBcc($email); + } } } diff --git a/app/code/core/Mage/Sales/Model/Order/Creditmemo.php b/app/code/core/Mage/Sales/Model/Order/Creditmemo.php index 3d77445d76..f7f15ddef9 100644 --- a/app/code/core/Mage/Sales/Model/Order/Creditmemo.php +++ b/app/code/core/Mage/Sales/Model/Order/Creditmemo.php @@ -551,7 +551,9 @@ public function sendEmail($notifyCustomer=true, $comment='') 'email' => $order->getCustomerEmail() ); if ($copyTo && $copyMethod == 'bcc') { - $mailTemplate->addBcc($copyTo); + foreach ($copyTo as $email) { + $mailTemplate->addBcc($email); + } } } @@ -629,7 +631,9 @@ public function sendUpdateEmail($notifyCustomer=true, $comment='') 'email' => $order->getCustomerEmail() ); if ($copyTo && $copyMethod == 'bcc') { - $mailTemplate->addBcc($copyTo); + foreach ($copyTo as $email) { + $mailTemplate->addBcc($email); + } } } diff --git a/app/code/core/Mage/Sales/Model/Order/Invoice.php b/app/code/core/Mage/Sales/Model/Order/Invoice.php index b76993ee2c..0e8186c221 100644 --- a/app/code/core/Mage/Sales/Model/Order/Invoice.php +++ b/app/code/core/Mage/Sales/Model/Order/Invoice.php @@ -566,7 +566,9 @@ public function sendEmail($notifyCustomer=true, $comment='') 'email' => $order->getCustomerEmail() ); if ($copyTo && $copyMethod == 'bcc') { - $mailTemplate->addBcc($copyTo); + foreach ($copyTo as $email) { + $mailTemplate->addBcc($email); + } } } @@ -646,7 +648,9 @@ public function sendUpdateEmail($notifyCustomer=true, $comment='') 'email' => $order->getCustomerEmail() ); if ($copyTo && $copyMethod == 'bcc') { - $mailTemplate->addBcc($copyTo); + foreach ($copyTo as $email) { + $mailTemplate->addBcc($email); + } } } diff --git a/app/code/core/Mage/Sales/Model/Order/Pdf/Abstract.php b/app/code/core/Mage/Sales/Model/Order/Pdf/Abstract.php index c62260b218..e601376491 100644 --- a/app/code/core/Mage/Sales/Model/Order/Pdf/Abstract.php +++ b/app/code/core/Mage/Sales/Model/Order/Pdf/Abstract.php @@ -45,6 +45,10 @@ abstract class Mage_Sales_Model_Order_Pdf_Abstract extends Varien_Object */ protected $_renderers = array(); + const XML_PATH_SALES_PDF_INVOICE_PUT_ORDER_ID = 'sales_pdf/invoice/put_order_id'; + const XML_PATH_SALES_PDF_SHIPMENT_PUT_ORDER_ID = 'sales_pdf/shipment/put_order_id'; + const XML_PATH_SALES_PDF_CREDITMEMO_PUT_ORDER_ID = 'sales_pdf/creditmemo/put_order_id'; + abstract public function getPdf(); /** @@ -142,7 +146,7 @@ protected function insertAddress(&$page) //return $page; } - protected function insertOrder(&$page, $order) + protected function insertOrder(&$page, $order, $putOrderId = true) { $page->setFillColor(new Zend_Pdf_Color_GrayScale(0.5)); @@ -153,8 +157,11 @@ protected function insertOrder(&$page, $order) $this->_setFontRegular($page); - $page->drawText(Mage::helper('sales')->__('Order # ').$order->getRealOrderId(), 35, 770, 'UTF-8'); - $page->drawText(Mage::helper('sales')->__('Order Date: ') . date( 'D M j Y', strtotime( $order->getCreatedAt() ) ), 35, 760, 'UTF-8'); + if ($putOrderId) { + $page->drawText(Mage::helper('sales')->__('Order # ').$order->getRealOrderId(), 35, 770, 'UTF-8'); + } + //$page->drawText(Mage::helper('sales')->__('Order Date: ') . date( 'D M j Y', strtotime( $order->getCreatedAt() ) ), 35, 760, 'UTF-8'); + $page->drawText(Mage::helper('sales')->__('Order Date: ') . Mage::helper('core')->formatDate($order->getCreatedAt(), 'medium', false), 35, 760, 'UTF-8'); $page->setFillColor(new Zend_Pdf_Color_Rgb(0.93, 0.92, 0.92)); $page->setLineColor(new Zend_Pdf_Color_GrayScale(0.5)); @@ -266,7 +273,10 @@ protected function insertOrder(&$page, $order) $yShipments = $this->y; - $page->drawText(Mage::helper('sales')->__('(Total Shipping Charges %s)', $order->formatPriceTxt($order->getBaseShippingAmount())), 285, $yShipments-7, 'UTF-8'); + + $totalShippingChargesText = "(" . Mage::helper('sales')->__('Total Shipping Charges') . " " . $order->formatPriceTxt($order->getBaseShippingAmount()) . ")"; + + $page->drawText($totalShippingChargesText, 285, $yShipments-7, 'UTF-8'); $yShipments -=10; $tracks = $order->getTracksCollection(); if (count($tracks)) { diff --git a/app/code/core/Mage/Sales/Model/Order/Pdf/Creditmemo.php b/app/code/core/Mage/Sales/Model/Order/Pdf/Creditmemo.php index 3115fd72d0..795c8a995e 100644 --- a/app/code/core/Mage/Sales/Model/Order/Pdf/Creditmemo.php +++ b/app/code/core/Mage/Sales/Model/Order/Pdf/Creditmemo.php @@ -56,7 +56,7 @@ public function getPdf($creditmemos = array()) $this->insertAddress($page); /* Add head */ - $this->insertOrder($page, $order); + $this->insertOrder($page, $order, Mage::getStoreConfigFlag(self::XML_PATH_SALES_PDF_CREDITMEMO_PUT_ORDER_ID, $order->getStoreId())); $page->setFillColor(new Zend_Pdf_Color_GrayScale(1)); $this->_setFontRegular($page); diff --git a/app/code/core/Mage/Sales/Model/Order/Pdf/Invoice.php b/app/code/core/Mage/Sales/Model/Order/Pdf/Invoice.php index 205fcf55bc..42a92e4830 100644 --- a/app/code/core/Mage/Sales/Model/Order/Pdf/Invoice.php +++ b/app/code/core/Mage/Sales/Model/Order/Pdf/Invoice.php @@ -56,7 +56,7 @@ public function getPdf($invoices = array()) $this->insertAddress($page); /* Add head */ - $this->insertOrder($page, $order); + $this->insertOrder($page, $order, Mage::getStoreConfigFlag(self::XML_PATH_SALES_PDF_INVOICE_PUT_ORDER_ID, $order->getStoreId())); $page->setFillColor(new Zend_Pdf_Color_GrayScale(1)); diff --git a/app/code/core/Mage/Sales/Model/Order/Pdf/Shipment.php b/app/code/core/Mage/Sales/Model/Order/Pdf/Shipment.php index 454aed5511..041edfff41 100644 --- a/app/code/core/Mage/Sales/Model/Order/Pdf/Shipment.php +++ b/app/code/core/Mage/Sales/Model/Order/Pdf/Shipment.php @@ -55,7 +55,7 @@ public function getPdf($shipments = array()) $this->insertAddress($page); /* Add head */ - $this->insertOrder($page, $order); + $this->insertOrder($page, $order, Mage::getStoreConfigFlag(self::XML_PATH_SALES_PDF_SHIPMENT_PUT_ORDER_ID, $order->getStoreId())); $page->setFillColor(new Zend_Pdf_Color_GrayScale(1)); $this->_setFontRegular($page); diff --git a/app/code/core/Mage/Sales/Model/Order/Shipment.php b/app/code/core/Mage/Sales/Model/Order/Shipment.php index ec9c6dd353..901b6bc0fb 100644 --- a/app/code/core/Mage/Sales/Model/Order/Shipment.php +++ b/app/code/core/Mage/Sales/Model/Order/Shipment.php @@ -326,7 +326,9 @@ public function sendEmail($notifyCustomer=true, $comment='') 'email' => $order->getCustomerEmail() ); if ($copyTo && $copyMethod == 'bcc') { - $mailTemplate->addBcc($copyTo); + foreach ($copyTo as $email) { + $mailTemplate->addBcc($email); + } } } @@ -404,7 +406,9 @@ public function sendUpdateEmail($notifyCustomer = true, $comment='') 'email' => $order->getCustomerEmail() ); if ($copyTo && $copyMethod == 'bcc') { - $mailTemplate->addBcc($copyTo); + foreach ($copyTo as $email) { + $mailTemplate->addBcc($email); + } } } diff --git a/app/code/core/Mage/Sales/etc/config.xml b/app/code/core/Mage/Sales/etc/config.xml index e95fa299da..a8f076349d 100644 --- a/app/code/core/Mage/Sales/etc/config.xml +++ b/app/code/core/Mage/Sales/etc/config.xml @@ -844,6 +844,17 @@ bcc + + + 1 + + + 1 + + + 1 + + diff --git a/app/code/core/Mage/Sales/etc/system.xml b/app/code/core/Mage/Sales/etc/system.xml index 22c4df5754..c01e610e39 100644 --- a/app/code/core/Mage/Sales/etc/system.xml +++ b/app/code/core/Mage/Sales/etc/system.xml @@ -681,5 +681,73 @@ + + + sales + text + 302 + 1 + 1 + 1 + + + + text + 1 + 10 + 1 + 1 + + + + select + adminhtml/system_config_source_yesno + 1 + 1 + 1 + 1 + + + + + + text + 20 + 1 + 1 + 1 + + + + select + adminhtml/system_config_source_yesno + 1 + 1 + 1 + 1 + + + + + + text + 30 + 1 + 1 + 1 + + + + select + adminhtml/system_config_source_yesno + 1 + 1 + 1 + 1 + + + + + \ No newline at end of file diff --git a/app/design/adminhtml/default/default/template/catalog/category/edit.phtml b/app/design/adminhtml/default/default/template/catalog/category/edit.phtml index bc189caf71..fcc367f3b8 100644 --- a/app/design/adminhtml/default/default/template/catalog/category/edit.phtml +++ b/app/design/adminhtml/default/default/template/catalog/category/edit.phtml @@ -70,7 +70,7 @@ parameters: params || {}, method: 'post', loaderArea: categoryContainer, - onComplete: refreshTree?refreshTreeArea.bind(this):false, + onComplete: refreshTree ? refreshTreeArea.bind(this) : false, evalScripts: true } ); @@ -78,54 +78,46 @@ function refreshTreeArea(transport) { - if (tree && tree.addNodeTo) { - var parent = tree.getNodeById(tree.currentNodeId); - var parameters = { - text: $('_generalname').value, - draggable: tree.rootVisible, - allowDrop: tree.rootVisible, - id: $('_generalid').value, - path: $('_generalpath').value, - expanded: false, - store_id: tree.storeId, - category_id: $('_generalid').value - }; + if (tree && editingCategoryBreadcrumbs) { + // category deleted - delete its node + if (tree.nodeForDelete) { + var parentNode = tree.getNodeById(tree.nodeForDelete).parentNode; + parentNode.removeChild(tree.getNodeById(tree.nodeForDelete)); + tree.nodeForDelete = false; + tree.currentNodeId = false; + } + // category created - add its node + else if (tree.addNodeTo) { + var parent = tree.getNodeById(tree.currentNodeId); + var node = new Ext.tree.AsyncTreeNode(editingCategoryBreadcrumbs[editingCategoryBreadcrumbs.length - 1]); + node.loaded = true; + tree.addNodeTo = false; + tree.currentNodeId = node.id; + parent.appendChild(node); - var node = new Ext.tree.AsyncTreeNode(parameters); - node.loaded = true; - tree.addNodeTo = false; - tree.currentNodeId = node.id; - parent.appendChild(node); + if (parent.expanded) { + tree.selectCurrentNode(); + } else { + var timer; + parent.expand(); + var f = function(){ + if(parent.expanded){ // done expanding + clearInterval(timer); + tree.selectCurrentNode(); + } + }; + timer = setInterval(f, 200); + } + // tree.selectCurrentNode(); + } - if (parent.expanded) { - tree.selectCurrentNode(); - } else { - var timer; - parent.expand(); - var f = function(){ - if(parent.expanded){ // done expanding - clearInterval(timer); - tree.selectCurrentNode(); - } - }; - timer = setInterval(f, 200); - return; + // update all affected categories nodes names + for (var i = 0; i < editingCategoryBreadcrumbs.length; i++) { + var node = tree.getNodeById(editingCategoryBreadcrumbs[i].id); + if (node) { + node.setText(editingCategoryBreadcrumbs[i].text); + } } -// tree.selectCurrentNode(); - } - else if (tree && tree.nodeForDelete) { - var parentNode = tree.getNodeById(tree.nodeForDelete).parentNode; - parentNode.removeChild(tree.getNodeById(tree.nodeForDelete)); - tree.nodeForDelete = false; - tree.currentNodeId = false; - } - } - - function updateNodeName(name) - { - if (tree && !tree.addNodeTo) { - var currentNode = tree.getNodeById(tree.currentNodeId); - currentNode.setText(name); } }