diff --git a/CHANGELOG.markdown b/CHANGELOG.markdown index 0787fcbd61ff436ec5d1ae225ae265d4e9a64dd8..3e8af1f31ff6d32884f74c82d80f942462973a19 100644 --- a/CHANGELOG.markdown +++ b/CHANGELOG.markdown @@ -1,3 +1,24 @@ +2.0.0.0-dev34 +============= +* Test Framework: + * Created `CodingStandard_ToolInterface` - new interface for coding standard static tests. Refactored `CodeSniffer` class as an implementation of the interface + * Fixed DB isolation in integration tests after themes refactoring + * Minor test fixes +* Changes in product creation process + * Added ability to change product type "on the fly" depending on selected options + * Added ability of new category creation on "General" tab + * Moved "Associated Products" tab contents to collapsible block on "General" tab for configurable products + * Visual enhancement made for base image and Virtual/Downloadable checkbox + * Refactored implementation of associated products in backend (admin) to make them configurable through grid layout, rather than hard-coded. + * Enhanced product variation matrix for configurable products + * Changed "Apply To" feature in product attributes management due to changes in product creation process +* Fixed XSS vulnerabilities in `Mage_Wishlist_IndexController`, `Mage_Adminhtml_Block_Review_Edit_Form`, `Mage_Catalog_Product_CompareController` +* Bug fixes + * Fixed error on `Catalog -> Google Content -> Manage Items page` + * Fixed bug with "Update Attributes" mass action for products on backend caused by setting incorrect inheritance of `Mage_Adminhtml_Helper_Catalog_Product_Edit_Action_Attribute` + * Added additional validation of "quantity" field to fix issues with inventory during product saving + * Added additional validation into `EAV` models to forbid creation of two products with the same unique multi-select attribute + 2.0.0.0-dev33 ============= * Improved Themes functionality to meet the following requirements: diff --git a/app/Mage.php b/app/Mage.php index d9a447d81eb4fbc3cf94849c82d891cdc56f036c..8dc32ae5cd05a835b0d7d941fc4e2ab92f85e50e 100644 --- a/app/Mage.php +++ b/app/Mage.php @@ -153,7 +153,7 @@ final class Mage { $i = self::getVersionInfo(); return trim("{$i['major']}.{$i['minor']}.{$i['revision']}" . ($i['patch'] != '' ? ".{$i['patch']}" : "") - . "-{$i['stability']}{$i['number']}", '.-'); + . "-{$i['stability']}{$i['number']}", '.-'); } /** @@ -170,7 +170,7 @@ final class Mage 'revision' => '0', 'patch' => '0', 'stability' => 'dev', - 'number' => '33', + 'number' => '34', ); } @@ -280,7 +280,7 @@ final class Mage } if ('' === $appRoot) { - // automagically find application root by dirname of Mage.php + // automatically find application root by dirname of Mage.php $appRoot = dirname(__FILE__); } @@ -896,6 +896,7 @@ final class Mage * Display exception * * @param Exception $e + * @param string $extra */ public static function printException(Exception $e, $extra = '') { 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 967784f6c3afbcda277c3e60f34a64cdb705ebdb..66c56b61f5d6e2fea9821ce92283d10613678de7 100644 --- a/app/code/core/Mage/Adminhtml/Block/Catalog/Category/Tree.php +++ b/app/code/core/Mage/Adminhtml/Block/Catalog/Category/Tree.php @@ -34,6 +34,7 @@ */ class Mage_Adminhtml_Block_Catalog_Category_Tree extends Mage_Adminhtml_Block_Catalog_Category_Abstract { + const XML_PATH_SUGGESTED_CATEGORIES_LIMIT = 'global/catalog/suggested_categories/limit'; protected $_withProductCount; @@ -119,7 +120,9 @@ class Mage_Adminhtml_Block_Catalog_Category_Tree extends Mage_Adminhtml_Block_Ca $matchingNamesCollection = clone $collection; $matchingNamesCollection->addAttributeToFilter('name', array('like' => "%{$namePart}%")) + ->addAttributeToFilter('entity_id', array('neq' => Mage_Catalog_Model_Category::TREE_ROOT_ID)) ->addAttributeToSelect('path') + ->setPageSize((string)Mage::getConfig()->getNode(self::XML_PATH_SUGGESTED_CATEGORIES_LIMIT)) ->setStoreId($storeId); $shownCategoriesIds = array(); diff --git a/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Attribute/Edit/Tab/Main.php b/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Attribute/Edit/Tab/Main.php index 0ef65045f43aff0f7fb37218ff2e894ce075cc64..79f7ac6589204f87478c82ac2300f60d1ac6faea 100644 --- a/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Attribute/Edit/Tab/Main.php +++ b/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Attribute/Edit/Tab/Main.php @@ -114,7 +114,8 @@ class Mage_Adminhtml_Block_Catalog_Product_Attribute_Edit_Tab_Main extends Mage_ 'all' => Mage::helper('Mage_Catalog_Helper_Data')->__('All Product Types'), 'custom' => Mage::helper('Mage_Catalog_Helper_Data')->__('Selected Product Types') ), - 'required' => true + 'required' => true, + 'disabled' => !$attributeObject->getIsUserDefined() && $attributeObject->getId(), ), 'frontend_class'); $fieldset->addField('is_configurable', 'select', array( diff --git a/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit.php b/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit.php index 278a21bcd9fdc8e56f2f8e360fec0e74d75d9e4a..2c3c1ac799dcbc2c0a0cea374cfc700cf1ceaa50 100644 --- a/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit.php +++ b/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit.php @@ -217,11 +217,9 @@ class Mage_Adminhtml_Block_Catalog_Product_Edit extends Mage_Adminhtml_Block_Wid public function getHeader() { - $header = ''; if ($this->getProduct()->getId()) { $header = $this->escapeHtml($this->getProduct()->getName()); - } - else { + } else { $header = Mage::helper('Mage_Catalog_Helper_Data')->__('New Product'); } if ($setName = $this->getAttributeSetName()) { @@ -277,4 +275,37 @@ class Mage_Adminhtml_Block_Catalog_Product_Edit extends Mage_Adminhtml_Block_Wid { return $this->helper('Mage_Catalog_Helper_Product')->getAttributesAllowedForAutogeneration(); } + + /** + * Get data for JS (product type transition) + * + * @return string + */ + public function getTypeSwitcherData() + { + return Mage::helper('Mage_Core_Helper_Data')->jsonEncode(array( + 'tab_id' => 'product_info_tabs_downloadable_items', + 'is_virtual_id' => Mage_Adminhtml_Block_Catalog_Product_Helper_Form_Weight_Renderer::VIRTUAL_FIELD_HTML_ID, + 'weight_id' => 'weight', + 'current_type' => $this->getProduct()->getTypeId(), + 'attributes' => $this->_getAttributes(), + )); + } + + /** + * Get formed array with attribute codes and Apply To property + * + * @return array + */ + protected function _getAttributes() + { + /** @var $product Mage_Catalog_Model_Product */ + $product = $this->getProduct(); + $attributes = array(); + + foreach ($product->getAttributes() as $key => $attribute) { + $attributes[$key] = $attribute->getApplyTo(); + } + return $attributes; + } } diff --git a/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/AttributeSet.php b/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/AttributeSet.php index 00c2bc0e7ab037dffcfb0c6eaf5268a7d4892b30..b3933b9dc968e34d9ee0bc9309ea35e030e11640 100644 --- a/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/AttributeSet.php +++ b/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/AttributeSet.php @@ -31,7 +31,7 @@ * @package Mage_Adminhtml * @author Magento Core Team <core@magentocommerce.com> */ -class Mage_Adminhtml_Block_Catalog_Product_Edit_AttributeSet extends Mage_Adminhtml_Block_Widget_Form +class Mage_Adminhtml_Block_Catalog_Product_Edit_AttributeSet extends Mage_Backend_Block_Widget_Form { protected function _prepareForm() { @@ -54,6 +54,14 @@ class Mage_Adminhtml_Block_Catalog_Product_Edit_AttributeSet extends Mage_Adminh ->toOptionArray() )); + $fieldset->addField( + 'type_id', + 'hidden', + array( + 'name' => 'type_id', + 'value' => Mage::registry('product')->getTypeId(), + ) + ); $this->setForm($form); } } diff --git a/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/NewCategory.php b/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/NewCategory.php new file mode 100644 index 0000000000000000000000000000000000000000..49a7f22dc77e47ec13f125b0ac8a4bf7dc62e21e --- /dev/null +++ b/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/NewCategory.php @@ -0,0 +1,85 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @category Mage + * @package Mage_Adminhtml + * @copyright Copyright (c) 2012 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +/** + * New category creation form + * + * @category Mage + * @package Mage_Adminhtml + * @author Magento Core Team <core@magentocommerce.com> + */ +class Mage_Adminhtml_Block_Catalog_Product_Edit_NewCategory extends Mage_Backend_Block_Widget_Form +{ + /** + * Form preparation + */ + protected function _prepareForm() + { + $form = new Varien_Data_Form(); + + $form->addField('new_category_messages', 'note', array()); + + $fieldset = $form->addFieldset('new_category_form', array()); + + $fieldset->addField('new_category_name', 'text', array( + 'label' => Mage::helper('Mage_Catalog_Helper_Data')->__('Category Name'), + 'title' => Mage::helper('Mage_Catalog_Helper_Data')->__('Category Name'), + 'required' => true, + )); + + $fieldset->addField('new_category_parent', 'text', array( + 'label' => Mage::helper('Mage_Catalog_Helper_Data')->__('Parent Category'), + 'title' => Mage::helper('Mage_Catalog_Helper_Data')->__('Parent Category'), + 'autocomplete' => 'off', + 'required' => true, + 'class' => 'validate-parent-category', + )); + + $fieldset->addField('new_category_parent_id', 'hidden', array()); + + $this->setForm($form); + } + + /** + * Category save action URL + * + * @return string + */ + public function getSaveCategoryUrl() + { + return $this->getUrl('*/catalog_category/save'); + } + + /** + * Category suggestion action URL + * + * @return string + */ + public function getSuggestCategoryUrl() + { + return $this->getUrl('*/catalog_category/suggestCategories'); + } +} diff --git a/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/Tab/Super/Config.php b/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/Tab/Super/Config.php index a0169cbdfe26d9fdbd03979ce948b6b79b0ddcdd..3a4d31d9799c5fc41b5e2340e1e18ac1f3fafeb5 100644 --- a/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/Tab/Super/Config.php +++ b/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/Tab/Super/Config.php @@ -82,6 +82,16 @@ class Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Super_Config extends Mage_Ad return (bool) $this->_getProduct()->getAttributesConfigurationReadonly(); } + /** + * Get configurable product type + * + * @return Mage_Catalog_Model_Product_Type_Configurable + */ + protected function _getProductType() + { + return Mage::getModel('Mage_Catalog_Model_Product_Type_Configurable'); + } + /** * Check whether prices of configurable products can be editable * @@ -100,11 +110,6 @@ class Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Super_Config extends Mage_Ad */ protected function _prepareLayout() { - $this->setChild('grid', - $this->getLayout()->createBlock('Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Super_Config_Grid', - 'admin.product.edit.tab.super.config.grid') - ); - $this->addChild('create_empty', 'Mage_Adminhtml_Block_Widget_Button', array( 'label' => Mage::helper('Mage_Catalog_Helper_Data')->__('Create Empty'), 'class' => 'add', @@ -139,32 +144,26 @@ class Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Super_Config extends Mage_Ad } /** - * Retrieve attributes data in JSON format + * Retrieve attributes data * - * @return string + * @return array */ - public function getAttributesJson() + public function getAttributes() { - $attributes = $this->_getProduct()->getTypeInstance() - ->getConfigurableAttributesAsArray($this->_getProduct()); - if(!$attributes) { - return '[]'; - } else { - // Hide price if needed - foreach ($attributes as &$attribute) { - if (isset($attribute['values']) && is_array($attribute['values'])) { - foreach ($attribute['values'] as &$attributeValue) { - if (!$this->getCanReadPrice()) { - $attributeValue['pricing_value'] = ''; - $attributeValue['is_percent'] = 0; - } - $attributeValue['can_edit_price'] = $this->getCanEditPrice(); - $attributeValue['can_read_price'] = $this->getCanReadPrice(); + $attributes = (array)$this->_getProductType()->getConfigurableAttributesAsArray($this->_getProduct()); + foreach ($attributes as &$attribute) { + if (isset($attribute['values']) && is_array($attribute['values'])) { + foreach ($attribute['values'] as &$attributeValue) { + if (!$this->getCanReadPrice()) { + $attributeValue['pricing_value'] = ''; + $attributeValue['is_percent'] = 0; } + $attributeValue['can_edit_price'] = $this->getCanEditPrice(); + $attributeValue['can_read_price'] = $this->getCanReadPrice(); } } } - return Mage::helper('Mage_Core_Helper_Data')->jsonEncode($attributes); + return $attributes; } /** @@ -174,7 +173,7 @@ class Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Super_Config extends Mage_Ad */ public function getLinksJson() { - $products = $this->_getProduct()->getTypeInstance() + $products = $this->_getProductType() ->getUsedProducts($this->_getProduct()); if(!$products) { return '{}'; @@ -194,7 +193,7 @@ class Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Super_Config extends Mage_Ad */ public function getConfigurableSettings($product) { $data = array(); - $attributes = $this->_getProduct()->getTypeInstance() + $attributes = $this->_getProductType() ->getUsedProductAttributes($this->_getProduct()); foreach ($attributes as $attribute) { $data[] = array( @@ -296,17 +295,6 @@ class Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Super_Config extends Mage_Ad return implode(',', $attributesIds); } - /** - * Escape JavaScript string - * - * @param string $string - * @return string - */ - public function escapeJs($string) - { - return addcslashes($string, "'\r\n\\"); - } - /** * Retrieve Tab label * @@ -365,8 +353,55 @@ class Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Super_Config extends Mage_Ad */ public function getSelectedAttributes() { - return array_filter( - $this->_getProduct()->getTypeInstance()->getUsedProductAttributes($this->_getProduct()) - ); + return $this->_getProduct()->isConfigurable() + ? array_filter($this->_getProductType()->getUsedProductAttributes($this->_getProduct())) + : array(); + } + + /** + * Retrieve all possible attribute values combinations + * + * @return array + */ + public function getVariations() + { + $attributesCount = 0; + $variationalAttributes = array(); + $usedProductAttributes = $this->getSelectedAttributes(); + foreach ($usedProductAttributes as $attribute) { + /** @var $attribute Mage_Catalog_Model_Resource_Eav_Attribute */ + $variationalAttributes[] = array( + 'id' => $attribute->getId(), + 'values' => $attribute->getSource()->getAllOptions(false), + ); + $attributesCount++; + } + + $variations = array(); + $currentVariation = array_fill(0, $attributesCount, 0); + $variationalAttributes = array_reverse($variationalAttributes); + $lastAttribute = $attributesCount - 1; + do { + for ($attributeIndex = 0; $attributeIndex < $attributesCount - 1; ++$attributeIndex) { + if ($currentVariation[$attributeIndex] >= count($variationalAttributes[$attributeIndex]['values'])) { + $currentVariation[$attributeIndex] = 0; + ++$currentVariation[$attributeIndex + 1]; + } + } + if ($currentVariation[$lastAttribute] >= count($variationalAttributes[$lastAttribute]['values'])) { + break; + } + + $filledVariation = array(); + for ($attributeIndex = $attributesCount; $attributeIndex--;) { + $currentAttribute = $variationalAttributes[$attributeIndex]; + $filledVariation[$currentAttribute['id']] = + $currentAttribute['values'][$currentVariation[$attributeIndex]]; + } + + $variations[] = $filledVariation; + $currentVariation[0]++; + } while (1); + return $variations; } } diff --git a/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/Tab/Super/Config/Grid.php b/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/Tab/Super/Config/Grid.php deleted file mode 100644 index b8a76ed7e5855550dda61ead7c768e58dcd2a72d..0000000000000000000000000000000000000000 --- a/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/Tab/Super/Config/Grid.php +++ /dev/null @@ -1,312 +0,0 @@ -<?php -/** - * Magento - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://opensource.org/licenses/osl-3.0.php - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@magentocommerce.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade Magento to newer - * versions in the future. If you wish to customize Magento for your - * needs please refer to http://www.magentocommerce.com for more information. - * - * @category Mage - * @package Mage_Adminhtml - * @copyright Copyright (c) 2012 X.commerce, Inc. (http://www.magentocommerce.com) - * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) - */ - -/** - * Adminhtml super product links grid - * - * @category Mage - * @package Mage_Adminhtml - * @author Magento Core Team <core@magentocommerce.com> - */ -class Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Super_Config_Grid extends Mage_Adminhtml_Block_Widget_Grid -{ - - protected function _construct() - { - parent::_construct(); - $this->setUseAjax(true); - $this->setId('super_product_links'); - - if ($this->_getProduct() && $this->_getProduct()->getId()) { - $this->setDefaultFilter(array('in_products'=>1)); - } - } - - /** - * Retrieve currently edited product object - * - * @return Mage_Catalog_Model_Product - */ - protected function _getProduct() - { - return Mage::registry('current_product'); - } - - protected function _addColumnFilterToCollection($column) - { - // Set custom filter for in product flag - if ($column->getId() == 'in_products') { - $productIds = $this->_getSelectedProducts(); - - if (empty($productIds)) { - $productIds = 0; - } - - $createdProducts = $this->_getCreatedProducts(); - - $existsProducts = $productIds; // Only for "Yes" Filter we will add created products - - if(count($createdProducts)>0) { - if(!is_array($existsProducts)) { - $existsProducts = $createdProducts; - } else { - $existsProducts = array_merge($createdProducts); - } - } - - if ($column->getFilter()->getValue()) { - $this->getCollection()->addFieldToFilter('entity_id', array('in'=>$existsProducts)); - } - else { - if($productIds) { - $this->getCollection()->addFieldToFilter('entity_id', array('nin'=>$productIds)); - } - } - } - else { - parent::_addColumnFilterToCollection($column); - } - return $this; - } - - protected function _getCreatedProducts() - { - $products = $this->getRequest()->getPost('new_products', null); - if (!is_array($products)) { - $products = array(); - } - - return $products; - } - - /** - * Prepare collection - * - * @return Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Super_Config_Grid - */ - protected function _prepareCollection() - { - $allowProductTypes = array(); - foreach (Mage::helper('Mage_Catalog_Helper_Product_Configuration')->getConfigurableAllowedTypes() as $type) { - $allowProductTypes[] = $type->getName(); - } - - $product = $this->_getProduct(); - $collection = $product->getCollection() - ->addAttributeToSelect('name') - ->addAttributeToSelect('sku') - ->addAttributeToSelect('attribute_set_id') - ->addAttributeToSelect('type_id') - ->addAttributeToSelect('price') - ->addFieldToFilter('attribute_set_id',$product->getAttributeSetId()) - ->addFieldToFilter('type_id', $allowProductTypes) - ->addFilterByRequiredOptions() - ->joinAttribute('name', 'catalog_product/name', 'entity_id', null, 'inner'); - - if (Mage::helper('Mage_Catalog_Helper_Data')->isModuleEnabled('Mage_CatalogInventory')) { - Mage::getModel('Mage_CatalogInventory_Model_Stock_Item')->addCatalogInventoryToProductCollection($collection); - } - - foreach ($product->getTypeInstance()->getUsedProductAttributes($product) as $attribute) { - $collection->addAttributeToSelect($attribute->getAttributeCode()); - $collection->addAttributeToFilter($attribute->getAttributeCode(), array('notnull'=>1)); - } - - $this->setCollection($collection); - - if ($this->isReadonly()) { - $collection->addFieldToFilter('entity_id', array('in' => $this->_getSelectedProducts())); - } - - parent::_prepareCollection(); - return $this; - } - - protected function _getSelectedProducts() - { - $products = $this->getRequest()->getPost('products', null); - if (!is_array($products)) { - $products = $this->_getProduct()->getTypeInstance()->getUsedProductIds($this->_getProduct()); - } - return $products; - } - - /** - * Check block is readonly - * - * @return boolean - */ - public function isReadonly() - { - if ($this->hasData('is_readonly')) { - return $this->getData('is_readonly'); - } - return $this->_getProduct()->getCompositeReadonly(); - } - - protected function _prepareColumns() - { - $product = $this->_getProduct(); - $attributes = $product->getTypeInstance()->getConfigurableAttributes($product); - - if (!$this->isReadonly()) { - $this->addColumn('in_products', array( - 'header_css_class' => 'a-center', - 'type' => 'checkbox', - 'name' => 'in_products', - 'values' => $this->_getSelectedProducts(), - 'align' => 'center', - 'index' => 'entity_id', - 'renderer' => 'Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Super_Config_Grid_Renderer_Checkbox', - 'attributes' => $attributes - )); - } - - $this->addColumn('entity_id', array( - 'header' => Mage::helper('Mage_Catalog_Helper_Data')->__('ID'), - 'sortable' => true, - 'width' => '60px', - 'index' => 'entity_id' - )); - $this->addColumn('name', array( - 'header' => Mage::helper('Mage_Catalog_Helper_Data')->__('Name'), - 'index' => 'name' - )); - - - $sets = Mage::getModel('Mage_Eav_Model_Entity_Attribute_Set')->getCollection() - ->setEntityTypeFilter($this->_getProduct()->getResource()->getTypeId()) - ->load() - ->toOptionHash(); - - $this->addColumn('set_name', - array( - 'header'=> Mage::helper('Mage_Catalog_Helper_Data')->__('Attrib. Set Name'), - 'width' => '130px', - 'index' => 'attribute_set_id', - 'type' => 'options', - 'options' => $sets, - )); - - $this->addColumn('sku', array( - 'header' => Mage::helper('Mage_Catalog_Helper_Data')->__('SKU'), - 'width' => '80px', - 'index' => 'sku' - )); - - $this->addColumn('price', array( - 'header' => Mage::helper('Mage_Catalog_Helper_Data')->__('Price'), - 'type' => 'currency', - 'currency_code' => (string) Mage::getStoreConfig(Mage_Directory_Model_Currency::XML_PATH_CURRENCY_BASE), - 'index' => 'price' - )); - - $this->addColumn('is_saleable', array( - 'header' => Mage::helper('Mage_Catalog_Helper_Data')->__('Inventory'), - 'renderer' => 'Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Super_Config_Grid_Renderer_Inventory', - 'filter' => 'Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Super_Config_Grid_Filter_Inventory', - 'index' => 'is_saleable' - )); - - foreach ($attributes as $attribute) { - $productAttribute = $attribute->getProductAttribute(); - $productAttribute->getSource(); - $this->addColumn($productAttribute->getAttributeCode(), array( - 'header' => $productAttribute->getFrontend()->getLabel(), - 'index' => $productAttribute->getAttributeCode(), - 'type' => $productAttribute->getSourceModel() ? 'options' : 'number', - 'options' => $productAttribute->getSourceModel() ? $this->getOptions($attribute) : '' - )); - } - - $this->addColumn('action', - array( - 'header' => Mage::helper('Mage_Catalog_Helper_Data')->__('Action'), - 'type' => 'action', - 'getter' => 'getId', - 'actions' => array( - array( - 'caption' => Mage::helper('Mage_Catalog_Helper_Data')->__('Edit'), - 'url' => $this->getEditParamsForAssociated(), - 'field' => 'id', - 'onclick' => 'superProduct.createPopup(this.href);return false;' - ) - ), - 'filter' => false, - 'sortable' => false - )); - - return parent::_prepareColumns(); - } - - public function getEditParamsForAssociated() - { - return array( - 'base' => '*/*/edit', - 'params' => array( - 'required' => $this->_getRequiredAttributesIds(), - 'popup' => 1, - 'product' => $this->_getProduct()->getId() - ) - ); - } - - /** - * Retrieve Required attributes Ids (comma separated) - * - * @return string - */ - protected function _getRequiredAttributesIds() - { - $attributesIds = array(); - foreach ( - $this->_getProduct() - ->getTypeInstance() - ->getConfigurableAttributes($this->_getProduct()) as $attribute - ) { - $attributesIds[] = $attribute->getProductAttribute()->getId(); - } - - return implode(',', $attributesIds); - } - - public function getOptions($attribute) { - $result = array(); - foreach ($attribute->getProductAttribute()->getSource()->getAllOptions() as $option) { - if($option['value']!='') { - $result[$option['value']] = $option['label']; - } - } - - return $result; - } - - public function getGridUrl() - { - return $this->getUrl('*/*/superConfig', array('_current'=>true)); - } - -} diff --git a/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/Tab/Super/Settings.php b/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/Tab/Super/Settings.php index 9dde5f621a77009cc4542f178ecce2cf58e11dd3..432b6db96c415e921480d1cbde878a54890f4554 100644 --- a/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/Tab/Super/Settings.php +++ b/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/Tab/Super/Settings.php @@ -26,7 +26,7 @@ /** - * Create Configuranle procuct Settings Tab Block + * Create Configurable product Settings Tab Block * * @category Mage * @package Mage_Adminhtml @@ -40,19 +40,14 @@ class Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Super_Settings extends Mage_ */ protected function _prepareLayout() { - $onclick = "setSuperSettings('" . $this->getContinueUrl() . "','attribute-checkbox', 'attributes')"; + $onclick = "jQuery('#product-edit-form').attr('action', " + . $this->helper('Mage_Core_Helper_Data')->jsonEncode($this->getContinueUrl()) + . ").addClass('ignore-validate').submit();"; $this->addChild('continue_button', 'Mage_Backend_Block_Widget_Button', array( - 'label' => Mage::helper('Mage_Catalog_Helper_Data')->__('Continue'), + 'label' => Mage::helper('Mage_Catalog_Helper_Data')->__('Generate Variations'), 'onclick' => $onclick, - 'class' => 'save', + 'class' => 'save', )); - - $this->addChild('back_button', 'Mage_Backend_Block_Widget_Button', array( - 'label' => Mage::helper('Mage_Catalog_Helper_Data')->__('Back'), - 'onclick' => "setLocation('" . $this->getBackUrl() . "')", - 'class' => 'back' - )); - parent::_prepareLayout(); } @@ -75,52 +70,42 @@ class Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Super_Settings extends Mage_ { $form = new Varien_Data_Form(); $fieldset = $form->addFieldset('settings', array( - 'legend'=>Mage::helper('Mage_Catalog_Helper_Data')->__('Select Configurable Attributes ') + 'legend'=>Mage::helper('Mage_Catalog_Helper_Data')->__('Select Configurable Attributes') )); $product = $this->_getProduct(); $attributes = $product->getTypeInstance() ->getSetAttributes($product); - $fieldset->addField('req_text', 'note', array( - 'text' => '<ul class="messages"><li class="notice-msg"><ul><li>' - . $this->__('Only attributes with scope "Global", input type "Dropdown" and Use To Create Configurable Product "Yes" are available.') - . '</li></ul></li></ul>' - )); - $hasAttributes = false; + $usedAttributes = $product->isConfigurable() + ? $this->_getProduct()->getTypeInstance()->getUsedProductAttributeIds($this->_getProduct()) + : array(); + + $configurableType = Mage::getSingleton('Mage_Catalog_Model_Product_Type_Configurable'); foreach ($attributes as $attribute) { - if ($product->getTypeInstance()->canUseAttribute($attribute, $product)) { + if ($configurableType->canUseAttribute($attribute, $product)) { $hasAttributes = true; - $fieldset->addField('attribute_'.$attribute->getAttributeId(), 'checkbox', array( + $fieldset->addField('attribute_' . $attribute->getAttributeId(), 'checkbox', array( 'label' => $attribute->getFrontend()->getLabel(), 'title' => $attribute->getFrontend()->getLabel(), - 'name' => 'attribute', - 'class' => 'attribute-checkbox', - 'value' => $attribute->getAttributeId() + 'name' => 'attributes[]', + 'class' => 'configurable-attribute-checkbox', + 'value' => $attribute->getAttributeId(), + 'checked' => in_array($attribute->getAttributeId(), $usedAttributes) )); } } if ($hasAttributes) { - $fieldset->addField('attributes', 'hidden', array( - 'name' => 'attribute_validate', - 'value' => '', - 'class' => 'validate-super-product-attributes' - )); - $fieldset->addField('continue_button', 'note', array( 'text' => $this->getChildHtml('continue_button'), )); - } - else { + } else { $fieldset->addField('note_text', 'note', array( 'text' => $this->__('This attribute set does not have attributes which we can use for configurable product') )); - $fieldset->addField('back_button', 'note', array( - 'text' => $this->getChildHtml('back_button'), - )); } @@ -137,8 +122,7 @@ class Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Super_Settings extends Mage_ public function getContinueUrl() { return $this->getUrl($this->_getProduct()->getId() ? '*/*/edit' : '*/*/new', array( - '_current' => true, - 'attributes' => '{{attributes}}' + '_current' => true, )); } diff --git a/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/Tabs.php b/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/Tabs.php index 477649b1630ac8e48934cfd1e1e0e6f7d9744ba2..356d3b40c693e0017a1953e74140983dab1076d6 100644 --- a/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/Tabs.php +++ b/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/Tabs.php @@ -39,7 +39,7 @@ class Mage_Adminhtml_Block_Catalog_Product_Edit_Tabs extends Mage_Adminhtml_Bloc { parent::_construct(); $this->setId('product_info_tabs'); - $this->setDestElementId('product-edit-form'); + $this->setDestElementId('product-edit-form-tabs'); $this->setTitle(Mage::helper('Mage_Catalog_Helper_Data')->__('Product Information')); } @@ -74,7 +74,7 @@ class Mage_Adminhtml_Block_Catalog_Product_Edit_Tabs extends Mage_Adminhtml_Bloc continue; } - $this->addTab('group_'.$group->getId(), array( + $this->addTab('group_' . $group->getId(), array( 'label' => Mage::helper('Mage_Catalog_Helper_Data')->__($group->getAttributeGroupName()), 'content' => $this->_translateHtml($tabAttributesBlock->setGroup($group) ->setGroupAttributes($attributes) @@ -120,11 +120,6 @@ class Mage_Adminhtml_Block_Catalog_Product_Edit_Tabs extends Mage_Adminhtml_Bloc 'class' => 'ajax', )); - $storeId = 0; - if ($this->getRequest()->getParam('store')) { - $storeId = Mage::app()->getStore($this->getRequest()->getParam('store'))->getId(); - } - $alertPriceAllow = Mage::getStoreConfig('catalog/productalert/allow_price'); $alertStockAllow = Mage::getStoreConfig('catalog/productalert/allow_stock'); diff --git a/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Helper/Form/Category.php b/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Helper/Form/Category.php index 1c71c929992d3041e8f6f2955d8352897ecfb306..107d9eb7d6250e00d3c5bdb3f2e24fca38151aa2 100644 --- a/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Helper/Form/Category.php +++ b/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Helper/Form/Category.php @@ -68,17 +68,19 @@ class Mage_Adminhtml_Block_Catalog_Product_Helper_Form_Category extends Varien_D } /** - * Get html for element + * Get html of element * * @return string */ public function getElementHtml() { - return parent::getElementHtml() - . "<script>//<![CDATA[\n jQuery(" - . $this->_getCodeHelper()->jsonEncode('#' . $this->getHtmlId()) - . ").categorySelector(" . $this->_getCodeHelper()->jsonEncode($this->_getSelectorOptions()) . "); - \n//]]></script>"; + /** @var $coreHelper Mage_Core_Helper_Data */ + $coreHelper = Mage::helper('Mage_Core_Helper_Data'); + return parent::getElementHtml() . "\n" + . '<script>//<![CDATA[' . "\n" + . 'jQuery(' . $coreHelper->jsonEncode('#' . $this->getHtmlId()) . ').categorySelector(' + . $coreHelper->jsonEncode($this->_getSelectorOptions()) . ')' . "\n" + . '//]]></script>'; } /** @@ -89,28 +91,7 @@ class Mage_Adminhtml_Block_Catalog_Product_Helper_Form_Category extends Varien_D protected function _getSelectorOptions() { return array( - 'url' => $this->_getBackendHelper()->getUrl('adminhtml/catalog_category/suggestCategories'), + 'url' => Mage::helper('Mage_Backend_Helper_Data')->getUrl('adminhtml/catalog_category/suggestCategories'), ); } - - /** - * Get backend area helper - * - * @return Mage_Backend_Helper_Data" - */ - protected function _getBackendHelper() - { - return Mage::helper("Mage_Backend_Helper_Data"); - } - - /** - * Get code module helper - * - * @return Mage_Backend_Helper_Data" - */ - protected function _getCodeHelper() - { - return Mage::helper("Mage_Core_Helper_Data"); - } - } diff --git a/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Helper/Form/Weight/Renderer.php b/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Helper/Form/Weight/Renderer.php new file mode 100644 index 0000000000000000000000000000000000000000..b38332fe54ceb081005772bd8c96d22eea6c2e73 --- /dev/null +++ b/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Helper/Form/Weight/Renderer.php @@ -0,0 +1,88 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @category Mage + * @package Mage_Adminhtml + * @copyright Copyright (c) 2012 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +/** + * Product form weight field helper + * + * @category Mage + * @package Mage_Adminhtml + * @author Magento Core Team <core@magentocommerce.com> + */ +class Mage_Adminhtml_Block_Catalog_Product_Helper_Form_Weight_Renderer extends Varien_Data_Form_Element_Text +{ + const VIRTUAL_FIELD_HTML_ID = 'weight_and_type_switcher'; + + /** + * Is virtual checkbox element + * + * @var Varien_Data_Form_Element_Checkbox + */ + protected $_virtual; + + /** + * Catalog helper + * + * @var Mage_Catalog_Helper_Product + */ + protected $_helper; + + public function __construct(array $data = array()) + { + $this->_helper = isset($data['helper']) ? $data['helper'] : Mage::helper('Mage_Catalog_Helper_Product'); + $this->_virtual = isset($data['element']) + ? $data['element'] + : Mage::getModel('Varien_Data_Form_Element_Checkbox'); + $this->_virtual->setId(self::VIRTUAL_FIELD_HTML_ID)->setName('is_virtual') + ->setLabel($this->_helper->getTypeSwitcherControlLabel()); + parent::__construct($data); + } + + /** + * Add Is Virtual checkbox html to weight field + * + * @return string + */ + public function getElementHtml() + { + if (!$this->getForm()->getDataObject()->getTypeInstance()->hasWeight()) { + $this->_virtual->setChecked('checked'); + } + return parent::getElementHtml() . $this->_virtual->getElementHtml() . $this->_virtual->getLabelHtml(); + } + + /** + * Set form for both fields + * + * @param Varien_Data_Form $form + * @return Varien_Data_Form + */ + public function setForm($form) + { + $this->_virtual->setForm($form); + return parent::setForm($form); + } + +} diff --git a/app/code/core/Mage/Adminhtml/Block/Review/Edit/Form.php b/app/code/core/Mage/Adminhtml/Block/Review/Edit/Form.php index 3507d8246fa2f49ab8ae5d90edac99b8adcc9ae0..5539454b6087c480b25240c5c5bbc587cc126f2b 100644 --- a/app/code/core/Mage/Adminhtml/Block/Review/Edit/Form.php +++ b/app/code/core/Mage/Adminhtml/Block/Review/Edit/Form.php @@ -48,9 +48,11 @@ class Mage_Adminhtml_Block_Review_Edit_Form extends Mage_Adminhtml_Block_Widget_ $fieldset = $form->addFieldset('review_details', array('legend' => Mage::helper('Mage_Review_Helper_Data')->__('Review Details'), 'class' => 'fieldset-wide')); + /** @var $helper Mage_Review_Helper_Data */ + $helper = Mage::helper('Mage_Review_Helper_Data'); $fieldset->addField('product_name', 'note', array( 'label' => Mage::helper('Mage_Review_Helper_Data')->__('Product'), - 'text' => '<a href="' . $this->getUrl('*/catalog_product/edit', array('id' => $product->getId())) . '" onclick="this.target=\'blank\'">' . $product->getName() . '</a>' + 'text' => '<a href="' . $this->getUrl('*/catalog_product/edit', array('id' => $product->getId())) . '" onclick="this.target=\'blank\'">' . $helper->escapeHtml($product->getName()) . '</a>' )); if ($customer->getId()) { diff --git a/app/code/core/Mage/Adminhtml/Helper/Catalog/Product/Edit/Action/Attribute.php b/app/code/core/Mage/Adminhtml/Helper/Catalog/Product/Edit/Action/Attribute.php index aef1a94a247084956d050c3bb7e15a7f320763cf..b30a52d018b787553f204b86a0429eaa8ddccb9e 100644 --- a/app/code/core/Mage/Adminhtml/Helper/Catalog/Product/Edit/Action/Attribute.php +++ b/app/code/core/Mage/Adminhtml/Helper/Catalog/Product/Edit/Action/Attribute.php @@ -32,7 +32,7 @@ * @package Mage_Adminhtml * @author Magento Core Team <core@magentocommerce.com> */ -class Mage_Adminhtml_Helper_Catalog_Product_Edit_Action_Attribute extends Mage_Core_Helper_Data +class Mage_Adminhtml_Helper_Catalog_Product_Edit_Action_Attribute extends Mage_Backend_Helper_Data { /** * Selected products for mass-update diff --git a/app/code/core/Mage/Adminhtml/controllers/Catalog/CategoryController.php b/app/code/core/Mage/Adminhtml/controllers/Catalog/CategoryController.php index 50eb7690679c9a657f6a92f55084c03c219ac0a8..ea2389c17c184f8ca6f80e3e069e49bbc5f32299 100644 --- a/app/code/core/Mage/Adminhtml/controllers/Catalog/CategoryController.php +++ b/app/code/core/Mage/Adminhtml/controllers/Catalog/CategoryController.php @@ -145,7 +145,7 @@ class Mage_Adminhtml_Catalog_CategoryController extends Mage_Adminhtml_Controlle /** * Check if we have data in session (if duering category save was exceprion) */ - $data = Mage::getSingleton('Mage_Adminhtml_Model_Session')->getCategoryData(true); + $data = $this->_getSession()->getCategoryData(true); if (isset($data['general'])) { $category->addData($data['general']); } @@ -331,9 +331,9 @@ class Mage_Adminhtml_Catalog_CategoryController extends Mage_Adminhtml_Controlle /** * Proceed with $_POST['use_config'] - * set into category model for proccessing through validation + * set into category model for processing through validation */ - $category->setData("use_post_data_config", $this->getRequest()->getPost('use_config')); + $category->setData('use_post_data_config', $this->getRequest()->getPost('use_config')); try { $validate = $category->validate(); @@ -348,13 +348,10 @@ class Mage_Adminhtml_Catalog_CategoryController extends Mage_Adminhtml_Controlle } } - /** - * Unset $_POST['use_config'] before save - */ $category->unsetData('use_post_data_config'); $category->save(); - Mage::getSingleton('Mage_Adminhtml_Model_Session')->addSuccess(Mage::helper('Mage_Catalog_Helper_Data')->__('The category has been saved.')); + $this->_getSession()->addSuccess(Mage::helper('Mage_Catalog_Helper_Data')->__('The category has been saved.')); $refreshTree = 'true'; } catch (Exception $e){ @@ -363,10 +360,26 @@ class Mage_Adminhtml_Catalog_CategoryController extends Mage_Adminhtml_Controlle $refreshTree = 'false'; } } - $url = $this->getUrl('*/*/edit', array('_current' => true, 'id' => $category->getId())); - $this->getResponse()->setBody( - '<script type="text/javascript">parent.updateContent("' . $url . '", {}, '.$refreshTree.');</script>' - ); + + if ($this->getRequest()->getPost('return_session_messages_only')) { + $category->load($category->getId()); // to obtain truncated category name + + /** @var $block Mage_Core_Block_Messages */ + $block = Mage::getSingleton('Mage_Core_Block_Messages'); + $block->setMessages($this->_getSession()->getMessages(true)); + $body = Mage::helper('Mage_Core_Helper_Data')->jsonEncode(array( + 'messages' => $block->getGroupedHtml(), + 'error' => $refreshTree !== 'true', + 'category' => $category->toArray(), + )); + } else { + $url = $this->getUrl('*/*/edit', array('_current' => true, 'id' => $category->getId())); + $body = '<script type="text/javascript">parent.updateContent("' + . $url . '", {}, ' . $refreshTree + . ');</script>'; + } + + $this->getResponse()->setBody($body); } /** @@ -390,7 +403,7 @@ class Mage_Adminhtml_Catalog_CategoryController extends Mage_Adminhtml_Controlle try { $category->move($parentNodeId, $prevNodeId); - $this->getResponse()->setBody("SUCCESS"); + $this->getResponse()->setBody('SUCCESS'); } catch (Mage_Core_Exception $e) { $this->getResponse()->setBody($e->getMessage()); @@ -415,15 +428,15 @@ class Mage_Adminhtml_Catalog_CategoryController extends Mage_Adminhtml_Controlle Mage::getSingleton('Mage_Backend_Model_Auth_Session')->setDeletedPath($category->getPath()); $category->delete(); - Mage::getSingleton('Mage_Adminhtml_Model_Session')->addSuccess(Mage::helper('Mage_Catalog_Helper_Data')->__('The category has been deleted.')); + $this->_getSession()->addSuccess(Mage::helper('Mage_Catalog_Helper_Data')->__('The category has been deleted.')); } catch (Mage_Core_Exception $e){ - Mage::getSingleton('Mage_Adminhtml_Model_Session')->addError($e->getMessage()); + $this->_getSession()->addError($e->getMessage()); $this->getResponse()->setRedirect($this->getUrl('*/*/edit', array('_current'=>true))); return; } catch (Exception $e){ - Mage::getSingleton('Mage_Adminhtml_Model_Session')->addError(Mage::helper('Mage_Catalog_Helper_Data')->__('An error occurred while trying to delete the category.')); + $this->_getSession()->addError(Mage::helper('Mage_Catalog_Helper_Data')->__('An error occurred while trying to delete the category.')); $this->getResponse()->setRedirect($this->getUrl('*/*/edit', array('_current'=>true))); return; } diff --git a/app/code/core/Mage/Adminhtml/controllers/Catalog/Product/AttributeController.php b/app/code/core/Mage/Adminhtml/controllers/Catalog/Product/AttributeController.php index 92da98be9e7b1359b48fbd5cd8374ff44c99ef79..97f85823609473e499fb1825eb625fa1a79320ce 100644 --- a/app/code/core/Mage/Adminhtml/controllers/Catalog/Product/AttributeController.php +++ b/app/code/core/Mage/Adminhtml/controllers/Catalog/Product/AttributeController.php @@ -311,6 +311,10 @@ class Mage_Adminhtml_Catalog_Product_AttributeController extends Mage_Adminhtml_ if(!isset($data['apply_to'])) { $data['apply_to'] = array(); } + if (!$model->getIsUserDefined() && $model->getId()) { + //Unset attribute field for system attributes + unset($data['apply_to']); + } //filter $data = $this->_filterPostData($data); diff --git a/app/code/core/Mage/Adminhtml/controllers/Catalog/ProductController.php b/app/code/core/Mage/Adminhtml/controllers/Catalog/ProductController.php index 1b3007e4bcf8494a36d582faa7cbe684428c5a7c..a113a4503c0bee40dac3460ea33e1dfee98a9077 100644 --- a/app/code/core/Mage/Adminhtml/controllers/Catalog/ProductController.php +++ b/app/code/core/Mage/Adminhtml/controllers/Catalog/ProductController.php @@ -87,13 +87,17 @@ class Mage_Adminhtml_Catalog_ProductController extends Mage_Adminhtml_Controller $product->setAttributeSetId($setId); } - $attributes = $this->getRequest()->getParam('attributes'); - if ($attributes && $product->isConfigurable() && - (!$productId || !$product->getTypeInstance()->getUsedProductAttributeIds($product))) { - $product->getTypeInstance()->setUsedProductAttributeIds( - explode(",", base64_decode(urldecode($attributes))), - $product - ); + if ($this->getRequest()->has('attributes')) { + $attributes = $this->getRequest()->getParam('attributes'); + if (!empty($attributes)) { + $product->setTypeId(Mage_Catalog_Model_Product_Type::TYPE_CONFIGURABLE); + $this->_objectManager->get('Mage_Catalog_Model_Product_Type_Configurable')->setUsedProductAttributeIds( + $attributes, + $product + ); + } else { + $product->setTypeId(Mage_Catalog_Model_Product_Type::TYPE_SIMPLE); + } } // Required attributes of simple product for configurable creation @@ -120,7 +124,6 @@ class Mage_Adminhtml_Catalog_ProductController extends Mage_Adminhtml_Controller /* @var $configProduct Mage_Catalog_Model_Product */ $data = array(); foreach ($configProduct->getTypeInstance()->getEditableAttributes($configProduct) as $attribute) { - /* @var $attribute Mage_Catalog_Model_Resource_Eav_Attribute */ if(!$attribute->getIsUnique() && $attribute->getFrontend()->getInputType()!='gallery' @@ -255,8 +258,8 @@ class Mage_Adminhtml_Catalog_ProductController extends Mage_Adminhtml_Controller $_additionalLayoutPart = ''; if ($product->getTypeId() == Mage_Catalog_Model_Product_Type::TYPE_CONFIGURABLE - && !($product->getTypeInstance()->getUsedProductAttributeIds($product))) - { + && !($product->getTypeInstance()->getUsedProductAttributeIds($product)) + ) { $_additionalLayoutPart = '_new'; } @@ -644,21 +647,29 @@ class Mage_Adminhtml_Catalog_ProductController extends Mage_Adminhtml_Controller /** * Initialize data for configurable product */ - if (($data = $this->getRequest()->getPost('configurable_products_data')) - && !$product->getConfigurableReadonly() - ) { - $product->setConfigurableProductsData(Mage::helper('Mage_Core_Helper_Data')->jsonDecode($data)); - } - if (($data = $this->getRequest()->getPost('configurable_attributes_data')) - && !$product->getConfigurableReadonly() - ) { - $product->setConfigurableAttributesData(Mage::helper('Mage_Core_Helper_Data')->jsonDecode($data)); - } - $product->setCanSaveConfigurableAttributes( - (bool) $this->getRequest()->getPost('affect_configurable_product_attributes') - && !$product->getConfigurableReadonly() - ); + $attributes = $this->getRequest()->getParam('attributes'); + if (!empty($attributes)) { + $product->setTypeId(Mage_Catalog_Model_Product_Type::TYPE_CONFIGURABLE); + $this->_objectManager->get('Mage_Catalog_Model_Product_Type_Configurable')->setUsedProductAttributeIds( + $attributes, + $product + ); + + $product->setAssociatedProductIds($this->getRequest()->getPost('associated_product_ids', array())); + + $data = $this->getRequest()->getPost('configurable_attributes_data'); + if ($data) { + $product->setConfigurableAttributesData(Mage::helper('Mage_Core_Helper_Data')->jsonDecode($data)); + } + + $product->setCanSaveConfigurableAttributes( + (bool)$this->getRequest()->getPost('affect_configurable_product_attributes') + ); + } elseif ($product->getTypeId() === Mage_Catalog_Model_Product_Type::TYPE_CONFIGURABLE) { + $product->setTypeId(Mage_Catalog_Model_Product_Type::TYPE_VIRTUAL); + $product->setTypeInstance(null); + } /** * Initialize product options @@ -715,6 +726,10 @@ class Mage_Adminhtml_Catalog_ProductController extends Mage_Adminhtml_Controller $this->_filterStockData($data['product']['stock_data']); $product = $this->_initProductSave($this->_initProduct()); + Mage::dispatchEvent( + 'catalog_product_transition_product_type', + array('product' => $product, 'request' => $this->getRequest()) + ); try { if (isset($data['product'][$product->getIdFieldName()])) { diff --git a/app/code/core/Mage/Adminhtml/view/adminhtml/catalog.xml b/app/code/core/Mage/Adminhtml/view/adminhtml/catalog.xml index 70382288ae46896e907b96dd4d0195c135d9e490..fe724ee61925806d706d3e6adf729f7412b6303f 100644 --- a/app/code/core/Mage/Adminhtml/view/adminhtml/catalog.xml +++ b/app/code/core/Mage/Adminhtml/view/adminhtml/catalog.xml @@ -50,21 +50,28 @@ <action method="addJs"><file>Mage_Adminhtml::jquery/fileUploader/load-image.min.js</file></action> <action method="addJs"><file>Mage_Adminhtml::jquery/fileUploader/canvas-to-blob.min.js</file></action> <action method="addJs"><file>Mage_Adminhtml::jquery/fileUploader/jquery.fileupload-fp.js</file></action> - <action method="addCss"><file>Mage_Adminhtml::catalog/jquery.category-selector.css</file></action> - <action method="addJs"><file>Mage_Adminhtml::catalog/jquery.category-selector.js</file></action> - <action method="addJs"><file>Mage_Adminhtml::catalog/jquery.base-image-uploader.js</file></action> - <action method="addCss"><file>Mage_Adminhtml::catalog/jquery.base-image-uploader.css</file></action> + <action method="addCss"><file>Mage_Adminhtml::catalog/category-selector.css</file></action> + <action method="addJs"><file>Mage_Adminhtml::catalog/category-selector.js</file></action> + <action method="addJs"><file>Mage_Adminhtml::catalog/type-switcher.js</file></action> + <action method="addJs"><file>Mage_Adminhtml::catalog/base-image-uploader.js</file></action> + <action method="addCss"><file>Mage_Adminhtml::catalog/base-image-uploader.css</file></action> + <action method="addCss"><file>Mage_Adminhtml::catalog/configurable-product.css</file></action> </reference> <reference name="content"> - <block type="Mage_Adminhtml_Block_Catalog_Product_Edit" name="product_edit"></block> + <block type="Mage_Adminhtml_Block_Catalog_Product_Edit" name="product_edit"> + <container name="product-type-tabs" label="Tabs"> + </container> + </block> <block type="Mage_Adminhtml_Block_Catalog_Product_Edit_AttributeSet" name="attribute-set-info" template="Mage_Adminhtml::catalog/product/edit/attribute_set.phtml"></block> + <block type="Mage_Adminhtml_Block_Catalog_Product_Edit_NewCategory" name="new-category" template="Mage_Adminhtml::catalog/product/edit/category/new/form.phtml"/> </reference> <reference name="left"> <block type="Mage_Adminhtml_Block_Catalog_Product_Edit_Tabs" name="product_tabs"></block> </reference> <reference name="js"> - <block type="Mage_Core_Block_Template" name="change-attribute-set" template="Mage_Adminhtml::catalog/product/change_attribute_set_widget.phtml" /> - <block type="Mage_Adminhtml_Block_Catalog_Product_Edit_Js" template="catalog/product/js.phtml" name="catalog_product_js"></block> + <block type="Mage_Core_Block_Template" name="change-attribute-set" template="Mage_Adminhtml::catalog/product/change_attribute_set_widget.phtml"/> + <block type="Mage_Adminhtml_Block_Catalog_Product_Edit_NewCategory" name="new-category-js" template="Mage_Adminhtml::catalog/product/edit/category/new/js.phtml"/> + <block type="Mage_Adminhtml_Block_Catalog_Product_Edit_Js" template="catalog/product/js.phtml" name="catalog_product_js"/> <block type="Mage_Core_Block_Template" template="Mage_Adminhtml::catalog/wysiwyg/js.phtml"/> </reference> </adminhtml_catalog_product_new> @@ -79,23 +86,30 @@ <action method="addJs"><file>Mage_Adminhtml::jquery/fileUploader/load-image.min.js</file></action> <action method="addJs"><file>Mage_Adminhtml::jquery/fileUploader/canvas-to-blob.min.js</file></action> <action method="addJs"><file>Mage_Adminhtml::jquery/fileUploader/jquery.fileupload-fp.js</file></action> - <action method="addCss"><file>Mage_Adminhtml::catalog/jquery.category-selector.css</file></action> - <action method="addJs"><file>Mage_Adminhtml::catalog/jquery.category-selector.js</file></action> - <action method="addJs"><file>Mage_Adminhtml::catalog/jquery.base-image-uploader.js</file></action> - <action method="addCss"><file>Mage_Adminhtml::catalog/jquery.base-image-uploader.css</file></action> + <action method="addCss"><file>Mage_Adminhtml::catalog/category-selector.css</file></action> + <action method="addJs"><file>Mage_Adminhtml::catalog/category-selector.js</file></action> + <action method="addJs"><file>Mage_Adminhtml::catalog/type-switcher.js</file></action> + <action method="addJs"><file>Mage_Adminhtml::catalog/base-image-uploader.js</file></action> + <action method="addCss"><file>Mage_Adminhtml::catalog/base-image-uploader.css</file></action> + <action method="addCss"><file>Mage_Adminhtml::catalog/configurable-product.css</file></action> </reference> <reference name="content"> - <block type="Mage_Adminhtml_Block_Catalog_Product_Edit" name="product_edit"></block> + <block type="Mage_Adminhtml_Block_Catalog_Product_Edit" name="product_edit"> + <container name="product-type-tabs" label="Tabs"> + </container> + </block> <block type="Mage_Adminhtml_Block_Catalog_Product_Edit_AttributeSet" name="attribute-set-info" template="Mage_Adminhtml::catalog/product/edit/attribute_set.phtml"></block> + <block type="Mage_Adminhtml_Block_Catalog_Product_Edit_NewCategory" name="new-category" template="Mage_Adminhtml::catalog/product/edit/category/new/form.phtml"/> </reference> <reference name="left"> <block type="Mage_Backend_Block_Store_Switcher" name="store_switcher" before="-"></block> <block type="Mage_Adminhtml_Block_Catalog_Product_Edit_Tabs" name="product_tabs"></block> </reference> <reference name="js"> - <block type="Mage_Core_Block_Template" name="change-attribute-set" template="Mage_Adminhtml::catalog/product/change_attribute_set_widget.phtml" /> - <block type="Mage_Adminhtml_Block_Catalog_Product_Edit_Js" template="catalog/product/js.phtml" name="catalog_product_js"></block> - <block type="Mage_Core_Block_Template" name="catalog.wysiwyg.js" template="Mage_Adminhtml::catalog/wysiwyg/js.phtml"/> + <block type="Mage_Core_Block_Template" name="change-attribute-set" template="Mage_Adminhtml::catalog/product/change_attribute_set_widget.phtml"/> + <block type="Mage_Adminhtml_Block_Catalog_Product_Edit_NewCategory" name="new-category-js" template="Mage_Adminhtml::catalog/product/edit/category/new/js.phtml"/> + <block type="Mage_Adminhtml_Block_Catalog_Product_Edit_Js" template="catalog/product/js.phtml" name="catalog_product_js"/> + <block type="Mage_Core_Block_Template" template="Mage_Adminhtml::catalog/wysiwyg/js.phtml"/> </reference> </adminhtml_catalog_product_edit> @@ -143,8 +157,92 @@ </container> </adminhtml_catalog_product_relatedgrid> + <adminhtml_catalog_product_superconfig_config> + <reference name="admin.product.edit.tab.super.config.grid.container"> + <block type="Mage_Backend_Block_Widget_Grid" name="admin.product.edit.tab.super.config.grid" as="grid"> + <arguments> + <id>configurable_associated_products_grid</id> + <dataSource type="object">Mage_Catalog_Model_Resource_Product_Collection_AssociatedProduct</dataSource> + <use_ajax>true</use_ajax> + <default_sort>entity_id</default_sort> + <default_dir>DESC</default_dir> + <save_parameters_in_session>0</save_parameters_in_session> + <grid_url type="url"> + <path>*/*/superConfig</path> + <params> + <_current>1</_current> + </params> + </grid_url> + </arguments> + <block type="Mage_Catalog_Block_Product_Configurable_AssociatedSelector_Backend_Grid_ColumnSet" as="grid.columnSet" + name="admin.product.edit.tab.super.config.grid.columnSet"> + <arguments> + <id>super_product_links</id> + </arguments> + <block type="Mage_Backend_Block_Widget_Grid_Column" as="entity_id"> + <arguments> + <header translate="true" module="Mage_Core">ID</header> + <width>60px</width> + <type>text</type> + <index>entity_id</index> + <id>entity_id</id> + <filter>0</filter> + <sortable>1</sortable> + <column_css_class>associated-product-id</column_css_class> + </arguments> + </block> + <block type="Mage_Backend_Block_Widget_Grid_Column" as="name"> + <arguments> + <header translate="true" module="Mage_Core">Name</header> + <type>text</type> + <index>name</index> + <id>name</id> + <filter>0</filter> + <sortable>1</sortable> + <column_css_class>associated-product-name</column_css_class> + </arguments> + </block> + <block type="Mage_Backend_Block_Widget_Grid_Column" as="price"> + <arguments> + <header translate="true" module="Mage_Core">Price</header> + <type>currency</type> + <index>price</index> + <id>price</id> + <filter>0</filter> + <sortable>1</sortable> + <column_css_class>associated-product-price</column_css_class> + </arguments> + </block> + <block type="Mage_Backend_Block_Widget_Grid_Column" as="sku" name="admin.product.edit.tab.super.config.grid.sku"> + <arguments> + <header translate="true" module="Mage_Core">SKU</header> + <type>text</type> + <index>sku</index> + <id>sku</id> + <filter>0</filter> + <sortable>1</sortable> + <column_css_class>associated-product-sku</column_css_class> + </arguments> + </block> + <block type="Mage_Backend_Block_Widget_Grid_Column" as="weight"> + <arguments> + <header translate="true" module="Mage_Core">Weight</header> + <type>text</type> + <index>weight</index> + <id>weight</id> + <filter>0</filter> + <sortable>1</sortable> + <column_css_class>associated-product-weight</column_css_class> + </arguments> + </block> + </block> + </block> + </reference> + </adminhtml_catalog_product_superconfig_config> + <adminhtml_catalog_product_superconfig> - <block type="Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Super_Config_Grid" name="admin.product.edit.tab.super.config.grid" output="1" /> + <update handle="adminhtml_catalog_product_superconfig_config"/> + <container output="1" name="admin.product.edit.tab.super.config.grid.container" label="grid"></container> </adminhtml_catalog_product_superconfig> <adminhtml_catalog_product_alertspricegrid> @@ -207,8 +305,27 @@ <!-- Layout handle for simple products --> - - <adminhtml_catalog_product_simple /> + <adminhtml_catalog_product_simple> + <update handle="adminhtml_catalog_product_superconfig_config"/> + <reference name="product_tabs"> + <action method="addTab"><name>downloadable_items</name><block>Mage_Downloadable_Block_Adminhtml_Catalog_Product_Edit_Tab_Downloadable</block></action> + </reference> + <reference name="product-type-tabs"> + <block type="Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Super_Config" name="admin.product.edit.tab.super.config.grid.container"></block> + </reference> + </adminhtml_catalog_product_simple> +<!-- +Layout handle for virtual products +--> + <adminhtml_catalog_product_virtual> + <update handle="adminhtml_catalog_product_superconfig_config"/> + <reference name="product_tabs"> + <action method="addTab"><name>downloadable_items</name><block>Mage_Downloadable_Block_Adminhtml_Catalog_Product_Edit_Tab_Downloadable</block></action> + </reference> + <reference name="product-type-tabs"> + <block type="Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Super_Config" name="admin.product.edit.tab.super.config.grid.container"></block> + </reference> + </adminhtml_catalog_product_virtual> <!-- Layout handle for grouped products @@ -249,22 +366,16 @@ Layout handle for configurable products --> <adminhtml_catalog_product_configurable_new> - <reference name="product_tabs"> - <action method="addTab"> - <name>configurable</name> - <block>Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Super_Config</block> - </action> - <action method="bindShadowTabs"> - <first>configurable</first> - <second>customer_options</second> - </action> + <update handle="adminhtml_catalog_product_superconfig_config"/> + <reference name="product-type-tabs"> + <block type="Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Super_Config" name="admin.product.edit.tab.super.config.grid.container"></block> </reference> </adminhtml_catalog_product_configurable_new> <adminhtml_catalog_product_configurable> - <reference name="product_tabs"> - <action method="addTab"><name>configurable</name><block>Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Super_Config</block></action> - <action method="bindShadowTabs"><first>configurable</first><second>customer_options</second></action> + <update handle="adminhtml_catalog_product_superconfig_config"/> + <reference name="product-type-tabs"> + <block type="Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Super_Config" name="admin.product.edit.tab.super.config.grid.container"></block> </reference> </adminhtml_catalog_product_configurable> diff --git a/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/base-image-uploader.css b/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/base-image-uploader.css new file mode 100644 index 0000000000000000000000000000000000000000..2d947376687ba326bf15feb17681da01880643fd --- /dev/null +++ b/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/base-image-uploader.css @@ -0,0 +1,61 @@ +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @category Mage + * @package Mage_Adminhtml + * @copyright Copyright (c) 2012 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ + +#product-edit-form-tabs .base-image-uploader { + max-height: 265px; + max-width: 180px; +} + +#product-edit-form-tabs > div:first-of-type { + min-width: 940px; +} + +#product-edit-form-tabs > div:first-of-type .hor-scroll { + width: auto; + padding-right: 200px; + overflow: visible; + position: relative; +} + +#product-edit-form-tabs #image_image { + position: absolute; + right: 0; +} + +#product-edit-form-tabs #qty { + width: 50px; + margin-right: 16px; + text-align: right; + padding-right: 3px; +} + +#product-edit-form-tabs #quantity_and_stock_status { + width: 204px; +} + +#product-edit-form-tabs #short_description { + height: auto; + min-height: 3em; +} diff --git a/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/jquery.base-image-uploader.js b/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/base-image-uploader.js similarity index 98% rename from app/code/core/Mage/Adminhtml/view/adminhtml/catalog/jquery.base-image-uploader.js rename to app/code/core/Mage/Adminhtml/view/adminhtml/catalog/base-image-uploader.js index ace4806dfeec9237fae83af1c42a8a3828cbad4d..2613c8a704f384429c94580ac8720deee46194d0 100644 --- a/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/jquery.base-image-uploader.js +++ b/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/base-image-uploader.js @@ -18,7 +18,7 @@ * needs please refer to http://www.magentocommerce.com for more information. * * @category Mage - * @package js + * @package Mage_Adminhtml * @copyright Copyright (c) 2012 X.commerce, Inc. (http://www.magentocommerce.com) * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) */ @@ -54,4 +54,4 @@ function BaseImageUploader(id, maxFileSize) { } }); })(jQuery); -} \ No newline at end of file +} diff --git a/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/jquery.category-selector.css b/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/category-selector.css similarity index 99% rename from app/code/core/Mage/Adminhtml/view/adminhtml/catalog/jquery.category-selector.css rename to app/code/core/Mage/Adminhtml/view/adminhtml/catalog/category-selector.css index 9f2407fc789bf57d48ffc85dfda777b4a732d8ce..47aba2552f20596096f258f67e7f5cf8586d6513 100644 --- a/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/jquery.category-selector.css +++ b/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/category-selector.css @@ -17,8 +17,8 @@ * versions in the future. If you wish to customize Magento for your * needs please refer to http://www.magentocommerce.com for more information. * - * @category Mage_Cat - * @package + * @category Mage + * @package Mage_Adminhtml * @copyright Copyright (c) 2012 X.commerce, Inc. (http://www.magentocommerce.com) * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) */ @@ -27,6 +27,7 @@ display:inline-block; vertical-align:top; width:99%; + margin-bottom: 6px; } .category-selector-container, @@ -192,7 +193,7 @@ margin-top:4px; } -.category-selector-search input.category-selector-active { +.category-selector-search input.category-selector-active, input.input-text.parent-category-selector-active { background:#fff url('images/spinner.gif') no-repeat 100%; background:url('images/spinner.gif') no-repeat 100%, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, white), color-stop(0.99, #eeeeee)); background:url('images/spinner.gif') no-repeat 100%, -webkit-linear-gradient(center bottom, white 85%, #eeeeee 99%); diff --git a/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/jquery.category-selector.js b/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/category-selector.js similarity index 69% rename from app/code/core/Mage/Adminhtml/view/adminhtml/catalog/jquery.category-selector.js rename to app/code/core/Mage/Adminhtml/view/adminhtml/catalog/category-selector.js index 56a7b9edeea148327dd289534f2dc5ce9e438d9f..6a22e9b20df93a751967d437d7c2673af185297c 100644 --- a/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/jquery.category-selector.js +++ b/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/category-selector.js @@ -18,12 +18,12 @@ * needs please refer to http://www.magentocommerce.com for more information. * * @category Mage - * @package js + * @package Mage_Adminhtml * @copyright Copyright (c) 2012 X.commerce, Inc. (http://www.magentocommerce.com) * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) */ -(function ($, undefined) { - "use strict"; +(function ($) { + 'use strict'; var treeToList = function(list, nodes, level, path) { $.each(nodes, function() { list.push({ @@ -47,42 +47,54 @@ '<li class="category-selector-search-field">' + '<input type="text" autocomplete="off" ' + 'data-ui-id="category-selector-input" class="category-selector-input">' + - '</li></ul></div>' + '</li></ul></div>' + + '<button title="New Category" type="button" onclick="jQuery(\'#new-category\').dialog(\'open\')">' + + '<span><span><span>New Category</span></span></span>' + + '</button>' ), $list = $element.children(), $this = $(this), name = $this.attr('name'), $searchField = $list.find('.category-selector-search-field'), - itemRenderer = function(value, text, data) { - $('<li class="category-selector-search-choice button"/>') - .data(data || {}) - .append($('<input type="hidden" />').attr('name', name).val(value)) - .append($('<div/>').text(text)) - .append('<span ' + - 'class="category-selector-search-choice-close" tabindex="-1"></span>' - ) - .insertBefore($searchField); - }, $input = $element.find('.category-selector-input'), elementPresent = function(item) { var selector = '[name="product[category_ids][]"][value=' + parseInt(item.value, 10) + ']'; return $list.find(selector).length > 0; }; + + $this.bind('categorySelector:add', function(event, args) { + $('<li class="category-selector-search-choice button"/>') + .data(args.data || {}) + .append($('<input type="hidden" />').attr('name', name).val(args.value)) + .append($('<div/>').text(args.text)) + .append('<span ' + + 'class="category-selector-search-choice-close" tabindex="-1"></span>' + ) + .insertBefore($searchField); + }); + $element.append($('<input type="hidden" />').attr('name', name)); - $this.find('option').each(function(){ - itemRenderer($(this).val(), $(this).text()); + $this.find('option').each(function() { + $this.trigger('categorySelector:add', { + text: $(this).text(), + value: $(this).val() + }); }); $this.attr('disabled', 'disabled').hide(); $this.data('category-selector-element', $element); $element.insertAfter($this); - $list.delegate(".category-selector-search-choice-close", "click", function() { + $list.delegate('.category-selector-search-choice-close', 'click', function() { $(this).parent().remove(); }); $input.bind('ajaxSend ajaxComplete', function(e) { e.stopPropagation(); switch (e.type) { - case 'ajaxSend': $input.addClass('category-selector-active'); break; - case 'ajaxComplete': $input.removeClass('category-selector-active'); break; + case 'ajaxSend': + $input.addClass('category-selector-active'); + break; + case 'ajaxComplete': + $input.removeClass('category-selector-active'); + break; } }); $input.autocomplete({ @@ -90,22 +102,28 @@ $.ajax({ url: options.url, context: $input, - dataType: "json", - data: { - name_part: request.term - }, + dataType: 'json', + data: {name_part: request.term}, success: function(data) { response(treeToList([], data || [], 0, '')); } }); }, - minLength: 1, + minLength: 0, + focus: function(event, ui) { + $element.find('.category-selector-input').val(ui.item.label); + return false; + }, select: function(event, ui) { if (elementPresent(ui.item)) { event.preventDefault(); return false; } - itemRenderer(ui.item.value, ui.item.label, ui.item); + $this.trigger('categorySelector:add', { + text: ui.item.label, + value: ui.item.value, + data: ui.item + }); $element.find('.category-selector-input').val(''); return false; }, @@ -114,7 +132,7 @@ return false; } }); - $input.data("autocomplete")._renderItem = function(ul, item) { + $input.data('autocomplete')._renderItem = function(ul, item) { var level = window.parseInt(item.level), $li = $("<li>"); $li.data("item.autocomplete", item); diff --git a/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/category/edit.js b/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/category/edit.js index 0542ac08bc3b1dfe3696e9d32895c3a203982976..f7619910406b4628f2938f7694c08760f170d860 100644 --- a/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/category/edit.js +++ b/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/category/edit.js @@ -17,8 +17,8 @@ * versions in the future. If you wish to customize Magento for your * needs please refer to http://www.magentocommerce.com for more information. * - * @category design - * @package default_default + * @category Mage + * @package Mage_Adminhtml * @copyright Copyright (c) 2012 X.commerce, Inc. (http://www.magentocommerce.com) * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) */ diff --git a/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/jquery.base-image-uploader.css b/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/configurable-product.css similarity index 83% rename from app/code/core/Mage/Adminhtml/view/adminhtml/catalog/jquery.base-image-uploader.css rename to app/code/core/Mage/Adminhtml/view/adminhtml/catalog/configurable-product.css index 8fd2a7cf544e62d3b4fb19b3b6da470c83313f5f..1c922f39e43d271fefdaa120ebe1c72f579027fc 100644 --- a/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/jquery.base-image-uploader.css +++ b/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/configurable-product.css @@ -17,12 +17,12 @@ * versions in the future. If you wish to customize Magento for your * needs please refer to http://www.magentocommerce.com for more information. * - * @category Mage_Catalog - * @package + * @category Mage + * @package Mage_Adminhtml * @copyright Copyright (c) 2012 X.commerce, Inc. (http://www.magentocommerce.com) * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) */ -.base-image-uploader { - max-height:265px; - max-width:265px; -} \ No newline at end of file +#configurable_associated_products_grid .filter-actions, +#configurable_associated_products_grid .filter { + display: none; +} diff --git a/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/form/renderer/fieldset/element.phtml b/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/form/renderer/fieldset/element.phtml index 3b5d1ed999ffef89afcf28b6c05f619f63feae46..0ac56242745b815d284e070d6dcacfb3cc65a4a8 100644 --- a/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/form/renderer/fieldset/element.phtml +++ b/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/form/renderer/fieldset/element.phtml @@ -41,7 +41,7 @@ <td class="hidden" colspan="100"><?php echo trim($_element->getElementHtml()) ?></td> </tr> <?php else: ?> -<tr> +<tr id="attribute-<?php echo $_element->getHtmlId()?>-container"> <td class="label"><?php echo trim($this->getElementLabelHtml()) ?></td> <td class="value"> <?php echo trim($this->getElementHtml()) ?> diff --git a/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product.js b/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product.js index b47179e066061d1a0158ce31251bdb6659ed2f09..8c0ef79882e5749649b7783f38a6ddb32a5c05c6 100644 --- a/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product.js +++ b/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product.js @@ -375,6 +375,7 @@ Product.Configurable.prototype = { this.grid.rows.each( function(row) { this.rowInit(this.grid, row); }.bind(this)); + this.updateGrid(); }, createAttributes : function() { this.attributes.each( function(attribute, index) { @@ -583,6 +584,7 @@ Product.Configurable.prototype = { }, updateGrid : function() { this.grid.reloadParams = { + 'attributes[]': this.attributes.map(function(el) { return el.attribute_id; }), 'products[]' :this.links.keys().size() ? this.links.keys() : [ 0 ], 'new_products[]' :this.newProducts }; @@ -737,7 +739,6 @@ Product.Configurable.prototype = { }, updateSaveInput : function() { $(this.idPrefix + 'save_attributes').value = Object.toJSON(this.attributes); - $(this.idPrefix + 'save_links').value = Object.toJSON(this.links); }, initializeAdvicesForSimpleForm : function() { if ($(this.idPrefix + 'simple_form').advicesInited) { diff --git a/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product/change_attribute_set_widget.phtml b/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product/change_attribute_set_widget.phtml index 1f5c99b99846760eaf93ef3f9146d5352a1721f6..ef078d80ba0a840707f49a305ca63fa494d6ab97 100644 --- a/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product/change_attribute_set_widget.phtml +++ b/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product/change_attribute_set_widget.phtml @@ -39,7 +39,7 @@ var uri = document.location.href.replace(/(\/|&|\?)?\bset(\/|=)\d+/g, '').replace('#', ''); uri += /\?/.test(uri) ? '&' : '?'; uri += 'set=' + window.encodeURIComponent(attributeSetId); - $form.attr('action', uri).submit(); + $form.attr('action', uri).addClass('ignore-validate').submit(); }); $('#attribute-set-info').dialog({ diff --git a/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product/edit.phtml b/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product/edit.phtml index eaa37837951d123aae33016649ed5e94fea32196..0c62cf23e1cbc3511fd36fab9d4307967a66b5e8 100644 --- a/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product/edit.phtml +++ b/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product/edit.phtml @@ -51,7 +51,8 @@ </div> <form action="<?php echo $this->getSaveUrl() ?>" method="post" id="product-edit-form" enctype="multipart/form-data"> <?php echo $this->getBlockHtml('formkey')?> - <div style="display:none"></div> + <div id="product-edit-form-tabs"></div> + <?php echo $this->getChildHtml('product-type-tabs') ?> </form> <script type="text/javascript"> //<![CDATA[ @@ -99,7 +100,9 @@ jQuery(function() { product_info_tabsJsTabs.showTabContent(obj); } Product.AttributesBridge.setTabsObject(product_info_tabsJsTabs); - + window.varienGlobalEvents.attachEventHandler('tabChangeBefore', function(data) { + jQuery('#config_super_product')[data.first ? 'show' : 'hide'](); + }); (function ($) { var masks = <?php echo $this->helper('Mage_Core_Helper_Data')->jsonEncode($this->getFieldsAutogenerationMasks())?>; @@ -176,5 +179,11 @@ jQuery(function() { new Autogenerator(masks).bindAll(); })(jQuery); }); + +jQuery(function($) { + var data = <?php echo $this->getTypeSwitcherData();?>; + new TypeSwitcher(data).bindAll(); +}); + //]]> </script> diff --git a/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product/edit/category/new/form.phtml b/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product/edit/category/new/form.phtml new file mode 100644 index 0000000000000000000000000000000000000000..faaaf509467e386d9db63b36a2a6fb62203c5c72 --- /dev/null +++ b/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product/edit/category/new/form.phtml @@ -0,0 +1,31 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @category design + * @package default_default + * @copyright Copyright (c) 2012 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +/* @var $this Mage_Adminhtml_Block_Catalog_Product_Edit_NewCategory */ +?> +<div id="<?php echo $this->getNameInLayout() ?>" style="display:none"> + <?php echo $this->getFormHtml();?> + <?php echo $this->getChildHtml('form_after');?> +</div> diff --git a/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product/edit/category/new/js.phtml b/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product/edit/category/new/js.phtml new file mode 100644 index 0000000000000000000000000000000000000000..c6b426e1be52f160632250dab4ea2c492fb4b226 --- /dev/null +++ b/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product/edit/category/new/js.phtml @@ -0,0 +1,210 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @category design + * @package default_default + * @copyright Copyright (c) 2012 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +?> +<?php /** @var $this Mage_Adminhtml_Block_Catalog_Product_Edit_NewCategory */ ?> +<script type="text/javascript">//<[CDATA[ +(function($) { + 'use strict'; + $(function() { + Validation.add('validate-parent-category', 'Choose existing category.', function() { + return $('#new_category_parent_id').val() !== ''; + }); + var newCategoryForm = new Validation($('#new-category').get(0)); + + var treeToList = function(list, nodes, level, path) { + $.each(nodes, function() { + list.push({ + label: this.name, + value: this.id, + level: level, + item: this, + path: path + this.name + }); + if ('children' in this) { + treeToList(list, this.children, level + 1, path + this.name + '/' ); + } + }); + return list; + }; + + $('#new_category_parent') + .removeClass('validate-parent-category') + .addClass('validate-parent-category') // adjusting validation rules order + .bind('ajaxSend ajaxComplete', function(e) { + e.stopPropagation(); + switch (e.type) { + case 'ajaxSend': + $('#new_category_parent').addClass('parent-category-selector-active'); + break; + case 'ajaxComplete': + $('#new_category_parent').removeClass('parent-category-selector-active'); + break; + } + }) + .autocomplete({ + source: function(request, response) { + $.ajax({ + url: '<?php echo $this->getSuggestCategoryUrl()?>', + data: {name_part: request.term}, + dataType: 'json', + context: $('#new_category_parent') + }).success(function(data) { + response(treeToList([], data || [], 0, '')); + }); + }, + minLength: 0, + focus: function(event, ui) { + $(this).val(ui.item.label); + return false; + }, + open: function(event, ui) { + $('#new_category_parent').data('selected-name', ''); + }, + select: function(event, ui) { + $('#new_category_parent_id').val(ui.item.value); + $('#new_category_parent').data('selected-name', $('#new_category_parent').val()); + $(this).val(ui.item.label); + + if ($('#new_category_name').val() === '') { + $('#new_category_name').focus(); + } else { + $('#<?php echo $this->getJsId('save-button')?>').focus(); + } + + return false; + }, + close: function(event, ui) { + var selectedName = $('#new_category_parent').data('selected-name'); + $('#new_category_parent').val(selectedName === '' ? $(this).data('autocomplete').term : selectedName); + return false; + } + }) + .focus(function () { + var $this = $(this); + if (!$this.data('focus-emulated') && $this.val() === '') { + $this.autocomplete('search'); + } + setTimeout(function() { // fix for IE9 in which two focus events are triggered + $this.data('focus-emulated', false); + }, 100); + }) + .data('autocomplete')._renderItem = function(ul, item) { + var level = window.parseInt(item.level), + $li = $('<li>'); + $li.data('item.autocomplete', item); + $li.append($('<a/>', { + 'data-level': level, + 'data-ui-id': 'category-selector-' + item.value + }).attr('title', item.path) + .addClass('level-' + level) + .text(item.label) + .css({marginLeft: level * 16}) + ); + if (window.parseInt(item.item.is_active, 10) == 0) { + $li.addClass('category-disabled'); + } + $li.appendTo(ul); + + return $li; + }; + + $('#new-category').dialog({ + title: '<?php echo Mage::helper('Mage_Catalog_Helper_Data')->__('Create New Category');?>', + autoOpen: false, + id: '<?php echo $this->getJsId()?>', + minWidth: 560, + modal: true, + resizable: false, + open: function() { + var enteredName = $('#category_ids + .category-selector-container .category-selector-input').val(); + $('#new_category_name').val(enteredName); + if (enteredName === '') { + $('#new_category_name').focus(); + } else { + $('#new_category_parent').data('focus-emulated', true).focus(); + } + $('#new_category_messages').html(''); + }, + close: function() { + $('#new_category_name, #new_category_parent_id, #new_category_parent').val(''); + $('#new_category_parent').autocomplete('close'); + newCategoryForm.reset(); + $('#category_ids + .category-selector-container .category-selector-input').focus(); + }, + buttons: [{ + text: '<?php echo $this->helper('Mage_Catalog_Helper_Data')->__('Cancel');?>', + id: '<?php echo $this->getJsId('close-button')?>', + click: function() { + $(this).dialog('close'); + } + }, { + text: '<?php echo $this->helper('Mage_Catalog_Helper_Data')->__('Save');?>', + id: '<?php echo $this->getJsId('save-button')?>', + click: function() { + if ($('#new_category_parent').data('selected-name') != $('#new_category_parent').val()) { + $('#new_category_parent_id').val(''); + } + + if (!newCategoryForm.validate()) { + return; + } + + $.ajax({ + type: 'POST', + url: '<?php echo $this->getSaveCategoryUrl()?>', + data: { + general: { + name: $('#new_category_name').val(), + is_active: 1, + include_in_menu: 0 + }, + parent: $('#new_category_parent_id').val(), + use_config: ['available_sort_by', 'default_sort_by'], + form_key: '<?php echo $this->getFormKey()?>', + return_session_messages_only: 1 + }, + dataType: 'json', + context: $('body') + }).success(function (data) { + if (!data.error) { + $('#category_ids').trigger('categorySelector:add', { + text: data.category.name, + value: data.category.entity_id + }); + $('#new_category_name, #new_category_parent_id, #new_category_parent').val(''); + $('#category_ids + .category-selector-container .category-selector-input').val(''); + $('#new-category').dialog('close'); + } else { + $('#new_category_messages').html(data.messages); + } + }); + } + }] + }); + }); +})(jQuery); +//]]> +</script> diff --git a/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product/edit/options/option.phtml b/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product/edit/options/option.phtml index c6561965c7f9c7b215761c14b4f9e16d1a9feedd..11c31555569bd101c2ad9d5e0a5d0ac2228260a2 100644 --- a/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product/edit/options/option.phtml +++ b/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product/edit/options/option.phtml @@ -24,6 +24,7 @@ * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) */ ?> +<?php /** @var $this Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Options_Option */?> <?php echo $this->getTemplatesHtml() ?> <script type="text/javascript"> @@ -358,7 +359,6 @@ window.productOptionScope.bindScopeCheckbox(); }); $('#import-container').dialog('open'); }); - }); $('#import-container').dialog({ @@ -397,7 +397,7 @@ window.productOptionScope.bindScopeCheckbox(); el.id = window.productOption.getFreeOptionId(el.id); el.option_id = el.id; if (typeof el.optionValues != 'undefined') { - for (i = 0; i < el.optionValues.length; i++) { + for (var i = 0; i < el.optionValues.length; i++) { el.optionValues[i].option_id = el.id; } } diff --git a/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product/edit/price/group.phtml b/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product/edit/price/group.phtml index 3968d99c0869f8adb5aad9b65e4f7d375a84819f..d03e94aa439bddd109a148f9e06ad86c742d04ae 100644 --- a/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product/edit/price/group.phtml +++ b/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product/edit/price/group.phtml @@ -34,7 +34,7 @@ $_priceValueValidation = $this->getPriceValidation('validate-zero-or-greater'); $_showWebsite= $this->isMultiWebsites(); ?> -<tr> +<tr id="attribute-<?php echo $_htmlId?>-container"> <td class="label"><?php echo $this->getElement()->getLabel(); ?></td> <td colspan="10" class="grid tier"> <table cellspacing="0" class="data border" id="group_prices_table"> diff --git a/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product/edit/price/tier.phtml b/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product/edit/price/tier.phtml index 50191a2b11bc413b3b1ba43ac4b0fe0b64d6aac4..5837cd3493df234a30f63d3a23959bb86881faea 100644 --- a/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product/edit/price/tier.phtml +++ b/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product/edit/price/tier.phtml @@ -36,7 +36,7 @@ <?php $_showWebsite = $this->isShowWebsiteColumn(); ?> <?php $_showWebsite= $this->isMultiWebsites(); ?> -<tr> +<tr id="attribute-<?php echo $_htmlId?>-container"> <td class="label"><?php echo $this->getElement()->getLabel() ?></td> <td colspan="10" class="grid tier"> <table cellspacing="0" class="data border" id="tiers_table"> diff --git a/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product/edit/super/config.phtml b/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product/edit/super/config.phtml index e469b12613f9ef8c031e726a07e320d1078b1b83..26870f0fe0090ee184ad1ab0d3f431a77ec5b9b5 100644 --- a/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product/edit/super/config.phtml +++ b/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product/edit/super/config.phtml @@ -23,48 +23,36 @@ * @copyright Copyright (c) 2012 X.commerce, Inc. (http://www.magentocommerce.com) * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) */ - -/** @var $this Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Super_Config */ -if (!count($this->getSelectedAttributes())) { - echo $this->getChildHtml('super_settings'); -} else { + /** @var $this Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Super_Config */ ?> -<?php if (!$this->isReadonly()):?> -<div class="entry-edit"> - <div id="assign_product_warrning" style="display: none;"> - <ul class="messages"> - <li class="error-msg"> - <ul> - <li><?php echo $this->__('Links with associated products will retain only after saving current product.') ?></li> - </ul> - </li> - </ul> - </div> - <div class="entry-edit-head"> - <h4 class="icon-head head-edit-form fieldset-legend"><?php echo Mage::helper('Mage_Catalog_Helper_Data')->__('Create Simple Associated Product') ?></h4> - </div> - <fieldset class="a-right"> - <?php echo $this->getChildHtml('create_empty') ?> <?php echo $this->getChildHtml('create_from_configurable') ?> - </fieldset> -</div> -<div id="<?php echo $this->getHtmlId() ?>_simple_form" class="ignore-validate configurable-simple-product"> -<?php echo $this->getChildHtml('simple'); ?> -</div> -<?php endif;?> +<div id="<?php echo $this->getId()?>"> +<input type="checkbox" id="<?php echo $this->getId()?>-checkbox" name="attributes" + value="" +<?php if ($this->_getProduct()->isConfigurable() || $this->getRequest()->has('attributes')) { + echo ' checked="checked" '; +}?> +/> +<label for="<?php echo $this->getId()?>-checkbox"> + <?php echo Mage::helper('Mage_Catalog_Helper_Data')->__('Does this product have variations?') ?> +</label> +<fieldset> +<?php +echo $this->getChildHtml('super_settings'); +if (count($this->getSelectedAttributes())) { +?> <div class="entry-edit"> <div class="entry-edit-head"> <h4 class="icon-head head-edit-form fieldset-legend"><?php echo Mage::helper('Mage_Catalog_Helper_Data')->__('Super product attributes configuration') ?></h4> </div> <fieldset id="<?php echo $this->getHtmlId() ?>"> <legend><?php echo Mage::helper('Mage_Catalog_Helper_Data')->__('Super product attributes configuration') ?></legend> - <input type="hidden" id="<?php echo $this->getHtmlId() ?>_save_links" name="configurable_products_data" value=""/> <input type="hidden" id="<?php echo $this->getHtmlId() ?>_save_attributes" name="configurable_attributes_data" /> <ul class="messages"> <li class="notice-msg"> <ul><li><?php echo Mage::helper('Mage_Catalog_Helper_Data')->__('Price values for options should be specified in system base currency.')?></li></ul> - <ul><li><?php echo Mage::helper('Mage_Catalog_Helper_Data')->__('Attrribute names can be specified per store.')?></li></ul> + <ul><li><?php echo Mage::helper('Mage_Catalog_Helper_Data')->__('Attribute names can be specified per store.')?></li></ul> </li> </ul> <ul id="<?php echo $this->getHtmlId() ?>_attributes" class="super-attributes"> @@ -141,19 +129,179 @@ if (!count($this->getSelectedAttributes())) { <div class="template no-display" id="<?php echo $this->getHtmlId() ?>_simple_pricing_view"> <?php echo Mage::helper('Mage_Catalog_Helper_Data')->__('Price') ?> <strong>'{{value}}'</strong> </div> -<?php echo $this->getGridHtml() ?> -<script type="text/javascript"> -var superProduct = new Product.Configurable(<?php echo $this->getAttributesJson() ?>,<?php echo $this->getLinksJson() ?>,'<?php echo $this->getHtmlId() ?>_',<?php echo $this->getGridJsObject() ?>, <?php echo ( $this->isReadonly() ? 'true' : 'false'); ?>); -superProduct.createEmptyUrl = '<?php echo $this->getNewEmptyProductUrl() ?>'; -superProduct.createNormalUrl = '<?php echo $this->getNewProductUrl() ?>'; -superProduct.createQuickUrl = '<?php echo $this->getQuickCreationUrl() ?>'; -Validation.add( - 'validate-configurable', - '<?php echo $this->escapeJs(Mage::helper('Mage_Catalog_Helper_Data')->__('Product with this combination of attributes already associated to configurable.')) ?>', - superProduct.checkCreationUniqueAttributes.bind(superProduct) -) +<div id="product-variations-matrix" class="grid" style="margin:20px 0"> +<?php + $variations = $this->getVariations(); + $usedProductAttributes = $this->getSelectedAttributes(); +?> + <table cellspacing="0"> + <thead> + <tr class="headings"> + <th width="180">Product Name</th> + <th width="180">Price</th> + <th width="220">SKU</th> + <th width="180">Quantity</th> + <th width="180">Weight</th> +<?php + foreach ($usedProductAttributes as $attribute) { + /** @var $attribute Mage_Catalog_Model_Resource_Eav_Attribute */ + echo '<th>', $attribute->getStoreLabel(), '</th>', PHP_EOL; + } +?> + <th class="a-center" width="55">Include</th> + </tr> + </thead> + <tbody> +<?php + $isEven = true; + + $productByUsedAttributes = array(); + foreach ($this->_getProduct()->getTypeInstance()->getUsedProducts($this->_getProduct()) as $product) { + $keys = array(); + foreach ($usedProductAttributes as $attribute) { + /** @var $attribute Mage_Catalog_Model_Resource_Eav_Attribute */ + $keys[] = $product->getData($attribute->getAttributeCode()); + } + $productByUsedAttributes[implode('-', $keys)] = $product; + } + + foreach ($variations as $variation) { + $attributeValues = array(); + $attributeLabels = array(); + foreach ($usedProductAttributes as $attribute) { + /** @var $attribute Mage_Catalog_Model_Resource_Eav_Attribute */ + $attributeValues[$attribute->getAttributeCode()] = $variation[$attribute->getId()]['value']; + $attributeLabels[$attribute->getAttributeCode()] = $variation[$attribute->getId()]['label']; + } + $key = implode('-', $attributeValues); + if (isset($productByUsedAttributes[$key])) { + $product = $productByUsedAttributes[$key]; +?> + <tr class="<?php echo $isEven ? 'even' : '' ?>"> + <td class="associated-matrix-product-name"><?php echo $product->getName()?></td> + <td class="associated-matrix-product-price"><?php echo $product->getPrice()?></td> + <td><span class="associated-matrix-product-sku"><?php echo $product->getSku()?></span> + <button class="choose-product" + data-attributes="<?php echo $this->escapeHtml($this->helper('Mage_Core_Helper_Data')->jsonEncode($attributeValues)); ?>" + style="float:right"> + Choose + </button> + </td> + <td class="associated-matrix-product-qty"><?php echo $product->getStockItem()->getQty()?></td> + <td class="associated-matrix-product-weight"><?php echo $product->getWeight()?></td> + <td><?php echo implode('</td><td>', $attributeLabels)?></td> + <td class="a-center"><input type="checkbox" name="associated_product_ids[]" value="<?php echo $product->getId()?>" class="checkbox associated-matrix-product-id" checked="checked"></td> + </tr> +<?php + } else { +?> + <tr class="<?php echo $isEven ? 'even' : '' ?>"> + <td class="associated-matrix-product-name"></td> + <td class="associated-matrix-product-price"></td> + <td><span class="associated-matrix-product-sku"></span> + <button class="choose-product" + data-attributes="<?php echo $this->escapeHtml($this->helper('Mage_Core_Helper_Data')->jsonEncode($attributeValues)); ?>" + style="float:right"> + Choose + </button> + </td> + <td class="associated-matrix-product-qty"></td> + <td class="associated-matrix-product-weight"></td> +<!-- <td><input class="associated-matrix-product-name" value="--><?php //echo $this->_getProduct()->getName(), ' ', implode(' ', $attributeValues)?><!--"></td>--> +<!-- <td><input class="associated-matrix-product-price" value=""></td>--> +<!-- <td><input class="associated-matrix-product-sku" value="--><?php //echo $this->_getProduct()->getSku(), '-', implode('-', $attributeValues)?><!--">--> +<!-- <button class="choose-product"--> +<!-- data-attributes="--><?php //echo $this->escapeHtml($this->helper('Mage_Core_Helper_Data')->jsonEncode($attributeValues)); ?><!--"--> +<!-- style="float:right">--> +<!-- Choose--> +<!-- </button>--> +<!-- </td>--> +<!-- <td><input class="associated-matrix-product-qty" value=""></td>--> +<!-- <td><input class="associated-matrix-product-weight" value=""></td>--> + <td><?php echo implode('</td><td>', $attributeLabels)?></td> + <td class="a-center"><input type="checkbox" name="associated_product_ids[]" value="" class="checkbox associated-matrix-product-id" disabled="disabled"></td> + </tr> +<?php + } + $isEven = !$isEven; + } +?> + </tbody> + </table> +</div> + +<div id="associated-products-container" data-used-attributes="<?php echo $this->escapeHtml($this->helper('Mage_Core_Helper_Data')->jsonEncode($this->getAttributes())); ?>" style="display: none;"> + <?php echo $this->getGridHtml(); ?> +</div> +<script type="text/javascript"> + var superProduct = new Product.Configurable(jQuery('#associated-products-container').data('usedAttributes'), <?php echo $this->getLinksJson() ?>,'<?php echo $this->getHtmlId() ?>_',<?php echo $this->getGridJsObject() ?>, <?php echo ( $this->isReadonly() ? 'true' : 'false'); ?>); </script> <div><input type="hidden" name="affect_configurable_product_attributes" value="1" /></div> -<?php } ?> \ No newline at end of file +<?php } ?> +</fieldset> +</div> +<script type="text/javascript"> +jQuery(function($) { + var usedAttributes = jQuery('#associated-products-container').data('usedAttributes') || []; + $("#<?php echo $this->getId()?>-checkbox").on('click change', function() { + var $fieldset = $("#<?php echo $this->getId()?> > fieldset"); + if ($(this).is(':checked')) { + $fieldset.show(); + $("#<?php echo $this->getId()?> input[name='attributes[]']").removeAttr('disabled'); + $('#qty').attr('disabled', true); + $.each(usedAttributes, function() { + $('#attribute-' + this.attribute_code + '-container select').attr('disabled', true); + }); + } else { + $('#qty').removeAttr('disabled'); + $("#<?php echo $this->getId()?> input[name='attributes[]']").attr('disabled', true); + $.each(usedAttributes, function() { + $('#attribute-' + this.attribute_code + '-container select').removeAttr('disabled'); + }); + $fieldset.hide(); + } + }).trigger('change'); + + var $gridDialog = $('#associated-products-container').dialog({ + title:'Select Associated Product', + autoOpen:false, + minWidth:980, + modal:true, + resizable:true + }); + + $('#product-variations-matrix').on('click', '.choose-product', function(event) { + event.preventDefault(); + var grid = window.<?php echo $this->getGridJsObject() ?>; + var $button = $(this); + grid.reloadParams = { + 'filter': $button.data('attributes'), + 'attributes[]': usedAttributes.map(function(el) { return el.attribute_id; }) + }; + grid.reload(null, function() { + $gridDialog.dialog('open') + }); + + grid.rowClickCallback = function(grid, event) { + if (!this.rows || !this.rows.length) { + return; + } + var $matrixRow = $button.parents('tr'); + var $gridRow = $(event.target).parents('tr'); + var matrixClass = '.associated-matrix-product-'; + var associatedClass = '.associated-product-'; + var productFields = ['name', 'price', 'sku', 'qty', 'weight', 'id']; + + $.each(productFields, function() { + var target = $matrixRow.find(matrixClass + this), + value = $.trim($gridRow.find(associatedClass + this).text()); + target[target.is('input') ? 'val' : 'html'](value); + }); + $matrixRow.find(matrixClass + 'id').attr('checked', true).removeAttr('disabled'); + $gridDialog.dialog('close'); + }; + }); +}); +</script> diff --git a/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product/tab/inventory.phtml b/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product/tab/inventory.phtml index c97fb1d0a7848f21037cbd84e51b8a4493a1a4b0..5a871bc0b058b3d1ca72bbb84c6b258ad7ba5321 100644 --- a/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product/tab/inventory.phtml +++ b/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product/tab/inventory.phtml @@ -23,6 +23,7 @@ * @copyright Copyright (c) 2012 X.commerce, Inc. (http://www.magentocommerce.com) * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) */ + /** @var $this Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Inventory */ ?> <?php if ($this->isReadonly()):?> <?php $_readonly = ' disabled="disabled" ';?> @@ -54,14 +55,14 @@ <?php endif; ?> </tr> -<?php if(!$this->getProduct()->isComposite()): ?> +<?php if (!$this->getProduct()->isComposite() || $this->getProduct()->isConfigurable()): ?> <tr> - <td class="label"><label for="inventory_qty"><?php echo Mage::helper('Mage_Catalog_Helper_Data')->__('Qty') ?><span class="required">*</span></label></td> + <td class="label"><label for="inventory_qty"><?php echo Mage::helper('Mage_Catalog_Helper_Data')->__('Qty') ?></label></td> <td class="value"> <?php if (!$_readonly):?> <input type="hidden" id="original_inventory_qty" name="<?php echo $this->getFieldSuffix() ?>[stock_data][original_inventory_qty]" value="<?php echo $this->getFieldValue('qty')*1 ?>"/> <?php endif;?> - <input type="text" class="input-text required-entry validate-number" id="inventory_qty" name="<?php echo $this->getFieldSuffix() ?>[stock_data][qty]" value="<?php echo $this->getFieldValue('qty')*1 ?>" <?php echo $_readonly;?>/> + <input type="text" class="input-text validate-number" id="inventory_qty" name="<?php echo $this->getFieldSuffix() ?>[stock_data][qty]" value="<?php echo $this->getFieldValue('qty')*1 ?>" <?php echo $_readonly;?>/> </td> <?php if (!Mage::app()->isSingleStoreMode()): ?> <td class="value scope-label"><?php echo Mage::helper('Mage_Adminhtml_Helper_Data')->__('[GLOBAL]') ?></td> diff --git a/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/type-switcher.js b/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/type-switcher.js new file mode 100644 index 0000000000000000000000000000000000000000..bec8629de4deae4a2282aeb7f6ac7889eb28f525 --- /dev/null +++ b/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/type-switcher.js @@ -0,0 +1,112 @@ +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @category Mage + * @package Mage_Adminhtml + * @copyright Copyright (c) 2012 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +(function ($) { + /** + * Type Switcher + * + * @param {object} data + * @constructor + */ + var TypeSwitcher = function (data) { + this._data = data; + this.$type = $('#type_id'); + this.$weight = $('#' + data.weight_id); + this.$is_virtual = $('#' + data.is_virtual_id); + this.$tab = $('#' + data.tab_id); + + // @todo: move $is_virtual checkbox logic to separate widget + if (this.$is_virtual.is(':checked')) { + this.baseType = { + virtual: this.$type.val(), + real: 'simple' + }; + } else { + this.baseType = { + virtual: 'virtual', + real: this.$type.val() + }; + } + }; + $.extend(TypeSwitcher.prototype, { + /** @lends {TypeSwitcher} */ + + /** + * Bind event + */ + bindAll: function () { + var self = this, + $type = this.$type; + $type.on('change', function() { + self._switchToType($(this).val()); + }); + + this.$is_virtual.on('change click', function() { + if ($(this).is(':checked')) { + $type.val(self.baseType.virtual).trigger('change'); + self.$weight.addClass('ignore-validate').attr('disabled', 'disabled'); + self.$tab.show(); + } else { + $type.val(self.baseType.real).trigger('change'); + self.$weight.removeClass('ignore-validate').removeAttr('disabled', 'disabled'); + self.$tab.hide(); + } + }).trigger('change'); + }, + + /** + * Get element bu code + * @param {string} code + * @return {jQuery|HTMLElement} + */ + getElementByCode: function(code) { + return $('#attribute-' + code + '-container'); + }, + + /** + * Show/hide elements based on type + * + * @param {string} typeCode + * @private + */ + _switchToType: function(typeCode) { + var self = this, + attributes = this._data.attributes; + + $.each(attributes, function(code, applyTo) { + var attrContainer = self.getElementByCode(code); + var $inputs = attrContainer.find('select, input, textarea'); + if (applyTo.length === 0 || $.inArray(typeCode, applyTo) !== -1) { + attrContainer.show(); + $inputs.removeClass('ignore-validate'); + } else { + attrContainer.hide(); + $inputs.addClass('ignore-validate'); + } + }); + } + }); + // export to global scope + window.TypeSwitcher = TypeSwitcher; +})(jQuery); diff --git a/app/code/core/Mage/Adminhtml/view/adminhtml/cms/browser/content/uploader.phtml b/app/code/core/Mage/Adminhtml/view/adminhtml/cms/browser/content/uploader.phtml index 6472897edf5fca23a8f666829fe38b3f09e84f74..38b7e6d4533a648edb3630952c540a7dce07b7c1 100644 --- a/app/code/core/Mage/Adminhtml/view/adminhtml/cms/browser/content/uploader.phtml +++ b/app/code/core/Mage/Adminhtml/view/adminhtml/cms/browser/content/uploader.phtml @@ -61,7 +61,7 @@ }, sequentialUploads: true, acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i, - maxFileSize: <?php echo Mage::helper('Mage_Core_Helper_File_Storage')->getMaxFileSize(); ?>, + maxFileSize: <?php echo Mage::helper('Mage_Core_Helper_File_Storage')->getMaxFileSize()?>, add: function(e, data) { $.each(data.files, function (index, file) { data.fileId = Math.random().toString(36).substr(2,9); diff --git a/app/code/core/Mage/Adminhtml/view/adminhtml/css/ui-lightness/jquery-ui-1.8.21.custom.css b/app/code/core/Mage/Adminhtml/view/adminhtml/css/ui-lightness/jquery-ui-1.8.21.custom.css index 7780a8240f3e7f6eedf20ed9e90a42da4825d21d..56e68d5d1763efc6b2248d4d0e97ae1d8a6de5ab 100644 --- a/app/code/core/Mage/Adminhtml/view/adminhtml/css/ui-lightness/jquery-ui-1.8.21.custom.css +++ b/app/code/core/Mage/Adminhtml/view/adminhtml/css/ui-lightness/jquery-ui-1.8.21.custom.css @@ -17,8 +17,8 @@ * versions in the future. If you wish to customize Magento for your * needs please refer to http://www.magentocommerce.com for more information. * - * @category design - * @package Mage_A + * @category Mage + * @package Mage_Adminhtml * @copyright Copyright (c) 2012 X.commerce, Inc. (http://www.magentocommerce.com) * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) */ @@ -1675,4 +1675,4 @@ button.ui-button::-moz-focus-inner { .ui-progressbar .ui-progressbar-value { margin: -1px; height: 100%; -} \ No newline at end of file +} diff --git a/app/code/core/Mage/Backend/Block/Widget/Grid/ColumnSet.php b/app/code/core/Mage/Backend/Block/Widget/Grid/ColumnSet.php index c5500dd97505ab18523d9c117ade7a940a931155..440962e4b4b94cd2a1f5409bb716fbc17dd1852b 100644 --- a/app/code/core/Mage/Backend/Block/Widget/Grid/ColumnSet.php +++ b/app/code/core/Mage/Backend/Block/Widget/Grid/ColumnSet.php @@ -134,6 +134,8 @@ class Mage_Backend_Block_Widget_Grid_ColumnSet extends Mage_Core_Block_Template * @param Mage_Core_Model_Factory_Helper $helperFactory * @param Mage_Backend_Helper_Data $helper * @param Mage_Backend_Model_Widget_Grid_Row_UrlGeneratorFactory $generatorFactory + * @param Mage_Backend_Model_Widget_Grid_SubTotals $subtotals + * @param Mage_Backend_Model_Widget_Grid_Totals $totals * @param array $data * * @SuppressWarnings(PHPMD.ExcessiveParameterList) diff --git a/app/code/core/Mage/Backend/view/adminhtml/widget/form.phtml b/app/code/core/Mage/Backend/view/adminhtml/widget/form.phtml index 3a166b33df10c653b01b468743caba9e3a43782e..805fc32ba2e72ac43b0e8b37b6c3b44772304ca3 100644 --- a/app/code/core/Mage/Backend/view/adminhtml/widget/form.phtml +++ b/app/code/core/Mage/Backend/view/adminhtml/widget/form.phtml @@ -23,6 +23,7 @@ * @copyright Copyright (c) 2012 X.commerce, Inc. (http://www.magentocommerce.com) * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) */ +/** $this Mage_Backend_Block_Widget_Form */ ?> <div class="entry-edit"> <?php echo $this->getFormHtml();?> diff --git a/app/code/core/Mage/Bundle/Model/Product/Type.php b/app/code/core/Mage/Bundle/Model/Product/Type.php index da2889e3dc0718e90763a6006d3771ae527b4366..a3e68cea000414ce35af66f8975bb32189fdaaf1 100644 --- a/app/code/core/Mage/Bundle/Model/Product/Type.php +++ b/app/code/core/Mage/Bundle/Model/Product/Type.php @@ -1073,4 +1073,13 @@ class Mage_Bundle_Model_Product_Type extends Mage_Catalog_Model_Product_Type_Abs return null; } + + /** + * Delete data specific for Bundle product type + * + * @param Mage_Catalog_Model_Product $product + */ + public function deleteTypeSpecificData(Mage_Catalog_Model_Product $product) + { + } } diff --git a/app/code/core/Mage/Catalog/Block/Product/Configurable/AssociatedSelector/Backend/Grid/ColumnSet.php b/app/code/core/Mage/Catalog/Block/Product/Configurable/AssociatedSelector/Backend/Grid/ColumnSet.php new file mode 100644 index 0000000000000000000000000000000000000000..b80c319eff758350f81e72be2e17334172b1fe36 --- /dev/null +++ b/app/code/core/Mage/Catalog/Block/Product/Configurable/AssociatedSelector/Backend/Grid/ColumnSet.php @@ -0,0 +1,157 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @category Mage + * @package Mage_Catalog + * @copyright Copyright (c) 2012 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +/** + * Block representing set of columns in product grid + * + * @category Mage + * @package Mage_Catalog + * @author Magento Core Team <core@magentocommerce.com> + * + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ +class Mage_Catalog_Block_Product_Configurable_AssociatedSelector_Backend_Grid_ColumnSet + extends Mage_Backend_Block_Widget_Grid_ColumnSet +{ + /** + * Registry instance + * + * @var Mage_Core_Model_Registry + */ + protected $_registryManager; + + /** + * Product type configurable instance + * + * @var Mage_Catalog_Model_Product_Type_Configurable + */ + protected $_productType; + + /** + * @param Mage_Core_Controller_Request_Http $request + * @param Mage_Core_Model_Layout $layout + * @param Mage_Core_Model_Event_Manager $eventManager + * @param Mage_Core_Model_Url $urlBuilder + * @param Mage_Core_Model_Translate $translator + * @param Mage_Core_Model_Cache $cache + * @param Mage_Core_Model_Design_Package $designPackage + * @param Mage_Core_Model_Session $session + * @param Mage_Core_Model_Store_Config $storeConfig + * @param Mage_Core_Controller_Varien_Front $frontController + * @param Mage_Core_Model_Factory_Helper $helperFactory + * @param Mage_Backend_Model_Widget_Grid_Row_UrlGeneratorFactory $generatorFactory + * @param Mage_Core_Model_Registry $registryManager, + * @param Mage_Catalog_Model_Product_Type_Configurable $productType + * @param Mage_Backend_Model_Widget_Grid_SubTotals $subtotals + * @param Mage_Backend_Model_Widget_Grid_Totals $totals + * @param array $data + * + * @SuppressWarnings(PHPMD.ExcessiveParameterList) + */ + public function __construct( + Mage_Core_Controller_Request_Http $request, + Mage_Core_Model_Layout $layout, + Mage_Core_Model_Event_Manager $eventManager, + Mage_Core_Model_Url $urlBuilder, + Mage_Core_Model_Translate $translator, + Mage_Core_Model_Cache $cache, + Mage_Core_Model_Design_Package $designPackage, + Mage_Core_Model_Session $session, + Mage_Core_Model_Store_Config $storeConfig, + Mage_Core_Controller_Varien_Front $frontController, + Mage_Core_Model_Factory_Helper $helperFactory, + Mage_Backend_Model_Widget_Grid_Row_UrlGeneratorFactory $generatorFactory, + Mage_Core_Model_Registry $registryManager, + Mage_Backend_Model_Widget_Grid_SubTotals $subtotals, + Mage_Backend_Model_Widget_Grid_Totals $totals, + Mage_Catalog_Model_Product_Type_Configurable $productType, + array $data = array() + ) { + parent::__construct($request, $layout, $eventManager, $urlBuilder, $translator, $cache, $designPackage, + $session, $storeConfig, $frontController, $helperFactory, $helperFactory->get('Mage_Backend_Helper_Data'), + $generatorFactory, $subtotals, $totals, $data); + + $this->_registryManager = $registryManager; + $this->_productType = $productType; + } + + /** + * Retrieve currently edited product object + * + * @return Mage_Catalog_Model_Product + */ + protected function _getProduct() + { + return $this->_registryManager->registry('current_product'); + } + + /** + * Preparing layout + * + * @return Mage_Catalog_Block_Product_Configurable_AssociatedSelector_Backend_Grid_ColumnSet + */ + protected function _prepareLayout() + { + parent::_prepareLayout(); + + $product = $this->_getProduct(); + $attributes = $this->_productType->getUsedProductAttributes($product); + /** @var $attribute Mage_Catalog_Model_Entity_Attribute */ + foreach ($attributes as $attribute) { + /** @var $block Mage_Backend_Block_Widget_Grid_Column */ + $block = $this->addChild( + $attribute->getAttributeCode(), + 'Mage_Backend_Block_Widget_Grid_Column', + array( + 'header' => $attribute->getStoreLabel(), + 'index' => $attribute->getAttributeCode(), + 'type' => 'options', + 'options' => $this->getOptions($attribute->getSource()), + 'sortable' => false + ) + ); + $block->setId($attribute->getAttributeCode())->setGrid($this); + } + return $this; + } + + /** + * Get option as hash + * + * @param Mage_Eav_Model_Entity_Attribute_Source_Abstract $sourceModel + * @return array + */ + private function getOptions(Mage_Eav_Model_Entity_Attribute_Source_Abstract $sourceModel) + { + $result = array(); + foreach ($sourceModel->getAllOptions() as $option) { + if ($option['value'] != '') { + $result[$option['value']] = $option['label']; + } + } + return $result; + } +} diff --git a/app/code/core/Mage/Catalog/Helper/Product.php b/app/code/core/Mage/Catalog/Helper/Product.php index d1abbe48bca2a2d77746f9d814b2f3fc8b7c5025..6aa423be44afb5b3b81cc64dda0a38b7acb22696 100644 --- a/app/code/core/Mage/Catalog/Helper/Product.php +++ b/app/code/core/Mage/Catalog/Helper/Product.php @@ -37,7 +37,7 @@ class Mage_Catalog_Helper_Product extends Mage_Core_Helper_Url const XML_PATH_AUTO_GENERATE_MASK = 'catalog/fields_masks'; const XML_PATH_UNASSIGNABLE_ATTRIBUTES = 'global/catalog/product/attributes/unassignable'; const XML_PATH_ATTRIBUTES_USED_IN_AUTOGENERATION = 'global/catalog/product/attributes/used_in_autogeneration'; - + const XML_PATH_PRODUCT_TYPE_SWITCHER_LABEL = 'global/catalog/product/attributes/weight/type_switcher/label'; /** * Flag that shows if Magento has to check product to be saleable (enabled and/or inStock) @@ -505,4 +505,14 @@ class Mage_Catalog_Helper_Product extends Mage_Core_Helper_Url { return array_keys(Mage::getConfig()->getNode(self::XML_PATH_ATTRIBUTES_USED_IN_AUTOGENERATION)->asArray()); } + + /** + * Get label for virtual control + * + * @return string + */ + public function getTypeSwitcherControlLabel() + { + return $this->__((string)Mage::getConfig()->getNode(self::XML_PATH_PRODUCT_TYPE_SWITCHER_LABEL)); + } } diff --git a/app/code/core/Mage/Catalog/Model/Observer.php b/app/code/core/Mage/Catalog/Model/Observer.php index 0e7d59879041fc3452db43a4eb1dc4a18f39c53a..3663638d1732f65f41b46909f4607327850c87b5 100644 --- a/app/code/core/Mage/Catalog/Model/Observer.php +++ b/app/code/core/Mage/Catalog/Model/Observer.php @@ -49,7 +49,8 @@ class Mage_Catalog_Model_Observer /** @var $categoryFlatHelper Mage_Catalog_Helper_Category_Flat */ $categoryFlatHelper = Mage::helper('Mage_Catalog_Helper_Category_Flat'); if ($categoryFlatHelper->isAvailable() && $categoryFlatHelper->isBuilt()) { - Mage::getResourceModel('Mage_Catalog_Model_Resource_Category_Flat')->synchronize(null, array($store->getId())); + Mage::getResourceModel('Mage_Catalog_Model_Resource_Category_Flat') + ->synchronize(null, array($store->getId())); } Mage::getResourceSingleton('Mage_Catalog_Model_Resource_Product')->refreshEnabledIndex($store); } @@ -71,7 +72,8 @@ class Mage_Catalog_Model_Observer /** @var $categoryFlatHelper Mage_Catalog_Helper_Category_Flat */ $categoryFlatHelper = Mage::helper('Mage_Catalog_Helper_Category_Flat'); if ($categoryFlatHelper->isAvailable() && $categoryFlatHelper->isBuilt()) { - Mage::getResourceModel('Mage_Catalog_Model_Resource_Category_Flat')->synchronize(null, array($store->getId())); + Mage::getResourceModel('Mage_Catalog_Model_Resource_Category_Flat') + ->synchronize(null, array($store->getId())); } Mage::getResourceModel('Mage_Catalog_Model_Resource_Product')->refreshEnabledIndex($store); return $this; @@ -93,7 +95,8 @@ class Mage_Catalog_Model_Observer /** @var $categoryFlatHelper Mage_Catalog_Helper_Category_Flat */ $categoryFlatHelper = Mage::helper('Mage_Catalog_Helper_Category_Flat'); if ($categoryFlatHelper->isAvailable() && $categoryFlatHelper->isBuilt()) { - Mage::getResourceModel('Mage_Catalog_Model_Resource_Category_Flat')->synchronize(null, array($store->getId())); + Mage::getResourceModel('Mage_Catalog_Model_Resource_Category_Flat') + ->synchronize(null, array($store->getId())); } } } @@ -131,7 +134,8 @@ class Mage_Catalog_Model_Observer /** @var $categoryFlatHelper Mage_Catalog_Helper_Category_Flat */ $categoryFlatHelper = Mage::helper('Mage_Catalog_Helper_Category_Flat'); if ($categoryFlatHelper->isAvailable() && $categoryFlatHelper->isBuilt()) { - Mage::getResourceModel('Mage_Catalog_Model_Resource_Category_Flat')->move($categoryId, $prevParentId, $parentId); + Mage::getResourceModel('Mage_Catalog_Model_Resource_Category_Flat') + ->move($categoryId, $prevParentId, $parentId); } return $this; } @@ -211,7 +215,10 @@ class Mage_Catalog_Model_Observer */ public function addCatalogToTopmenuItems(Varien_Event_Observer $observer) { - $this->_addCategoriesToMenu(Mage::helper('Mage_Catalog_Helper_Category')->getStoreCategories(), $observer->getMenu()); + $this->_addCategoriesToMenu( + Mage::helper('Mage_Catalog_Helper_Category')->getStoreCategories(), + $observer->getMenu() + ); } /** @@ -270,4 +277,22 @@ class Mage_Catalog_Model_Observer $categoryPathIds = explode(',', $currentCategory->getPathInStore()); return in_array($category->getId(), $categoryPathIds); } -} \ No newline at end of file + + /** + * Change product type on the fly depending on selected options + * + * @param Varien_Event_Observer $observer + */ + public function transitionProductType(Varien_Event_Observer $observer) + { + $product = $observer->getProduct(); + $isTransitionalType = $product->getTypeId() === Mage_Catalog_Model_Product_Type::TYPE_SIMPLE + || $product->getTypeId() === Mage_Catalog_Model_Product_Type::TYPE_VIRTUAL; + if ($isTransitionalType) { + $product->setTypeId($product->hasIsVirtual() + ? Mage_Catalog_Model_Product_Type::TYPE_VIRTUAL + : Mage_Catalog_Model_Product_Type::TYPE_SIMPLE + ); + } + } +} diff --git a/app/code/core/Mage/Catalog/Model/Product.php b/app/code/core/Mage/Catalog/Model/Product.php index fe1c99d1395ceba99155d62edc52ad24ff74d7ef..14712ff7143692e7516e8a55cad709079bb9020c 100644 --- a/app/code/core/Mage/Catalog/Model/Product.php +++ b/app/code/core/Mage/Catalog/Model/Product.php @@ -31,6 +31,10 @@ * @method Mage_Catalog_Model_Resource_Product _getResource() * @method Mage_Catalog_Model_Product setHasError(bool $value) * @method null|bool getHasError() + * @method Mage_Catalog_Model_Product setTypeId(string $typeId) + * @method string getTypeId() + * @method Mage_Catalog_Model_Product setAssociatedProductIds(array $productIds) + * @method array getAssociatedProductIds() * * @category Mage * @package Mage_Catalog @@ -119,7 +123,7 @@ class Mage_Catalog_Model_Product extends Mage_Catalog_Model_Abstract Mage_Catalog_Model_Resource_Product $resource, Mage_Catalog_Model_Resource_Product_Collection $resourceCollection, array $data = array() - ) { + ) { parent::__construct($eventDispatcher, $cacheManager, $resource, $resourceCollection, $data); } @@ -265,7 +269,7 @@ class Mage_Catalog_Model_Product extends Mage_Catalog_Model_Abstract /** * Set type instance for the product * - * @param Mage_Catalog_Model_Product_Type_Abstract $instance Product type instance + * @param Mage_Catalog_Model_Product_Type_Abstract|null $instance Product type instance * @return Mage_Catalog_Model_Product */ public function setTypeInstance($instance) diff --git a/app/code/core/Mage/Catalog/Model/Product/Attribute/Backend/Stock.php b/app/code/core/Mage/Catalog/Model/Product/Attribute/Backend/Stock.php index 1270db61f68788e22770f01346d27775d7df00b3..92a9a66f57412a021d0c0de4de69ff961d74db91 100644 --- a/app/code/core/Mage/Catalog/Model/Product/Attribute/Backend/Stock.php +++ b/app/code/core/Mage/Catalog/Model/Product/Attribute/Backend/Stock.php @@ -66,15 +66,17 @@ class Mage_Catalog_Model_Product_Attribute_Backend_Stock extends Mage_Eav_Model_ } /** - * Prepare inventory data from custom atribute + * Prepare inventory data from custom attribute * - * @param Varien_Object $object + * @param Mage_Catalog_Model_Product $object * @return Mage_Eav_Model_Entity_Attribute_Backend_Abstract|void */ public function beforeSave($object) { - /** @var $object Mage_Catalog_Model_Product */ $stockData = $object->getData($this->getAttribute()->getAttributeCode()); + if (isset($stockData['qty']) && $stockData['qty'] === '') { + $stockData['qty'] = null; + } if ($object->getStockData() !== null || $stockData !== null) { $object->setStockData(array_replace((array)$object->getStockData(), (array)$stockData)); } diff --git a/app/code/core/Mage/Catalog/Model/Product/Type/Abstract.php b/app/code/core/Mage/Catalog/Model/Product/Type/Abstract.php index a43eae9424876cecbabc07e7766fc74631d98952..d6077ff1010d97c64d2f729c312913a78667722c 100644 --- a/app/code/core/Mage/Catalog/Model/Product/Type/Abstract.php +++ b/app/code/core/Mage/Catalog/Model/Product/Type/Abstract.php @@ -111,6 +111,13 @@ abstract class Mage_Catalog_Model_Product_Type_Abstract */ const OPTION_PREFIX = 'option_'; + /** + * Delete data specific for this product type + * + * @param Mage_Catalog_Model_Product $product + */ + abstract public function deleteTypeSpecificData(Mage_Catalog_Model_Product $product); + /** * Initialize data * @@ -215,11 +222,7 @@ abstract class Mage_Catalog_Model_Product_Type_Abstract if (!$product->hasData($cacheKey)) { $editableAttributes = array(); foreach ($this->getSetAttributes($product) as $attributeCode => $attribute) { - if (!is_array($attribute->getApplyTo()) - || count($attribute->getApplyTo())==0 - || in_array($product->getTypeId(), $attribute->getApplyTo())) { - $editableAttributes[$attributeCode] = $attribute; - } + $editableAttributes[$attributeCode] = $attribute; } $product->setData($cacheKey, $editableAttributes); } @@ -339,7 +342,7 @@ abstract class Mage_Catalog_Model_Product_Type_Abstract } /** - * Process product configuaration + * Process product configuration * * @param Varien_Object $buyRequest * @param Mage_Catalog_Model_Product $product @@ -593,6 +596,13 @@ abstract class Mage_Catalog_Model_Product_Type_Abstract */ public function save($product) { + if ($product->dataHasChangedFor('type_id') && $product->getOrigData('type_id')) { + $oldTypeProduct = clone $product; + $oldTypeInstance = Mage::getSingleton('Mage_Catalog_Model_Product_Type') + ->factory($oldTypeProduct->setTypeId($product->getOrigData('type_id'))); + $oldTypeProduct->setTypeInstance($oldTypeInstance); + $oldTypeInstance->deleteTypeSpecificData($oldTypeProduct); + } return $this; } @@ -773,7 +783,7 @@ abstract class Mage_Catalog_Model_Product_Type_Abstract } /** - * Retrive store filter for associated products + * Retrieve store filter for associated products * * @return int|Mage_Core_Model_Store */ @@ -798,7 +808,7 @@ abstract class Mage_Catalog_Model_Product_Type_Abstract } /** - * Allow for updates of chidren qty's + * Allow for updates of children qty's * (applicable for complicated product types. As default returns false) * * @param Mage_Catalog_Model_Product $product @@ -959,4 +969,14 @@ abstract class Mage_Catalog_Model_Product_Type_Abstract { return isset($this->_helpers[$name]) ? $this->_helpers[$name] : Mage::helper($name); } + + /** + * Determine presence of weight for product type + * + * @return bool + */ + public function hasWeight() + { + return true; + } } diff --git a/app/code/core/Mage/Catalog/Model/Product/Type/Configurable.php b/app/code/core/Mage/Catalog/Model/Product/Type/Configurable.php index f1b4955a8bcd200cff3413b160839a61ecaa5847..2c9eb0ee3214c88874f1f639f67e6cd6b7d00774 100644 --- a/app/code/core/Mage/Catalog/Model/Product/Type/Configurable.php +++ b/app/code/core/Mage/Catalog/Model/Product/Type/Configurable.php @@ -136,40 +136,18 @@ class Mage_Catalog_Model_Product_Type_Configurable extends Mage_Catalog_Model_Pr } /** - * Retrieve product type attributes - * - * @param Mage_Catalog_Model_Product $product - * @return array - */ - public function getEditableAttributes($product) - { - if (is_null($this->_editableAttributes)) { - $this->_editableAttributes = parent::getEditableAttributes($product); - foreach ($this->_editableAttributes as $index => $attribute) { - if ($this->getUsedProductAttributeIds($product) - && in_array($attribute->getAttributeId(), $this->getUsedProductAttributeIds($product))) { - unset($this->_editableAttributes[$index]); - } - } - } - return $this->_editableAttributes; - } - - /** - * Checkin attribute availability for create superproduct + * Check attribute availability for super product creation * * @param Mage_Eav_Model_Entity_Attribute $attribute * @return bool */ public function canUseAttribute(Mage_Eav_Model_Entity_Attribute $attribute) { - $allow = $attribute->getIsGlobal() == Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_GLOBAL + return $attribute->getIsGlobal() == Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_GLOBAL && $attribute->getIsVisible() && $attribute->getIsConfigurable() && $attribute->usesSource() && $attribute->getIsUserDefined(); - - return $allow; } /** @@ -267,6 +245,7 @@ class Mage_Catalog_Model_Product_Type_Configurable extends Mage_Catalog_Model_Pr { $res = array(); foreach ($this->getConfigurableAttributes($product) as $attribute) { + /* @var $attribute Mage_Catalog_Model_Product_Type_Configurable_Attribute */ $res[] = array( 'id' => $attribute->getId(), 'label' => $attribute->getLabel(), @@ -416,27 +395,33 @@ class Mage_Catalog_Model_Product_Type_Configurable extends Mage_Catalog_Model_Pr public function save($product) { parent::save($product); - /** - * Save Attributes Information - */ - if ($data = $product->getConfigurableAttributesData()) { + + /* Save attributes information */ + $data = $product->getConfigurableAttributesData(); + if ($data) { foreach ($data as $attributeData) { - $id = isset($attributeData['id']) ? $attributeData['id'] : null; - Mage::getModel('Mage_Catalog_Model_Product_Type_Configurable_Attribute') - ->setData($attributeData) - ->setId($id) + /** @var $configurableAttribute Mage_Catalog_Model_Product_Type_Configurable_Attribute */ + $configurableAttribute = Mage::getModel('Mage_Catalog_Model_Product_Type_Configurable_Attribute'); + if (isset($attributeData['id'])) { + $configurableAttribute->load($attributeData['id']); + } else { + $configurableAttribute->loadByProductAndAttribute( + $product, + $product->getTypeInstance()->getAttributeById($attributeData['attribute_id'], $product) + ); + } + unset($attributeData['id']); + $configurableAttribute + ->addData($attributeData) ->setStoreId($product->getStoreId()) ->setProductId($product->getId()) ->save(); } } - /** - * Save product relations - */ - $data = $product->getConfigurableProductsData(); - if (is_array($data)) { - $productIds = array_keys($data); + /* Save product relations */ + $productIds = $product->getAssociatedProductIds(); + if (is_array($productIds)) { Mage::getResourceModel('Mage_Catalog_Model_Resource_Product_Type_Configurable') ->saveProducts($product, $productIds); } @@ -866,4 +851,28 @@ class Mage_Catalog_Model_Product_Type_Configurable extends Mage_Catalog_Model_Pr return Mage::getResourceSingleton('Mage_Catalog_Model_Resource_Product_Type_Configurable') ->getConfigurableOptions($product, $this->getUsedProductAttributes($product)); } + + /** + * Check that product of this type has weight + * + * @return bool + */ + public function hasWeight() + { + return false; + } + + /** + * Delete data specific for Configurable product type + * + * @param Mage_Catalog_Model_Product $product + */ + public function deleteTypeSpecificData(Mage_Catalog_Model_Product $product) + { + Mage::getResourceModel('Mage_Catalog_Model_Resource_Product_Type_Configurable') + ->saveProducts($product, array()); + /** @var $configurableAttribute Mage_Catalog_Model_Product_Type_Configurable_Attribute */ + $configurableAttribute = Mage::getModel('Mage_Catalog_Model_Product_Type_Configurable_Attribute'); + $configurableAttribute->deleteByProduct($product); + } } diff --git a/app/code/core/Mage/Catalog/Model/Product/Type/Configurable/Attribute.php b/app/code/core/Mage/Catalog/Model/Product/Type/Configurable/Attribute.php index ae0b5170f8a0ad164e653ec183811089954d1e41..9be8dc8e53ff8aaf234c3979cba7d721565984f6 100644 --- a/app/code/core/Mage/Catalog/Model/Product/Type/Configurable/Attribute.php +++ b/app/code/core/Mage/Catalog/Model/Product/Type/Configurable/Attribute.php @@ -37,6 +37,9 @@ * @method int getPosition() * @method Mage_Catalog_Model_Product_Type_Configurable_Attribute setPosition(int $value) * + * @method Mage_Catalog_Model_Product_Type_Configurable_Attribute setProductAttribute(Mage_Eav_Model_Entity_Attribute_Abstract $value) + * @method Mage_Eav_Model_Entity_Attribute_Abstract getProductAttribute() + * * @category Mage * @package Mage_Catalog * @author Magento Core Team <core@magentocommerce.com> @@ -97,4 +100,28 @@ class Mage_Catalog_Model_Product_Type_Configurable_Attribute extends Mage_Core_M $this->_getResource()->savePrices($this); return $this; } + + /** + * Load counfigurable attribute by product and product's attribute + * + * @param Mage_Catalog_Model_Product $product + * @param Mage_Eav_Model_Attribute $attribute + */ + public function loadByProductAndAttribute($product, $attribute) + { + $id = $this->_getResource()->getIdByProductIdAndAttributeId($this, $product->getId(), $attribute->getId()); + if ($id) { + $this->load($id); + } + } + + /** + * Delete configurable attributes by product id + * + * @param Mage_Catalog_Model_Product $product + */ + public function deleteByProduct($product) + { + $this->_getResource()->deleteAttributesByProductId($product->getId()); + } } diff --git a/app/code/core/Mage/Catalog/Model/Product/Type/Grouped.php b/app/code/core/Mage/Catalog/Model/Product/Type/Grouped.php index 44fdbe2d809d3bb7c141672a22f8eb97ab299d2e..cea326dab93473423a2be034811534c3048889e7 100644 --- a/app/code/core/Mage/Catalog/Model/Product/Type/Grouped.php +++ b/app/code/core/Mage/Catalog/Model/Product/Type/Grouped.php @@ -363,4 +363,23 @@ class Mage_Catalog_Model_Product_Type_Grouped extends Mage_Catalog_Model_Product return $options; } + + /** + * Check that product of this type has weight + * + * @return bool + */ + public function hasWeight() + { + return false; + } + + /** + * Delete data specific for Grouped product type + * + * @param Mage_Catalog_Model_Product $product + */ + public function deleteTypeSpecificData(Mage_Catalog_Model_Product $product) + { + } } diff --git a/app/code/core/Mage/Catalog/Model/Product/Type/Simple.php b/app/code/core/Mage/Catalog/Model/Product/Type/Simple.php index 0a5e88677d0c2b7b00fcdf50938a370390eb8c18..f6693a86e48d9ca766570b2213b55c9878a314b5 100644 --- a/app/code/core/Mage/Catalog/Model/Product/Type/Simple.php +++ b/app/code/core/Mage/Catalog/Model/Product/Type/Simple.php @@ -33,4 +33,12 @@ */ class Mage_Catalog_Model_Product_Type_Simple extends Mage_Catalog_Model_Product_Type_Abstract { + /** + * Delete data specific for Simple product type + * + * @param Mage_Catalog_Model_Product $product + */ + public function deleteTypeSpecificData(Mage_Catalog_Model_Product $product) + { + } } diff --git a/app/code/core/Mage/Catalog/Model/Product/Type/Virtual.php b/app/code/core/Mage/Catalog/Model/Product/Type/Virtual.php index 171915669be145876e8931819e513be09cdb28cf..990109ef3ae8ac1923342e5e9a4827c85a89a257 100644 --- a/app/code/core/Mage/Catalog/Model/Product/Type/Virtual.php +++ b/app/code/core/Mage/Catalog/Model/Product/Type/Virtual.php @@ -43,4 +43,23 @@ class Mage_Catalog_Model_Product_Type_Virtual extends Mage_Catalog_Model_Product { return true; } + + /** + * Check that product of this type has weight + * + * @return bool + */ + public function hasWeight() + { + return false; + } + + /** + * Delete data specific for Virtual product type + * + * @param Mage_Catalog_Model_Product $product + */ + public function deleteTypeSpecificData(Mage_Catalog_Model_Product $product) + { + } } diff --git a/app/code/core/Mage/Catalog/Model/Resource/Product/Collection/AssociatedProduct.php b/app/code/core/Mage/Catalog/Model/Resource/Product/Collection/AssociatedProduct.php new file mode 100644 index 0000000000000000000000000000000000000000..0010d06b36dabecc08ae0b2298b8de74b9327d46 --- /dev/null +++ b/app/code/core/Mage/Catalog/Model/Resource/Product/Collection/AssociatedProduct.php @@ -0,0 +1,128 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @category Mage + * @package Mage_Catalog + * @copyright Copyright (c) 2012 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +/** + * Catalog compare item resource model + * + * @category Mage + * @package Mage_Catalog + * @author Magento Core Team <core@magentocommerce.com> + */ +class Mage_Catalog_Model_Resource_Product_Collection_AssociatedProduct + extends Mage_Catalog_Model_Resource_Product_Collection +{ + /** + * Registry instance + * + * @var Mage_Core_Model_Registry + */ + protected $_registryManager; + + /** + * Product type configurable instance + * + * @var Mage_Catalog_Model_Product_Type_Configurable + */ + protected $_productType; + + /** + * Configuration helper instance + * + * @var Mage_Catalog_Helper_Product_Configuration + */ + protected $_configurationHelper; + + /** + * Collection constructor + * + * @param Mage_Core_Model_Registry $registryManager + * @param Mage_Catalog_Model_Product_Type_Configurable $productType + * @param Mage_Catalog_Helper_Product_Configuration $configurationHelper + * @param null $resource + */ + public function __construct( + Mage_Core_Model_Registry $registryManager, + Mage_Catalog_Model_Product_Type_Configurable $productType, + Mage_Catalog_Helper_Product_Configuration $configurationHelper, + $resource = null + ) { + $this->_registryManager = $registryManager; + $this->_productType = $productType; + $this->_configurationHelper = $configurationHelper; + + parent::__construct($resource); + } + + /** + * Get product type + * + * @return Mage_Catalog_Model_Product_Type_Configurable + */ + public function getProductType() + { + return $this->_productType; + } + + /** + * Retrieve currently edited product object + * + * @return mixed + */ + private function getProduct() + { + return $this->_registryManager->registry('current_product'); + } + + /** + * Prepare select for load + * + * @param Varien_Db_Select $select + * @return string + */ + public function _prepareSelect(Varien_Db_Select $select) + { + $allowProductTypes = array(); + foreach ($this->_configurationHelper->getConfigurableAllowedTypes() as $type) { + $allowProductTypes[] = $type->getName(); + } + + $product = $this->getProduct(); + + $this->addAttributeToSelect('name') + ->addAttributeToSelect('sku') + ->addAttributeToSelect('attribute_set_id') + ->addAttributeToSelect('type_id') + ->addAttributeToSelect('price') + ->addAttributeToSelect('weight') + ->addFieldToFilter('attribute_set_id', $product->getAttributeSetId()) + ->addFieldToFilter('type_id', $allowProductTypes) + ->addFieldToFilter($product->getIdFieldName(), array('neq' => $product->getId())) + ->addFilterByRequiredOptions() + ->joinAttribute('name', 'catalog_product/name', 'entity_id', null, 'inner'); + + return parent::_prepareSelect($select); + } +} diff --git a/app/code/core/Mage/Catalog/Model/Resource/Product/Collection/AssociatedProductUpdater.php b/app/code/core/Mage/Catalog/Model/Resource/Product/Collection/AssociatedProductUpdater.php new file mode 100644 index 0000000000000000000000000000000000000000..012750cbe00b42485c28cc84b60378d95c2fd89b --- /dev/null +++ b/app/code/core/Mage/Catalog/Model/Resource/Product/Collection/AssociatedProductUpdater.php @@ -0,0 +1,71 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @category Mage + * @package Mage_Catalog + * @copyright Copyright (c) 2012 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +/** + * Associated product resource collection + * + * @category Mage + * @package Mage_Catalog + * @author Magento Core Team <core@magentocommerce.com> + */ +class Mage_Catalog_Model_Resource_Product_Collection_AssociatedProductUpdater + implements Mage_Core_Model_Layout_Argument_UpdaterInterface +{ + /** + * Stock Item instance + * + * @var Mage_CatalogInventory_Model_Resource_Stock_Item + */ + protected $_stockItem; + + /** + * Updater constructor + * + * @param Mage_CatalogInventory_Model_Resource_Stock_Item $stockItem + */ + public function __construct(Mage_CatalogInventory_Model_Resource_Stock_Item $stockItem) + { + $this->_stockItem = $stockItem; + } + + /** + * Add filtration by qty and stock availability + * + * @param Mage_Catalog_Model_Resource_Product_Collection_AssociatedProduct $collection + * @return mixed + */ + public function update($collection) + { + $this->_stockItem->addCatalogInventoryToProductCollection( + $collection, + array( + 'qty' => 'qty', + 'inventory_in_stock' => 'is_in_stock' + ) + ); + return $collection; + } +} diff --git a/app/code/core/Mage/Catalog/Model/Resource/Product/Type/Configurable.php b/app/code/core/Mage/Catalog/Model/Resource/Product/Type/Configurable.php index 162f83c66a3fe7265cc4ccb16a7c55cea13deb3f..e189a8f9e50badd59c0c67f79214b72ce39f3af1 100755 --- a/app/code/core/Mage/Catalog/Model/Resource/Product/Type/Configurable.php +++ b/app/code/core/Mage/Catalog/Model/Resource/Product/Type/Configurable.php @@ -46,7 +46,7 @@ class Mage_Catalog_Model_Resource_Product_Type_Configurable extends Mage_Core_Mo /** * Save configurable product relations * - * @param Mage_Catalog_Model_Product|int $mainProduct the parent id + * @param Mage_Catalog_Model_Product $mainProduct the parent id * @param array $productIds the children id array * @return Mage_Catalog_Model_Resource_Product_Type_Configurable */ @@ -56,8 +56,6 @@ class Mage_Catalog_Model_Resource_Product_Type_Configurable extends Mage_Core_Mo if ($mainProduct instanceof Mage_Catalog_Model_Product) { $mainProductId = $mainProduct->getId(); $isProductInstance = true; - } else { - $mainProductId = $mainProduct; } $old = $mainProduct->getTypeInstance()->getUsedProductIds($mainProduct); diff --git a/app/code/core/Mage/Catalog/Model/Resource/Product/Type/Configurable/Attribute.php b/app/code/core/Mage/Catalog/Model/Resource/Product/Type/Configurable/Attribute.php index d0c0addd4b31d273f6d9b953c87a783615ce7e91..114b35fcb4885612390fb26205958be7d5abb4ca 100755 --- a/app/code/core/Mage/Catalog/Model/Resource/Product/Type/Configurable/Attribute.php +++ b/app/code/core/Mage/Catalog/Model/Resource/Product/Type/Configurable/Attribute.php @@ -277,4 +277,35 @@ class Mage_Catalog_Model_Resource_Product_Type_Configurable_Attribute extends Ma return $adapter->fetchCol($select, $bind); } + + /** + * Get configurable attribute id by product id and attribute id + * + * @param Mage_Catalog_Model_Product_Type_Configurable_Attribute $attribute + * @param $productId + * @param $attributeId + * + * @return string + */ + public function getIdByProductIdAndAttributeId($attribute, $productId, $attributeId) + { + $select = $this->_getReadAdapter()->select() + ->from($this->getMainTable(), $this->getIdFieldName()) + ->where('product_id = ?', $productId) + ->where('attribute_id = ?', $attributeId); + return $this->_getReadAdapter()->fetchOne($select); + } + + /** + * Delete configurable attributes by product id + * + * @param $productId + */ + public function deleteAttributesByProductId($productId) + { + $select = $this->_getReadAdapter()->select() + ->from($this->getMainTable(), $this->getIdFieldName()) + ->where('product_id = ?', $productId); + $this->_getWriteAdapter()->query($this->_getReadAdapter()->deleteFromSelect($select, $this->getMainTable())); + } } diff --git a/app/code/core/Mage/Catalog/Model/Resource/Product/Type/Configurable/Attribute/Collection.php b/app/code/core/Mage/Catalog/Model/Resource/Product/Type/Configurable/Attribute/Collection.php index b4b5b5aeb20748b6e3f2cedd8573825dabad34a1..1b2a014a36a34cb4976d11f473101bd19c76947d 100755 --- a/app/code/core/Mage/Catalog/Model/Resource/Product/Type/Configurable/Attribute/Collection.php +++ b/app/code/core/Mage/Catalog/Model/Resource/Product/Type/Configurable/Attribute/Collection.php @@ -92,6 +92,16 @@ class Mage_Catalog_Model_Resource_Product_Type_Configurable_Attribute_Collection return $this->addFieldToFilter('product_id', $product->getId()); } + /** + * Get product type + * + * @return Mage_Catalog_Model_Product_Type_Configurable + */ + private function getProductType() + { + return Mage::getSingleton('Mage_Catalog_Model_Product_Type_Configurable'); + } + /** * Set order collection by Position * @@ -145,7 +155,7 @@ class Mage_Catalog_Model_Resource_Product_Type_Configurable_Attribute_Collection protected function _addProductAttributes() { foreach ($this->_items as $item) { - $productAttribute = $this->getProduct()->getTypeInstance() + $productAttribute = $this->getProductType() ->getAttributeById($item->getAttributeId(), $this->getProduct()); $item->setProductAttribute($productAttribute); } @@ -159,7 +169,7 @@ class Mage_Catalog_Model_Resource_Product_Type_Configurable_Attribute_Collection */ public function _addAssociatedProductFilters() { - $this->getProduct()->getTypeInstance() + $this->getProductType() ->getUsedProducts($this->getProduct(), $this->getColumnValues('attribute_id')); // Filter associated products return $this; } @@ -241,7 +251,7 @@ class Mage_Catalog_Model_Resource_Product_Type_Configurable_Attribute_Collection } $values = array(); - $usedProducts = $this->getProduct()->getTypeInstance()->getUsedProducts($this->getProduct()); + $usedProducts = $this->getProductType()->getUsedProducts($this->getProduct()); if ($usedProducts) { foreach ($this->_items as $item) { $productAttribute = $item->getProductAttribute(); diff --git a/app/code/core/Mage/Catalog/controllers/Product/CompareController.php b/app/code/core/Mage/Catalog/controllers/Product/CompareController.php index 79f35e9e3875803bbe1a4354ed50d62178e9c645..09ab4724f7dbdf970269c087c474724e9bb1137b 100644 --- a/app/code/core/Mage/Catalog/controllers/Product/CompareController.php +++ b/app/code/core/Mage/Catalog/controllers/Product/CompareController.php @@ -120,14 +120,15 @@ class Mage_Catalog_Product_CompareController extends Mage_Core_Controller_Front_ } $item->loadByProduct($product); - + /** @var $helper Mage_Catalog_Helper_Product_Compare */ + $helper = Mage::helper('Mage_Catalog_Helper_Product_Compare'); if($item->getId()) { $item->delete(); Mage::getSingleton('Mage_Catalog_Model_Session')->addSuccess( - $this->__('The product %s has been removed from comparison list.', $product->getName()) + $this->__('The product %s has been removed from comparison list.', $helper->escapeHtml($product->getName())) ); - Mage::dispatchEvent('catalog_product_compare_remove_product', array('product'=>$item)); - Mage::helper('Mage_Catalog_Helper_Product_Compare')->calculate(); + Mage::dispatchEvent('catalog_product_compare_remove_product', array('product' => $item)); + $helper->calculate(); } } } diff --git a/app/code/core/Mage/Catalog/data/catalog_setup/data-upgrade-1.6.0.0.19-1.6.0.0.20.php b/app/code/core/Mage/Catalog/data/catalog_setup/data-upgrade-1.6.0.0.19-1.6.0.0.20.php new file mode 100644 index 0000000000000000000000000000000000000000..382cb74376df22c031b9f2d97d194eb6054f773b --- /dev/null +++ b/app/code/core/Mage/Catalog/data/catalog_setup/data-upgrade-1.6.0.0.19-1.6.0.0.20.php @@ -0,0 +1,39 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @category Mage + * @package Mage_Catalog + * @copyright Copyright (c) 2012 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +/** @var $this Mage_Catalog_Model_Resource_Setup */ +$applyTo = array_merge( + explode(',', $this->getAttribute(Mage_Catalog_Model_Product::ENTITY, 'weight', 'apply_to')), + array(Mage_Catalog_Model_Product_Type::TYPE_VIRTUAL, Mage_Catalog_Model_Product_Type::TYPE_CONFIGURABLE) +); + +$this->updateAttribute( + Mage_Catalog_Model_Product::ENTITY, + 'weight', + 'frontend_input_renderer', + 'Mage_Adminhtml_Block_Catalog_Product_Helper_Form_Weight_Renderer' +); +$this->updateAttribute(Mage_Catalog_Model_Product::ENTITY, 'weight', 'apply_to', implode(',', $applyTo)); diff --git a/app/code/core/Mage/Catalog/etc/config.xml b/app/code/core/Mage/Catalog/etc/config.xml index fcf9dccdd6c00280bd312e3875bc4a21b950dd61..4a529c650a1eb4938f22276da59f9294b8b1d348 100644 --- a/app/code/core/Mage/Catalog/etc/config.xml +++ b/app/code/core/Mage/Catalog/etc/config.xml @@ -28,7 +28,7 @@ <config> <modules> <Mage_Catalog> - <version>1.6.0.0.19</version> + <version>1.6.0.0.20</version> <active>true</active> <codePool>core</codePool> <depends> @@ -87,6 +87,14 @@ </catalog_add_topmenu_items> </observers> </page_block_html_topmenu_gethtml_before> + <catalog_product_transition_product_type> + <observers> + <type_transition> + <class>Mage_Catalog_Model_Observer</class> + <method>transitionProductType</method> + </type_transition> + </observers> + </catalog_product_transition_product_type> </events> <catalog> <product> @@ -227,11 +235,19 @@ <description/> <sku/> </used_in_autogeneration> + <weight> + <type_switcher translate="label"> + <label>Virtual</label> + </type_switcher> + </weight> </attributes> </product> <content> <tempate_filter>Mage_Catalog_Model_Template_Filter</tempate_filter> </content> + <suggested_categories> + <limit>10</limit> + </suggested_categories> </catalog> <eav_attributes> <catalog_product> diff --git a/app/code/core/Mage/CatalogInventory/Block/Adminhtml/Form/Field/Stock.php b/app/code/core/Mage/CatalogInventory/Block/Adminhtml/Form/Field/Stock.php index 16e4cc1cfc6de831962b108ef51f00754f7eed98..70cceee5e7e1e20102dcd77c1aa7110fe8eb27a1 100644 --- a/app/code/core/Mage/CatalogInventory/Block/Adminhtml/Form/Field/Stock.php +++ b/app/code/core/Mage/CatalogInventory/Block/Adminhtml/Form/Field/Stock.php @@ -102,10 +102,10 @@ class Mage_CatalogInventory_Block_Adminhtml_Form_Field_Stock extends Varien_Data */ public function setValue($value) { - if (isset($value['qty'])) { + if (is_array($value) && isset($value['qty'])) { $this->_qty->setValue($value['qty']); } - if (isset($value['is_in_stock'])) { + if (is_array($value) && isset($value['is_in_stock'])) { parent::setValue($value['is_in_stock']); } return $this; @@ -129,7 +129,7 @@ class Mage_CatalogInventory_Block_Adminhtml_Form_Field_Stock extends Varien_Data */ protected function _isProductComposite() { - if (null === $this->_isProductComposite) { + if ($this->_isProductComposite === null) { $this->_isProductComposite = $this->_qty->getForm()->getDataObject()->isComposite(); } return $this->_isProductComposite; @@ -142,7 +142,7 @@ class Mage_CatalogInventory_Block_Adminhtml_Form_Field_Stock extends Varien_Data */ protected function _disableFields() { - if (!$this->_isProductComposite() && null === $this->_qty->getValue()) { + if (!$this->_isProductComposite() && $this->_qty->getValue() === null) { $this->setDisabled('disabled'); } if ($this->_isProductComposite()) { @@ -164,16 +164,20 @@ class Mage_CatalogInventory_Block_Adminhtml_Form_Field_Stock extends Varien_Data <script> //<![CDATA[ jQuery(function($) { - var qty = $('#$quantityFieldId'); - var isInStock = $('#$inStockFieldId'); - var disabler = function(){ + var qty = $('#$quantityFieldId'), + isInStock = $('#$inStockFieldId'), + manageStock = $('#inventory_manage_stock').removeClass('disabled').removeAttr('disabled'), + useConfigManageStock = $('#inventory_use_config_manage_stock'); + + var disabler = function() { if ('' === qty.val()) { isInStock.attr('disabled', 'disabled'); + manageStock.val(0); } else { isInStock.removeAttr('disabled'); + manageStock.val(1); } }; - qty.bind('keyup change blur', disabler); //Associated fields var fieldsAssociations = { @@ -189,7 +193,7 @@ class Mage_CatalogInventory_Block_Adminhtml_Form_Field_Stock extends Varien_Data $('#' + getKeyByValue(fieldsAssociations, id)).val($(this).val()); } }; - //Get key by value form object + //Get key by value from object var getKeyByValue = function(object, value) { var returnVal = false; $.each(object, function(objKey, objValue){ @@ -201,10 +205,12 @@ class Mage_CatalogInventory_Block_Adminhtml_Form_Field_Stock extends Varien_Data }; $.each(fieldsAssociations, function(generalTabField, advancedTabField) { $('#' + generalTabField + ', #' + advancedTabField) - .bind('focus blur change keyup click', filler); + .bind('focus blur change keyup click', filler) + .bind('keyup change blur', disabler); filler.call($('#' + generalTabField)); filler.call($('#' + advancedTabField)); }); + disabler(); }); //]]> </script> diff --git a/app/code/core/Mage/CatalogInventory/Model/Resource/Stock/Item.php b/app/code/core/Mage/CatalogInventory/Model/Resource/Stock/Item.php index 9309b102a0a2c1ae8a4d4969e1393bb222f3c482..8a8065bef302c1ad680e93aa116ebbed86b4f6fb 100755 --- a/app/code/core/Mage/CatalogInventory/Model/Resource/Stock/Item.php +++ b/app/code/core/Mage/CatalogInventory/Model/Resource/Stock/Item.php @@ -84,22 +84,27 @@ class Mage_CatalogInventory_Model_Resource_Stock_Item extends Mage_Core_Model_Re * Add join for catalog in stock field to product collection * * @param Mage_Catalog_Model_Resource_Product_Collection $productCollection + * @param array $columns * @return Mage_CatalogInventory_Model_Resource_Stock_Item */ - public function addCatalogInventoryToProductCollection($productCollection) + public function addCatalogInventoryToProductCollection($productCollection, $columns = null) { - $adapter = $this->_getReadAdapter(); - $isManageStock = (int)Mage::getStoreConfig(Mage_CatalogInventory_Model_Stock_Item::XML_PATH_MANAGE_STOCK); - $stockExpr = $adapter->getCheckSql('cisi.use_config_manage_stock = 1', $isManageStock, 'cisi.manage_stock'); - $stockExpr = $adapter->getCheckSql("({$stockExpr} = 1)", 'cisi.is_in_stock', '1'); + if ($columns === null) { + $adapter = $this->_getReadAdapter(); + $isManageStock = (int)Mage::getStoreConfig(Mage_CatalogInventory_Model_Stock_Item::XML_PATH_MANAGE_STOCK); + $stockExpr = $adapter->getCheckSql('cisi.use_config_manage_stock = 1', $isManageStock, 'cisi.manage_stock'); + $stockExpr = $adapter->getCheckSql("({$stockExpr} = 1)", 'cisi.is_in_stock', '1'); + + $columns = array( + 'is_saleable' => new Zend_Db_Expr($stockExpr), + 'inventory_in_stock' => 'is_in_stock' + ); + } $productCollection->joinTable( array('cisi' => 'cataloginventory_stock_item'), 'product_id=entity_id', - array( - 'is_saleable' => new Zend_Db_Expr($stockExpr), - 'inventory_in_stock' => 'is_in_stock' - ), + $columns, null, 'left' ); diff --git a/app/code/core/Mage/CatalogInventory/etc/config.xml b/app/code/core/Mage/CatalogInventory/etc/config.xml index c48b5adde3c07ea5e343df4575db079566fc286c..ed090f9b1623cd4adc0164c40ba0501f7f9c3d19 100644 --- a/app/code/core/Mage/CatalogInventory/etc/config.xml +++ b/app/code/core/Mage/CatalogInventory/etc/config.xml @@ -28,7 +28,7 @@ <config> <modules> <Mage_CatalogInventory> - <version>1.6.0.0.2</version> + <version>1.6.0.0.3</version> <active>true</active> <codePool>core</codePool> <depends> @@ -254,6 +254,13 @@ </translate> </frontend> <adminhtml> + <layout> + <updates> + <cataloginventory module="Mage_CatalogInventory"> + <file>layout.xml</file> + </cataloginventory> + </updates> + </layout> <translate> <modules> <Mage_CatalogInventory> diff --git a/app/code/core/Mage/CatalogInventory/sql/cataloginventory_setup/upgrade-1.6.0.0.2-1.6.0.0.3.php b/app/code/core/Mage/CatalogInventory/sql/cataloginventory_setup/upgrade-1.6.0.0.2-1.6.0.0.3.php new file mode 100644 index 0000000000000000000000000000000000000000..7cf529288f8be1e845e4eba89c7177c1e3cbc697 --- /dev/null +++ b/app/code/core/Mage/CatalogInventory/sql/cataloginventory_setup/upgrade-1.6.0.0.2-1.6.0.0.3.php @@ -0,0 +1,42 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @category Mage + * @package Mage_CatalogInventory + * @copyright Copyright (c) 2012 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +/** @var $this Mage_Eav_Model_Entity_Setup */ + +$this->getConnection() + ->changeColumn( + $this->getTable('cataloginventory_stock_item'), + 'qty', + 'qty', + array( + 'TYPE' => Varien_Db_Ddl_Table::TYPE_DECIMAL, + 'LENGTH' => '12,4', + 'UNSIGNED' => false, + 'NULLABLE' => true, + 'DEFAULT' => null, + 'COMMENT' => 'Qty' + ) + ); diff --git a/app/code/core/Mage/CatalogInventory/view/adminhtml/layout.xml b/app/code/core/Mage/CatalogInventory/view/adminhtml/layout.xml new file mode 100644 index 0000000000000000000000000000000000000000..407576fcd25f1601a1aa93c11834c3964c30f977 --- /dev/null +++ b/app/code/core/Mage/CatalogInventory/view/adminhtml/layout.xml @@ -0,0 +1,62 @@ +<?xml version="1.0"?> +<!-- +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Academic Free License (AFL 3.0) + * that is bundled with this package in the file LICENSE_AFL.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/afl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @category design + * @package default_default + * @copyright Copyright (c) 2012 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) + */ +--> +<layout> + <adminhtml_catalog_product_superconfig_config> + <reference name="admin.product.edit.tab.super.config.grid"> + <arguments> + <dataSource> + <updater>Mage_Catalog_Model_Resource_Product_Collection_AssociatedProductUpdater</updater> + </dataSource> + </arguments> + <reference name="admin.product.edit.tab.super.config.grid.columnSet"> + <block type="Mage_Backend_Block_Widget_Grid_Column" as="inventory_in_stock" after="admin.product.edit.tab.super.config.grid.sku"> + <arguments> + <header translate="true" module="Mage_Core">Inventory</header> + <type>text</type> + <index>inventory_in_stock</index> + <id>inventory_in_stock</id> + <filter>0</filter> + <sortable>1</sortable> + <renderer>Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Super_Config_Grid_Renderer_Inventory</renderer> + </arguments> + </block> + <block type="Mage_Backend_Block_Widget_Grid_Column" as="qty" after="admin.product.edit.tab.super.config.grid.sku"> + <arguments> + <header translate="true" module="Mage_Core">Qty</header> + <type>text</type> + <index>qty</index> + <id>qty</id> + <filter>0</filter> + <sortable>1</sortable> + <column_css_class>associated-product-qty</column_css_class> + </arguments> + </block> + </reference> + </reference> + </adminhtml_catalog_product_superconfig_config> +</layout> diff --git a/app/code/core/Mage/Cms/Model/Wysiwyg/Config.php b/app/code/core/Mage/Cms/Model/Wysiwyg/Config.php index 77f50fbab5017821e60d72a89dc898969731a9e6..a83f3662e0f2e7a07336fe773619b113c201c514 100644 --- a/app/code/core/Mage/Cms/Model/Wysiwyg/Config.php +++ b/app/code/core/Mage/Cms/Model/Wysiwyg/Config.php @@ -117,12 +117,7 @@ class Mage_Cms_Model_Wysiwyg_Config extends Varien_Object */ public function isEnabled() { - $storeId = $this->getStoreId(); - if (!is_null($storeId)) { - $wysiwygState = Mage::getStoreConfig('cms/wysiwyg/enabled', $storeId); - } else { - $wysiwygState = Mage::getStoreConfig('cms/wysiwyg/enabled'); - } + $wysiwygState = Mage::getStoreConfig('cms/wysiwyg/enabled', $this->getStoreId()); return in_array($wysiwygState, array(self::WYSIWYG_ENABLED, self::WYSIWYG_HIDDEN)); } diff --git a/app/code/core/Mage/Core/Block/Messages.php b/app/code/core/Mage/Core/Block/Messages.php index a48dd30b7629e16565b8d53319a608b6e8a08775..852665b80e0c0ae43d661c6b0fc855b5996e522d 100644 --- a/app/code/core/Mage/Core/Block/Messages.php +++ b/app/code/core/Mage/Core/Block/Messages.php @@ -168,7 +168,7 @@ class Mage_Core_Block_Messages extends Mage_Core_Block_Template } /** - * Adding new nitice message + * Adding new notice message * * @param string $message * @return Mage_Core_Block_Messages @@ -208,12 +208,13 @@ class Mage_Core_Block_Messages extends Mage_Core_Block_Template * @param string $type * @return string */ - public function getHtml($type=null) + public function getHtml($type = null) { $html = '<' . $this->_messagesFirstLevelTagName . ' id="admin_messages">'; foreach ($this->getMessages($type) as $message) { - $html.= '<' . $this->_messagesSecondLevelTagName . ' class="'.$message->getType().'-msg" ' . $this->getUiId('message') . '>' - . ($this->_escapeMessageFlag) ? $this->escapeHtml($message->getText()) : $message->getText() + $html .= '<' . $this->_messagesSecondLevelTagName . ' class="' . $message->getType() . '-msg" ' + . $this->getUiId('message') . '>' + . $this->_escapeMessageFlag ? $this->escapeHtml($message->getText()) : $message->getText() . '</' . $this->_messagesSecondLevelTagName . '>'; } $html .= '</' . $this->_messagesFirstLevelTagName . '>'; @@ -223,8 +224,7 @@ class Mage_Core_Block_Messages extends Mage_Core_Block_Template /** * Retrieve messages in HTML format grouped by type * - * @param string $type - * @return string + * @return string */ public function getGroupedHtml() { diff --git a/app/code/core/Mage/Core/Model/App.php b/app/code/core/Mage/Core/Model/App.php index b5fc7d264beeea27d75a452d0511a6193eb7e224..fe2f10aad37fcfee365fd0d5424b0db039689799 100644 --- a/app/code/core/Mage/Core/Model/App.php +++ b/app/code/core/Mage/Core/Model/App.php @@ -47,6 +47,9 @@ class Mage_Core_Model_App const DEFAULT_ERROR_HANDLER = 'mageCoreErrorHandler'; + /** + * Default application locale + */ const DISTRO_LOCALE_CODE = 'en_US'; /** @@ -505,7 +508,8 @@ class Mage_Core_Model_App * * @param string $scopeCode code of default scope (website/store_group/store code) * @param string $scopeType type of default scope (website/group/store) - * @return unknown_type + * @return Mage_Core_Model_App + * @throws Mage_Core_Model_Store_Exception */ protected function _initCurrentStore($scopeCode, $scopeType) { @@ -536,7 +540,8 @@ class Mage_Core_Model_App $this->_checkGetStore($scopeType); } $this->_useSessionInUrl = $this->getStore()->getConfig( - Mage_Core_Model_Session_Abstract::XML_PATH_USE_FRONTEND_SID); + Mage_Core_Model_Session_Abstract::XML_PATH_USE_FRONTEND_SID + ); Mage::dispatchEvent('core_app_init_current_store_after'); return $this; } @@ -554,6 +559,7 @@ class Mage_Core_Model_App /** * Check get store * + * @param string $type * @return Mage_Core_Model_App */ protected function _checkGetStore($type) @@ -586,11 +592,9 @@ class Mage_Core_Model_App $curStoreObj = $this->_stores[$this->_currentStore]; if ($type == 'website' && $storeObj->getWebsiteId() == $curStoreObj->getWebsiteId()) { $this->_currentStore = $store; - } - elseif ($type == 'group' && $storeObj->getGroupId() == $curStoreObj->getGroupId()) { + } elseif ($type == 'group' && $storeObj->getGroupId() == $curStoreObj->getGroupId()) { $this->_currentStore = $store; - } - elseif ($type == 'store') { + } elseif ($type == 'store') { $this->_currentStore = $store; } @@ -620,13 +624,16 @@ class Mage_Core_Model_App $store = $this->getCookie()->get(Mage_Core_Model_Store::COOKIE_NAME); if ($store && isset($this->_stores[$store]) && $this->_stores[$store]->getId() - && $this->_stores[$store]->getIsActive()) { + && $this->_stores[$store]->getIsActive() + ) { if ($type == 'website' - && $this->_stores[$store]->getWebsiteId() == $this->_stores[$this->_currentStore]->getWebsiteId()) { + && $this->_stores[$store]->getWebsiteId() == $this->_stores[$this->_currentStore]->getWebsiteId() + ) { $this->_currentStore = $store; } if ($type == 'group' - && $this->_stores[$store]->getGroupId() == $this->_stores[$this->_currentStore]->getGroupId()) { + && $this->_stores[$store]->getGroupId() == $this->_stores[$this->_currentStore]->getGroupId() + ) { $this->_currentStore = $store; } if ($type == 'store') { @@ -643,7 +650,6 @@ class Mage_Core_Model_App /** * Init store, group and website collections - * */ protected function _initStores() { @@ -808,7 +814,7 @@ class Mage_Core_Model_App } /** - * Redeclare custom error handler + * Re-declare custom error handler * * @param string $handler * @return Mage_Core_Model_App @@ -832,7 +838,7 @@ class Mage_Core_Model_App } /** - * Loding part of area data + * Loading part of area data * * @param string $area * @param string $part @@ -878,7 +884,7 @@ class Mage_Core_Model_App return $this->_store; } - if (!isset($id) || ''===$id || $id === true) { + if (!isset($id) || '' === $id || $id === true) { $id = $this->_currentStore; } if ($id instanceof Mage_Core_Model_Store) { @@ -916,13 +922,11 @@ class Mage_Core_Model_App { try { return $this->getStore($id); - } - catch (Exception $e) { + } catch (Exception $e) { if ($this->_currentStore) { $this->getRequest()->setActionName('noRoute'); return new Varien_Object(); - } - else { + } else { Mage::throwException(Mage::helper('Mage_Core_Helper_Data')->__('Requested invalid store "%s"', $id)); } } @@ -944,8 +948,7 @@ class Mage_Core_Model_App } if ($codeKey) { $stores[$store->getCode()] = $store; - } - else { + } else { $stores[$store->getId()] = $store; } } @@ -989,9 +992,11 @@ class Mage_Core_Model_App /** * Retrieve application website object * + * @param null|bool|int|string|Mage_Core_Model_Website $id * @return Mage_Core_Model_Website + * @throws Mage_Core_Exception */ - public function getWebsite($id=null) + public function getWebsite($id = null) { if (is_null($id)) { $id = $this->getStore()->getWebsiteId(); @@ -1009,9 +1014,9 @@ class Mage_Core_Model_App throw Mage::exception('Mage_Core', 'Invalid website id requested.'); } } elseif (is_string($id)) { - $websiteConfig = $this->_config->getNode('websites/'.$id); + $websiteConfig = $this->_config->getNode('websites/' . $id); if (!$websiteConfig) { - throw Mage::exception('Mage_Core', 'Invalid website code requested: '.$id); + throw Mage::exception('Mage_Core', 'Invalid website code requested: ' . $id); } $website->loadConfig($id); } @@ -1031,8 +1036,7 @@ class Mage_Core_Model_App } if ($codeKey) { $websites[$website->getCode()] = $website; - } - else { + } else { $websites[$website->getId()] = $website; } } @@ -1044,9 +1048,11 @@ class Mage_Core_Model_App /** * Retrieve application store group object * + * @param null|Mage_Core_Model_Store_Group|string $id * @return Mage_Core_Model_Store_Group + * @throws Mage_Core_Exception */ - public function getGroup($id=null) + public function getGroup($id = null) { if (is_null($id)) { $id = $this->getStore()->getGroup()->getId(); @@ -1080,7 +1086,7 @@ class Mage_Core_Model_App } /** - * Retrive layout object + * Retrieve layout object * * @return Mage_Core_Model_Layout */ @@ -1127,7 +1133,6 @@ class Mage_Core_Model_App */ public function getBaseCurrencyCode() { - //return Mage::getStoreConfig(Mage_Directory_Model_Currency::XML_PATH_CURRENCY_BASE, 0); return (string) Mage::app()->getConfig() ->getNode('default/' . Mage_Directory_Model_Currency::XML_PATH_CURRENCY_BASE); } @@ -1196,12 +1201,13 @@ class Mage_Core_Model_App /** * Saving cache data * - * @param mixed $data - * @param string $id - * @param array $tags - * @return Mage_Core_Model_App + * @param mixed $data + * @param string $id + * @param array $tags + * @param bool $lifeTime + * @return Mage_Core_Model_App */ - public function saveCache($data, $id, $tags=array(), $lifeTime=false) + public function saveCache($data, $id, $tags = array(), $lifeTime = false) { $this->_cache->save($data, $id, $tags, $lifeTime); return $this; @@ -1225,7 +1231,7 @@ class Mage_Core_Model_App * @param array $tags * @return Mage_Core_Model_App */ - public function cleanCache($tags=array()) + public function cleanCache($tags = array()) { $this->_cache->clean($tags); Mage::dispatchEvent('application_clean_cache', array('tags' => $tags)); @@ -1233,11 +1239,12 @@ class Mage_Core_Model_App } /** - * Check whether to use cache for specific component - * - * @return boolean - */ - public function useCache($type=null) + * Check whether to use cache for specific component + * + * @param null|string $type + * @return boolean + */ + public function useCache($type = null) { return $this->_cache->canUse($type); } @@ -1257,10 +1264,11 @@ class Mage_Core_Model_App /** * Deletes all session files * + * @return Mage_Core_Model_App */ public function cleanAllSessions() { - if (session_module_name()=='files') { + if (session_module_name() == 'files') { $dir = session_save_path(); mageDelTree($dir); } @@ -1329,7 +1337,7 @@ class Mage_Core_Model_App public function dispatchEvent($eventName, $args) { - foreach ($this->_events as $area=>$events) { + foreach ($this->_events as $area => $events) { if (!isset($events[$eventName])) { $eventConfig = $this->getConfig()->getEventConfig($area, $eventName); if (!$eventConfig) { @@ -1347,7 +1355,7 @@ class Mage_Core_Model_App $events[$eventName]['observers'] = $observers; $this->_events[$area][$eventName]['observers'] = $observers; } - if (false===$events[$eventName]) { + if (false === $events[$eventName]) { continue; } else { $event = new Varien_Event($args); @@ -1355,8 +1363,8 @@ class Mage_Core_Model_App $observer = new Varien_Event_Observer(); } - foreach ($events[$eventName]['observers'] as $obsName=>$obs) { - $observer->setData(array('event'=>$event)); + foreach ($events[$eventName]['observers'] as $obsName => $obs) { + $observer->setData(array('event' => $event)); Magento_Profiler::start('OBSERVER:' . $obsName); switch ($obs['type']) { case 'disabled': @@ -1395,7 +1403,7 @@ class Mage_Core_Model_App if (method_exists($object, $method)) { $object->$method($observer); } elseif (Mage::getIsDeveloperMode()) { - Mage::throwException('Method "'.$method.'" is not defined in "'.get_class($object).'"'); + Mage::throwException('Method "' . $method . '" is not defined in "' . get_class($object) . '"'); } return $this; } @@ -1506,13 +1514,11 @@ class Mage_Core_Model_App } if ($codeKey) { $groups[$group->getCode()] = $group; - } - else { + } else { $groups[$group->getId()] = $group; } } } - return $groups; } @@ -1530,7 +1536,6 @@ class Mage_Core_Model_App * Unset website by id from app cache * * @param null|bool|int|string|Mage_Core_Model_Website $id - * @return void */ public function clearWebsiteCache($id = null) { diff --git a/app/code/core/Mage/Core/Model/Email/Template.php b/app/code/core/Mage/Core/Model/Email/Template.php index e60edb1aef15e0c5abad7dbe1f7642a677c64d57..784e5bd9b1aed26d7ecba958340fca998e6499ca 100644 --- a/app/code/core/Mage/Core/Model/Email/Template.php +++ b/app/code/core/Mage/Core/Model/Email/Template.php @@ -93,7 +93,6 @@ class Mage_Core_Model_Email_Template extends Mage_Core_Model_Template /** * Initialize email template model - * */ protected function _construct() { @@ -190,7 +189,7 @@ class Mage_Core_Model_Email_Template extends Mage_Core_Model_Template * Load default email template * * @param string $templateId - * @param string $locale + * @return Mage_Core_Model_Email_Template */ public function loadDefault($templateId) { @@ -200,7 +199,7 @@ class Mage_Core_Model_Email_Template extends Mage_Core_Model_Template } $data = &$defaultTemplates[$templateId]; - $this->setTemplateType($data['type']=='html' ? self::TYPE_HTML : self::TYPE_TEXT); + $this->setTemplateType($data['type'] == 'html' ? self::TYPE_HTML : self::TYPE_TEXT); $module = Mage::getConfig()->determineOmittedNamespace($data['@']['module'], true); $templateText = $this->loadBaseContents($module, $data['file']); @@ -250,13 +249,13 @@ class Mage_Core_Model_Email_Template extends Mage_Core_Model_Template } /** - * Retrive default templates from config + * Retrieve default templates from config * * @return array */ static public function getDefaultTemplates() { - if(is_null(self::$_defaultTemplates)) { + if (is_null(self::$_defaultTemplates)) { self::$_defaultTemplates = Mage::getConfig()->getNode(self::XML_PATH_TEMPLATE_EMAIL)->asArray(); } @@ -295,6 +294,7 @@ class Mage_Core_Model_Email_Template extends Mage_Core_Model_Template /** * Return template id + * * return int|null */ public function getId() @@ -304,7 +304,9 @@ class Mage_Core_Model_Email_Template extends Mage_Core_Model_Template /** * Set id of template + * * @param int $value + * @return Mage_Core_Model_Email_Template */ public function setId($value) { @@ -336,8 +338,9 @@ class Mage_Core_Model_Email_Template extends Mage_Core_Model_Template /** * Process email template code * - * @param array $variables - * @return string + * @param array $variables + * @return string + * @throws Exception */ public function getProcessedTemplate(array $variables = array()) { @@ -463,7 +466,7 @@ class Mage_Core_Model_Email_Template extends Mage_Core_Model_Template } if ($returnPathEmail !== null) { - $mailTransport = new Zend_Mail_Transport_Sendmail("-f".$returnPathEmail); + $mailTransport = new Zend_Mail_Transport_Sendmail("-f" . $returnPathEmail); Zend_Mail::setDefaultTransport($mailTransport); } @@ -519,8 +522,9 @@ class Mage_Core_Model_Email_Template extends Mage_Core_Model_Template * @param array $vars variables which can be used in template * @param int|null $storeId * @return Mage_Core_Model_Email_Template + * @throws Mage_Core_Exception */ - public function sendTransactional($templateId, $sender, $email, $name, $vars=array(), $storeId=null) + public function sendTransactional($templateId, $sender, $email, $name, $vars = array(), $storeId = null) { $this->setSentSuccess(false); if (($storeId === null) && $this->getDesignConfig()->getStore()) { @@ -534,7 +538,8 @@ class Mage_Core_Model_Email_Template extends Mage_Core_Model_Template } if (!$this->getId()) { - throw Mage::exception('Mage_Core', Mage::helper('Mage_Core_Helper_Data')->__('Invalid transactional email code: %s', $templateId)); + throw Mage::exception('Mage_Core', + Mage::helper('Mage_Core_Helper_Data')->__('Invalid transactional email code: %s', $templateId)); } if (!is_array($sender)) { @@ -557,12 +562,13 @@ class Mage_Core_Model_Email_Template extends Mage_Core_Model_Template * * @param array $variables * @return string + * @throws Exception */ public function getProcessedTemplateSubject(array $variables) { $processor = $this->getTemplateFilter(); - if(!$this->_preprocessFlag) { + if (!$this->_preprocessFlag) { $variables['this'] = $this; } @@ -570,11 +576,10 @@ class Mage_Core_Model_Email_Template extends Mage_Core_Model_Template $this->_applyDesignConfig(); $storeId = $this->getDesignConfig()->getStore(); - try{ + try { $processedResult = $processor->setStoreId($storeId) ->filter($this->getTemplateSubject()); - } - catch (Exception $e) { + } catch (Exception $e) { $this->_cancelDesignConfig(); throw $e; } @@ -672,7 +677,7 @@ class Mage_Core_Model_Email_Template extends Mage_Core_Model_Template if (empty($code)) { Mage::throwException(Mage::helper('Mage_Core_Helper_Data')->__('The template Name must not be empty.')); } - if($this->_getResource()->checkCodeUsage($this)) { + if ($this->_getResource()->checkCodeUsage($this)) { Mage::throwException(Mage::helper('Mage_Core_Helper_Data')->__('Duplicate Of Template Name')); } return parent::_beforeSave(); diff --git a/app/code/core/Mage/Core/Model/Layout/Merge.php b/app/code/core/Mage/Core/Model/Layout/Merge.php index ca3727212f450fbe781d14a03c38989004521d57..77e18ef7271f51b91133fa76181f9866e3f2475e 100644 --- a/app/code/core/Mage/Core/Model/Layout/Merge.php +++ b/app/code/core/Mage/Core/Model/Layout/Merge.php @@ -111,7 +111,7 @@ class Mage_Core_Model_Layout_Merge $this->_themeId = $arguments['themeId']; } elseif (isset($arguments['area'])) { $this->_area = $arguments['area']; - $this->_themeId = null; + $this->_themeId = Mage::getDesign()->getConfigurationDesignTheme($arguments['area']); } else { $this->_area = Mage::getDesign()->getArea(); $this->_themeId = Mage::getDesign()->getDesignTheme()->getId(); diff --git a/app/code/core/Mage/Core/Model/Template.php b/app/code/core/Mage/Core/Model/Template.php index 1dfd3a564001aaf439e5768d87587107bbb1f1c0..800669fdcbe646c685b9a0b65f5b64cf7fc63bfb 100644 --- a/app/code/core/Mage/Core/Model/Template.php +++ b/app/code/core/Mage/Core/Model/Template.php @@ -85,6 +85,8 @@ abstract class Mage_Core_Model_Template extends Mage_Core_Model_Abstract /** * Initialize data * + * @param Mage_Core_Model_Event_Manager $eventDispatcher + * @param Mage_Core_Model_Cache $cacheManager * @param array $data */ public function __construct( @@ -109,6 +111,7 @@ abstract class Mage_Core_Model_Template extends Mage_Core_Model_Abstract $storeId = is_object($store) ? $store->getId() : $store; $area = $designConfig->getArea(); if (!is_null($storeId)) { + /** @var $appEmulation Mage_Core_Model_App_Emulation */ $appEmulation = Mage::getSingleton('Mage_Core_Model_App_Emulation'); $this->_initialEnvironmentInfo = $appEmulation->startEnvironmentEmulation($storeId, $area); } diff --git a/app/code/core/Mage/Core/Model/Theme.php b/app/code/core/Mage/Core/Model/Theme.php index 9a43ba24d57a1cfc3980c03bbdbe96e57ee651bb..034c270240f1b1c0c1fbcdccc135eb93017d81cc 100644 --- a/app/code/core/Mage/Core/Model/Theme.php +++ b/app/code/core/Mage/Core/Model/Theme.php @@ -44,6 +44,11 @@ */ class Mage_Core_Model_Theme extends Mage_Core_Model_Abstract { + /** + * Cache tag for empty theme + */ + const CACHE_TAG_NO_THEME = 'NO_THEME'; + /** * Separator between theme_path elements */ @@ -451,6 +456,10 @@ class Mage_Core_Model_Theme extends Mage_Core_Model_Abstract */ public function getCacheKey() { + if (!$this->getId()) { + return self::CACHE_TAG_NO_THEME . $this->getThemePath(); + } + return $this->getId() . $this->getThemePath(); } @@ -544,4 +553,12 @@ class Mage_Core_Model_Theme extends Mage_Core_Model_Abstract { return $this->getLabelsCollection(Mage::helper('Mage_Core_Helper_Data')->__('-- No Theme --')); } + + /** + * Clear data for clone + */ + public function __clone() + { + $this->unsetData()->setOrigData(); + } } diff --git a/app/code/core/Mage/Downloadable/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable/Links.php b/app/code/core/Mage/Downloadable/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable/Links.php index d2084e6152280adbad743b232aab472c3f9ca286..4bc1d37772c47900097d349452e6237e1ac9e1ce 100644 --- a/app/code/core/Mage/Downloadable/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable/Links.php +++ b/app/code/core/Mage/Downloadable/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable/Links.php @@ -128,7 +128,9 @@ class Mage_Downloadable_Block_Adminhtml_Catalog_Product_Edit_Tab_Downloadable_Li */ public function getLinksTitle() { - return Mage::getStoreConfig(Mage_Downloadable_Model_Link::XML_PATH_LINKS_TITLE); + return $this->getProduct()->getId() && $this->getProduct()->getTypeId() == 'downloadable' + ? $this->getProduct()->getLinksTitle() + : Mage::getStoreConfig(Mage_Downloadable_Model_Link::XML_PATH_LINKS_TITLE); } /** @@ -163,6 +165,9 @@ class Mage_Downloadable_Block_Adminhtml_Catalog_Product_Edit_Tab_Downloadable_Li public function getLinkData() { $linkArr = array(); + if ($this->getProduct()->getTypeId() !== Mage_Downloadable_Model_Product_Type::TYPE_DOWNLOADABLE) { + return $linkArr; + } $links = $this->getProduct()->getTypeInstance()->getLinks($this->getProduct()); $priceWebsiteScope = $this->getIsPriceWebsiteScope(); $fileHelper = Mage::helper('Mage_Downloadable_Helper_File'); diff --git a/app/code/core/Mage/Downloadable/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable/Samples.php b/app/code/core/Mage/Downloadable/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable/Samples.php index 038499285aab90b8f28c3368ddde663a3817e702..e80437b8f8c33c69e22da3e4ff64f132ade7da38 100644 --- a/app/code/core/Mage/Downloadable/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable/Samples.php +++ b/app/code/core/Mage/Downloadable/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable/Samples.php @@ -88,6 +88,9 @@ class Mage_Downloadable_Block_Adminhtml_Catalog_Product_Edit_Tab_Downloadable_Sa public function getSampleData() { $samplesArr = array(); + if ($this->getProduct()->getTypeId() !== Mage_Downloadable_Model_Product_Type::TYPE_DOWNLOADABLE) { + return $samplesArr; + } $samples = $this->getProduct()->getTypeInstance()->getSamples($this->getProduct()); $fileHelper = Mage::helper('Mage_Downloadable_Helper_File'); foreach ($samples as $item) { @@ -139,7 +142,9 @@ class Mage_Downloadable_Block_Adminhtml_Catalog_Product_Edit_Tab_Downloadable_Sa */ public function getSamplesTitle() { - return Mage::getStoreConfig(Mage_Downloadable_Model_Sample::XML_PATH_SAMPLES_TITLE); + return $this->getProduct()->getId() && $this->getProduct()->getTypeId() == 'downloadable' + ? $this->getProduct()->getSamplesTitle() + : Mage::getStoreConfig(Mage_Downloadable_Model_Sample::XML_PATH_SAMPLES_TITLE); } /** diff --git a/app/code/core/Mage/Downloadable/Model/Observer.php b/app/code/core/Mage/Downloadable/Model/Observer.php index b0e1f9aaf6dc4773da4bea0a4ad37b52b50a49ec..215fccd5772491d2baea4a3d55b2bf745ad8d7f8 100644 --- a/app/code/core/Mage/Downloadable/Model/Observer.php +++ b/app/code/core/Mage/Downloadable/Model/Observer.php @@ -65,6 +65,34 @@ class Mage_Downloadable_Model_Observer return $this; } + /** + * Change product type on the fly depending on selected options + * + * @param Varien_Event_Observer $observer + * @return Mage_Downloadable_Model_Observer + */ + public function transitionProductType(Varien_Event_Observer $observer) + { + $request = $observer->getEvent()->getRequest(); + $product = $observer->getEvent()->getProduct(); + $downloadable = $request->getPost('downloadable'); + $isTransitionalType = $product->getTypeId() === Mage_Catalog_Model_Product_Type::TYPE_SIMPLE + || $product->getTypeId() === Mage_Catalog_Model_Product_Type::TYPE_VIRTUAL + || $product->getTypeId() === Mage_Downloadable_Model_Product_Type::TYPE_DOWNLOADABLE; + + if ($isTransitionalType) { + if ($product->hasIsVirtual()) { + if ($downloadable) { + $product->setTypeId(Mage_Downloadable_Model_Product_Type::TYPE_DOWNLOADABLE); + } else { + $product->setTypeId(Mage_Catalog_Model_Product_Type::TYPE_VIRTUAL); + } + } else { + $product->setTypeId(Mage_Catalog_Model_Product_Type::TYPE_SIMPLE); + } + } + return $this; + } /** * Save data from order to purchased links diff --git a/app/code/core/Mage/Downloadable/Model/Product/Type.php b/app/code/core/Mage/Downloadable/Model/Product/Type.php index 987ab57e39b111e16f2c8d8777c704ed6c4156aa..18441bab60c1a644191dee634d20529433ee9a4f 100644 --- a/app/code/core/Mage/Downloadable/Model/Product/Type.php +++ b/app/code/core/Mage/Downloadable/Model/Product/Type.php @@ -372,8 +372,6 @@ class Mage_Downloadable_Model_Product_Type extends Mage_Catalog_Model_Product_Ty return $options; } - - /** * Setting flag if dowenloadable product can be or not in complex product * based on link can be purchased separately or not @@ -470,4 +468,44 @@ class Mage_Downloadable_Model_Product_Type extends Mage_Catalog_Model_Product_Ty { return $this->hasLinks($product) && $product->getLinksPurchasedSeparately(); } + + /** + * Check that product of this type has weight + * + * @return bool + */ + public function hasWeight() + { + return false; + } + + /** + * Delete data specific for Downloadable product type + * + * @param Mage_Catalog_Model_Product $product + */ + public function deleteTypeSpecificData(Mage_Catalog_Model_Product $product) + { + if ($product->getOrigData('type_id') === Mage_Downloadable_Model_Product_Type::TYPE_DOWNLOADABLE) { + $downloadableData = $product->getDownloadableData(); + $sampleItems = array(); + if (isset($downloadableData['sample'])) { + foreach ($downloadableData['sample'] as $sample) { + $sampleItems[] = $sample['sample_id']; + } + } + if ($sampleItems) { + Mage::getResourceModel('Mage_Downloadable_Model_Resource_Sample')->deleteItems($sampleItems); + } + $linkItems = array(); + if (isset($downloadableData['link'])) { + foreach ($downloadableData['link'] as $link) { + $linkItems[] = $link['link_id']; + } + } + if ($linkItems) { + Mage::getResourceModel('Mage_Downloadable_Model_Resource_Link')->deleteItems($linkItems); + } + } + } } diff --git a/app/code/core/Mage/Downloadable/data/downloadable_setup/data-upgrade-1.6.0.0.2-1.6.0.0.3.php b/app/code/core/Mage/Downloadable/data/downloadable_setup/data-upgrade-1.6.0.0.2-1.6.0.0.3.php new file mode 100644 index 0000000000000000000000000000000000000000..55496ff75b3c672ec17e785d64b4eb09fe339e31 --- /dev/null +++ b/app/code/core/Mage/Downloadable/data/downloadable_setup/data-upgrade-1.6.0.0.2-1.6.0.0.3.php @@ -0,0 +1,32 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @category Mage + * @package Mage_Downloadable + * @copyright Copyright (c) 2012 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +$applyTo = array_merge( + explode(',', $this->getAttribute(Mage_Catalog_Model_Product::ENTITY, 'weight', 'apply_to')), + array(Mage_Downloadable_Model_Product_Type::TYPE_DOWNLOADABLE) +); + +$this->updateAttribute(Mage_Catalog_Model_Product::ENTITY, 'weight', 'apply_to', implode(',', $applyTo)); diff --git a/app/code/core/Mage/Downloadable/etc/config.xml b/app/code/core/Mage/Downloadable/etc/config.xml index 2d5216aacfacaec2415cc03967cfe58d3ca9816b..46cc6daed674edfdcc2636944b57be3f13177b9c 100644 --- a/app/code/core/Mage/Downloadable/etc/config.xml +++ b/app/code/core/Mage/Downloadable/etc/config.xml @@ -28,7 +28,7 @@ <config> <modules> <Mage_Downloadable> - <version>1.6.0.0.2</version> + <version>1.6.0.0.3</version> <active>true</active> <codePool>core</codePool> <depends> @@ -79,6 +79,13 @@ </allow_product_types> </grouped> </type> + <attributes> + <weight> + <type_switcher translate="label"> + <label>Virtual / Downloadable</label> + </type_switcher> + </weight> + </attributes> </product> </catalog> <pdf> @@ -149,6 +156,14 @@ </downloadable_observer> </observers> </sales_order_save_commit_after> + <catalog_product_transition_product_type> + <observers> + <type_transition> + <class>Mage_Downloadable_Model_Observer</class> + <method>transitionProductType</method> + </type_transition> + </observers> + </catalog_product_transition_product_type> </events> </adminhtml> <frontend> diff --git a/app/code/core/Mage/Downloadable/view/adminhtml/layout.xml b/app/code/core/Mage/Downloadable/view/adminhtml/layout.xml index 893ab49b67e9b234d0feb25208a663684294533d..6d953b1453d08dae036da4a3999f702f7b6e6654 100644 --- a/app/code/core/Mage/Downloadable/view/adminhtml/layout.xml +++ b/app/code/core/Mage/Downloadable/view/adminhtml/layout.xml @@ -29,9 +29,14 @@ <layout> <adminhtml_catalog_product_downloadable> + <update handle="adminhtml_catalog_product_superconfig_config"/> <reference name="product_tabs"> <action method="addTab"><name>downloadable_items</name><block>Mage_Downloadable_Block_Adminhtml_Catalog_Product_Edit_Tab_Downloadable</block></action> </reference> + <reference name="product-type-tabs"> + <block type="Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Super_Config" + name="admin.product.edit.tab.super.config.grid.container"></block> + </reference> </adminhtml_catalog_product_downloadable> <adminhtml_sales_order_view> diff --git a/app/code/core/Mage/Downloadable/view/adminhtml/product/edit/downloadable/links.phtml b/app/code/core/Mage/Downloadable/view/adminhtml/product/edit/downloadable/links.phtml index c7c4cbc3125f2c8d34ddc0f0530caf79cebd9bc2..5aabb14f597953c9cee05aad3bc1fc66faaab33f 100644 --- a/app/code/core/Mage/Downloadable/view/adminhtml/product/edit/downloadable/links.phtml +++ b/app/code/core/Mage/Downloadable/view/adminhtml/product/edit/downloadable/links.phtml @@ -39,7 +39,7 @@ <td class="label"><label for="name"><?php echo Mage::helper('Mage_Downloadable_Helper_Data')->__('Title')?></label> </td> <td class="value"> - <input type="text" class="input-text" id="downloadable_links_title" name="product[links_title]" value="<?php echo $_product->getId()?$_product->getLinksTitle():$this->getLinksTitle() ?>" <?php echo ($_product->getStoreId() && $this->getUsedDefault())?'disabled="disabled"':'' ?> /> + <input type="text" class="input-text" id="downloadable_links_title" name="product[links_title]" value="<?php echo $this->getLinksTitle() ?>" <?php echo ($_product->getStoreId() && $this->getUsedDefault())?'disabled="disabled"':'' ?> /> </td> <td class="scope-label"><?php echo !Mage::app()->isSingleStoreMode() ? Mage::helper('Mage_Adminhtml_Helper_Data')->__('[STORE VIEW]') : ''; ?></td> <td class="value use-default"> diff --git a/app/code/core/Mage/Downloadable/view/adminhtml/product/edit/downloadable/samples.phtml b/app/code/core/Mage/Downloadable/view/adminhtml/product/edit/downloadable/samples.phtml index 7c0429ead32d284e1929db89bd4226a3102fafec..3c1ea578375d206db6fd0c7c77728751548c1e1b 100644 --- a/app/code/core/Mage/Downloadable/view/adminhtml/product/edit/downloadable/samples.phtml +++ b/app/code/core/Mage/Downloadable/view/adminhtml/product/edit/downloadable/samples.phtml @@ -39,7 +39,7 @@ $this->getConfigJson(); <td class="label"><label for="name"><?php echo Mage::helper('Mage_Downloadable_Helper_Data')->__('Title')?></label> </td> <td class="value"> - <input type="text" class="input-text" name="product[samples_title]" value="<?php echo $_product->getId()?$_product->getSamplesTitle():$this->getSamplesTitle() ?>" <?php echo ($_product->getStoreId() && $this->getUsedDefault())?'disabled="disabled"':'' ?> /> + <input type="text" class="input-text" name="product[samples_title]" value="<?php echo $this->getSamplesTitle() ?>" <?php echo ($_product->getStoreId() && $this->getUsedDefault())?'disabled="disabled"':'' ?> /> </td> <td class="scope-label"><?php echo !Mage::app()->isSingleStoreMode() ? Mage::helper('Mage_Adminhtml_Helper_Data')->__('[STORE VIEW]') : ''; ?></td> <td class="value use-default"> diff --git a/app/code/core/Mage/Eav/Model/Entity/Attribute/Backend/Array.php b/app/code/core/Mage/Eav/Model/Entity/Attribute/Backend/Array.php index 09f117836905564aad8c5d4f1683bdc2f8cd89d9..b522dec8c2b27ed11c4e2a3f93708bd3e6f3d799 100644 --- a/app/code/core/Mage/Eav/Model/Entity/Attribute/Backend/Array.php +++ b/app/code/core/Mage/Eav/Model/Entity/Attribute/Backend/Array.php @@ -50,4 +50,20 @@ class Mage_Eav_Model_Entity_Attribute_Backend_Array extends Mage_Eav_Model_Entit return parent::beforeSave($object); } + + /** + * Implode data for validation + * + * @param Mage_Catalog_Model_Product $object + * @return bool + */ + public function validate($object) + { + $attributeCode = $this->getAttribute()->getAttributeCode(); + $data = $object->getData($attributeCode); + if (is_array($data)) { + $object->setData($attributeCode, implode(',', array_filter($data))); + } + return parent::validate($object); + } } diff --git a/app/code/core/Mage/GoogleShopping/Model/Resource/Item/Collection.php b/app/code/core/Mage/GoogleShopping/Model/Resource/Item/Collection.php index 8a42036072f52cb4d7d6d92b60f2c25582257422..109afdbae0a0f086bf63da6a3bc7827c17d3b9dd 100644 --- a/app/code/core/Mage/GoogleShopping/Model/Resource/Item/Collection.php +++ b/app/code/core/Mage/GoogleShopping/Model/Resource/Item/Collection.php @@ -129,7 +129,9 @@ class Mage_GoogleShopping_Model_Resource_Item_Collection extends Mage_Core_Model $this->getSelect() ->joinLeft( array('types' => $this->getTable('googleshopping_types')), - 'main_table.type_id=types.type_id'); + 'main_table.type_id=types.type_id' + ); + Mage::getResourceHelper('Mage_Core')->prepareColumnsList($this->getSelect()); // avoid column name collision return $this; } diff --git a/app/code/core/Mage/GoogleShopping/controllers/Adminhtml/Googleshopping/ItemsController.php b/app/code/core/Mage/GoogleShopping/controllers/Adminhtml/Googleshopping/ItemsController.php index 3a62f82aa5970a534439471b4ea9bef96837ee27..97c94d910431e44f29ed40a634521ad98255300c 100644 --- a/app/code/core/Mage/GoogleShopping/controllers/Adminhtml/Googleshopping/ItemsController.php +++ b/app/code/core/Mage/GoogleShopping/controllers/Adminhtml/Googleshopping/ItemsController.php @@ -53,9 +53,7 @@ class Mage_GoogleShopping_Adminhtml_Googleshopping_ItemsController extends Mage_ */ public function indexAction() { - $this->_initAction() - ->_addBreadcrumb(Mage::helper('Mage_GoogleShopping_Helper_Data')->__('Items'), Mage::helper('Mage_GoogleShopping_Helper_Data')->__('Items')) - ->_title($this->__('Catalog')) + $this->_title($this->__('Catalog')) ->_title($this->__('Google Content')) ->_title($this->__('Manage Items')); @@ -63,6 +61,9 @@ class Mage_GoogleShopping_Adminhtml_Googleshopping_ItemsController extends Mage_ $this->_redirect('*/*/', array('store' => Mage::app()->getAnyStoreView()->getId(), '_current' => true)); return; } + + $this->_initAction(); + $contentBlock = $this->getLayout() ->createBlock('Mage_GoogleShopping_Block_Adminhtml_Items')->setStore($this->_getStore()); @@ -82,7 +83,8 @@ class Mage_GoogleShopping_Adminhtml_Googleshopping_ItemsController extends Mage_ ); } - $this->_addContent($contentBlock) + $this->_addBreadcrumb(Mage::helper('Mage_GoogleShopping_Helper_Data')->__('Items'), Mage::helper('Mage_GoogleShopping_Helper_Data')->__('Items')) + ->_addContent($contentBlock) ->renderLayout(); } diff --git a/app/code/core/Mage/Wishlist/controllers/IndexController.php b/app/code/core/Mage/Wishlist/controllers/IndexController.php index 739bb05de71782312048bfc235553039d81cd115..d8b791e8f7311f656a7c02fd28650adc1819aedb 100644 --- a/app/code/core/Mage/Wishlist/controllers/IndexController.php +++ b/app/code/core/Mage/Wishlist/controllers/IndexController.php @@ -213,9 +213,9 @@ class Mage_Wishlist_IndexController */ $session->setAddActionReferer($referer); - Mage::helper('Mage_Wishlist_Helper_Data')->calculate(); - - $message = $this->__('%1$s has been added to your wishlist. Click <a href="%2$s">here</a> to continue shopping.', $product->getName(), Mage::helper('Mage_Core_Helper_Data')->escapeUrl($referer)); + /** @var $helper Mage_Wishlist_Helper_Data */ + $helper = Mage::helper('Mage_Wishlist_Helper_Data')->calculate(); + $message = $this->__('%1$s has been added to your wishlist. Click <a href="%2$s">here</a> to continue shopping.', $helper->escapeHtml($product->getName()), Mage::helper('Mage_Core_Helper_Data')->escapeUrl($referer)); $session->addSuccess($message); } catch (Mage_Core_Exception $e) { diff --git a/app/design/adminhtml/default/basic/boxes.css b/app/design/adminhtml/default/basic/boxes.css index f33681749260b36ffbae076ddacef5d54ca02953..c7742b01b15484894994f9a8c8f5d634a633a92e 100644 --- a/app/design/adminhtml/default/basic/boxes.css +++ b/app/design/adminhtml/default/basic/boxes.css @@ -405,6 +405,7 @@ select.multiselect option { padding:3px 4px; border-bottom:1px solid #ddd; .fieldset-wide .form-list td.value { width:auto !important; } .fieldset-wide .form-list td.value input.input-text, .fieldset-wide .form-list td.value textarea { width:98% !important; } +#weight {width: 110px !important; } /*.fieldset-wide .form-list td.value select { display:block; }*/ .fieldset-wide .form-list td.scope-label { white-space:nowrap; width:1px; } .fieldset-wide .form-list td.note { width:120px; } diff --git a/dev/tests/integration/testsuite/Mage/Adminhtml/Block/Catalog/Category/TreeTest.php b/dev/tests/integration/testsuite/Mage/Adminhtml/Block/Catalog/Category/TreeTest.php new file mode 100644 index 0000000000000000000000000000000000000000..ac8ad8e0c05b8cec67e748e984dd01ebb750d6cf --- /dev/null +++ b/dev/tests/integration/testsuite/Mage/Adminhtml/Block/Catalog/Category/TreeTest.php @@ -0,0 +1,53 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @category Mage + * @package Mage_Adminhtml + * @subpackage integration_tests + * @copyright Copyright (c) 2012 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +class Mage_Adminhtml_Block_Catalog_Category_TreeTest extends PHPUnit_Framework_TestCase +{ + /** @var Mage_Adminhtml_Block_Catalog_Category_Tree */ + protected $_block; + + protected function setUp() + { + $this->_block = Mage::getModel('Mage_Adminhtml_Block_Catalog_Category_Tree'); + } + + protected function tearDown() + { + $this->_block = null; + } + + public function testGetSuggestedCategoriesJson() + { + $this->assertEquals( + '[{"id":"2","children":[],"is_active":"1","name":"Default Category"}]', + $this->_block->getSuggestedCategoriesJson('Default') + ); + $this->assertEquals( + '[]', + $this->_block->getSuggestedCategoriesJson(strrev('Default')) + ); + } +} diff --git a/dev/tests/integration/testsuite/Mage/Adminhtml/Block/Catalog/Product/Attribute/Edit/Tab/MainTest.php b/dev/tests/integration/testsuite/Mage/Adminhtml/Block/Catalog/Product/Attribute/Edit/Tab/MainTest.php new file mode 100644 index 0000000000000000000000000000000000000000..68af5a101320c700a2166893339dcbbbd2e7320e --- /dev/null +++ b/dev/tests/integration/testsuite/Mage/Adminhtml/Block/Catalog/Product/Attribute/Edit/Tab/MainTest.php @@ -0,0 +1,70 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @category Magento + * @package Magento_Adminhtml + * @subpackage integration_tests + * @copyright Copyright (c) 2012 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +class Mage_Adminhtml_Block_Catalog_Product_Attribute_Edit_Tab_MainTest extends PHPUnit_Framework_TestCase +{ + /** + * @var Mage_Adminhtml_Block_Catalog_Product_Attribute_Edit_Tab_Main + */ + protected $_block = null; + + protected function setUp() + { + $this->_block = Mage::app()->getLayout() + ->createBlock('Mage_Adminhtml_Block_Catalog_Product_Attribute_Edit_Tab_Main'); + } + + protected function tearDown() + { + $this->_block = null; + Mage::unregister('entity_attribute'); + Mage::unregister('attribute_type_hidden_fields'); + Mage::unregister('attribute_type_disabled_types'); + } + + public function testPrepareFormSystemAttribute() + { + Mage::register('entity_attribute', new Varien_Object( + array('entity_type' => new Varien_Object(), 'id' => 1, 'is_user_defined' => false)) + ); + $this->_block->toHtml(); + $this->assertTrue( + $this->_block->getForm()->getElement('base_fieldset')->getContainer()->getElement('apply_to')->getDisabled() + ); + } + + public function testPrepareFormUserDefinedAttribute() + { + Mage::register('entity_attribute', new Varien_Object( + array('entity_type' => new Varien_Object(), 'id' => 1, 'is_user_defined' => true)) + ); + $this->_block->toHtml(); + $this->assertFalse( + $this->_block->getForm()->getElement('base_fieldset')->getContainer()->getElement('apply_to')->getDisabled() + ); + } +} diff --git a/dev/tests/integration/testsuite/Mage/Adminhtml/Block/Catalog/Product/Edit/Tab/Super/ConfigTest.php b/dev/tests/integration/testsuite/Mage/Adminhtml/Block/Catalog/Product/Edit/Tab/Super/ConfigTest.php index bdafb323543683f2c950315e3fc6043ae7c882b2..5a81d4e583f8ffc83fd8a8b245924b095043a8a3 100644 --- a/dev/tests/integration/testsuite/Mage/Adminhtml/Block/Catalog/Product/Edit/Tab/Super/ConfigTest.php +++ b/dev/tests/integration/testsuite/Mage/Adminhtml/Block/Catalog/Product/Edit/Tab/Super/ConfigTest.php @@ -19,7 +19,7 @@ * needs please refer to http://www.magentocommerce.com for more information. * * @category Magento - * @package Magento_Adminhtml + * @package Mage_Adminhtml * @subpackage integration_tests * @copyright Copyright (c) 2012 X.commerce, Inc. (http://www.magentocommerce.com) * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) @@ -30,31 +30,56 @@ class Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Super_ConfigTest extends PHP /** * @magentoAppIsolation enabled */ - public function testGetGridJsObject() + public function testGetSelectedAttributesForSimpleProductType() { - Mage::register('current_product', new Varien_Object); - /** @var $layout Mage_Core_Model_Layout */ - $layout = Mage::getModel('Mage_Core_Model_Layout'); + Mage::register('current_product', Mage::getModel('Mage_Catalog_Model_Product')); /** @var $block Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Super_Config */ - $block = $layout->createBlock('Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Super_Config', 'block'); - $this->assertEquals('super_product_linksJsObject', $block->getGridJsObject()); + $block = Mage::app()->getLayout()->createBlock('Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Super_Config'); + $this->assertEquals(array(), $block->getSelectedAttributes()); } /** * @magentoAppIsolation enabled + * @magentoDataFixture Mage/Catalog/_files/product_configurable.php */ - public function testGetSelectedAttributes() + public function testGetSelectedAttributesForConfigurableProductType() { - $productType = $this->getMock('stdClass', array('getUsedProductAttributes')); - $product = $this->getMock('Varien_Object', array('getTypeInstance')); - - $product->expects($this->once())->method('getTypeInstance')->will($this->returnValue($productType)); - $productType->expects($this->once())->method('getUsedProductAttributes')->with($this->equalTo($product)) - ->will($this->returnValue(array('', 'a'))); + Mage::register('current_product', Mage::getModel('Mage_Catalog_Model_Product')->load(1)); + Mage::app()->getLayout()->createBlock('Mage_Core_Block_Text', 'head'); + $usedAttribute = Mage::getSingleton('Mage_Catalog_Model_Entity_Attribute')->loadByCode( + Mage::getSingleton('Mage_Eav_Model_Config')->getEntityType('catalog_product')->getId(), + 'test_configurable' + ); + /** @var $block Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Super_Config */ + $block = Mage::app()->getLayout()->createBlock('Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Super_Config'); + $selectedAttributes = $block->getSelectedAttributes(); + $this->assertEquals(array($usedAttribute->getId()), array_keys($selectedAttributes)); + $selectedAttribute = reset($selectedAttributes); + $this->assertEquals('test_configurable', $selectedAttribute->getAttributeCode()); + } - Mage::register('current_product', $product); - $layout = Mage::getModel('Mage_Core_Model_Layout'); - $block = $layout->createBlock('Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Super_Config', 'block'); - $this->assertEquals(array(1 => 'a'), $block->getSelectedAttributes()); + /** + * @magentoAppIsolation enabled + * @magentoDataFixture Mage/Catalog/_files/product_configurable.php + */ + public function testGetVariations() + { + Mage::register('current_product', Mage::getModel('Mage_Catalog_Model_Product')->load(1)); + Mage::app()->getLayout()->createBlock('Mage_Core_Block_Text', 'head'); + /** @var $usedAttribute Mage_Catalog_Model_Entity_Attribute */ + $usedAttribute = Mage::getSingleton('Mage_Catalog_Model_Entity_Attribute')->loadByCode( + Mage::getSingleton('Mage_Eav_Model_Config')->getEntityType('catalog_product')->getId(), + 'test_configurable' + ); + $attributeOptions = $usedAttribute->getSource()->getAllOptions(false); + /** @var $block Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Super_Config */ + $block = Mage::app()->getLayout()->createBlock('Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Super_Config'); + $this->assertEquals( + array( + array($usedAttribute->getId() => $attributeOptions[0]), + array($usedAttribute->getId() => $attributeOptions[1]), + ), + $block->getVariations() + ); } } diff --git a/dev/tests/integration/testsuite/Mage/Adminhtml/Block/Catalog/Product/Edit/Tab/Super/SettingsTest.php b/dev/tests/integration/testsuite/Mage/Adminhtml/Block/Catalog/Product/Edit/Tab/Super/SettingsTest.php index 909a88a7f0b3cec94c3505e8f4cf86253c4a25bd..b199e47a3f3e777e9045deb5eb456658bf86ba7a 100644 --- a/dev/tests/integration/testsuite/Mage/Adminhtml/Block/Catalog/Product/Edit/Tab/Super/SettingsTest.php +++ b/dev/tests/integration/testsuite/Mage/Adminhtml/Block/Catalog/Product/Edit/Tab/Super/SettingsTest.php @@ -19,7 +19,7 @@ * needs please refer to http://www.magentocommerce.com for more information. * * @category Magento - * @package Magento_Adminhtml + * @package Mage_Adminhtml * @subpackage integration_tests * @copyright Copyright (c) 2012 X.commerce, Inc. (http://www.magentocommerce.com) * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) @@ -28,8 +28,11 @@ class Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Super_SettingsTest extends PHPUnit_Framework_TestCase { /** + * @param null|int $productId + * @param string $expectedUrl + * * @magentoAppIsolation enabled - * @dataProvider getGetContinueUrlProvider + * @dataProvider getContinueUrlDataProvider */ public function testGetContinueUrl($productId, $expectedUrl) { @@ -43,12 +46,13 @@ class Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Super_SettingsTest extends P ->disableOriginalConstructor() ->setMethods(array('getUrl')) ->getMock(); - $urlModel->expects($this->at(2))->method('getUrl')->with($this->equalTo($expectedUrl)) + $urlModel->expects($this->any())->method('getUrl')->with($this->equalTo($expectedUrl)) ->will($this->returnValue('url')); Mage::register('current_product', $product); $layout = Mage::getModel('Mage_Core_Model_Layout'); + /** @var $block Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Super_Settings */ $block = $layout->createBlock( 'Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Super_Settings', 'block', @@ -62,7 +66,7 @@ class Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Super_SettingsTest extends P /** * @return array */ - public function getGetContinueUrlProvider() + public static function getContinueUrlDataProvider() { return array( array(null, '*/*/new'), diff --git a/dev/tests/integration/testsuite/Mage/Adminhtml/Block/Catalog/Product/EditTest.php b/dev/tests/integration/testsuite/Mage/Adminhtml/Block/Catalog/Product/EditTest.php new file mode 100644 index 0000000000000000000000000000000000000000..e3816dd84f058f240e03c0640861847479836d9e --- /dev/null +++ b/dev/tests/integration/testsuite/Mage/Adminhtml/Block/Catalog/Product/EditTest.php @@ -0,0 +1,51 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @category Magento + * @package Magento_Adminhtml + * @subpackage integration_tests + * @copyright Copyright (c) 2012 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +class Mage_Adminhtml_Block_Catalog_Product_EditTest extends PHPUnit_Framework_TestCase +{ + /** + * @var Mage_Adminhtml_Block_Catalog_Product_Edit + */ + protected $_block; + + protected function setUp() + { + /** @var $product Mage_Catalog_Model_Product */ + $product = $this->getMock('Mage_Catalog_Model_Product', array('getAttributes'), array(), '', false); + $product->expects($this->any())->method('getAttributes')->will($this->returnValue(array())); + $product->setTypeId(Mage_Catalog_Model_Product_Type::TYPE_SIMPLE); + Mage::register('current_product', $product); + $this->_block = Mage::app()->getLayout()->createBlock('Mage_Adminhtml_Block_Catalog_Product_Edit'); + } + + public function testGetTypeSwitcherData() + { + $data = json_decode($this->_block->getTypeSwitcherData(), true); + $this->assertEquals('simple', $data['current_type']); + $this->assertEquals(array(), $data['attributes']); + } +} diff --git a/dev/tests/integration/testsuite/Mage/Adminhtml/Block/Catalog/Product/Helper/Form/Weight/RendererTest.php b/dev/tests/integration/testsuite/Mage/Adminhtml/Block/Catalog/Product/Helper/Form/Weight/RendererTest.php new file mode 100644 index 0000000000000000000000000000000000000000..c5ff44b11869b01d5b482ecc6fa866e9fbd31aef --- /dev/null +++ b/dev/tests/integration/testsuite/Mage/Adminhtml/Block/Catalog/Product/Helper/Form/Weight/RendererTest.php @@ -0,0 +1,89 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @category Magento + * @package Mage_Adminhtml + * @subpackage integration_tests + * @copyright Copyright (c) 2012 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +class Mage_Adminhtml_Block_Catalog_Product_Helper_Form_Weight_RendererTest extends PHPUnit_Framework_TestCase +{ + /** + * @param string $type + * @dataProvider virtualTypesDataProvider + */ + public function testIsVirtualChecked($type) + { + $currentProduct = Mage::getModel('Mage_Catalog_Model_Product'); + $currentProduct->setTypeInstance(new $type); + + $block = new Mage_Adminhtml_Block_Catalog_Product_Helper_Form_Weight_Renderer(); + + $form = new Varien_Data_Form(); + $form->setDataObject($currentProduct); + $block->setForm($form); + + $this->assertContains('checked="checked"', $block->getElementHtml(), + 'Is Virtual checkbox is not selected for virtual products'); + } + + /** + * @return array + */ + public static function virtualTypesDataProvider() + { + return array( + array('Mage_Catalog_Model_Product_Type_Virtual'), + array('Mage_Downloadable_Model_Product_Type'), + ); + } + + /** + * @param string $type + * @dataProvider physicalTypesDataProvider + */ + public function testIsVirtualUnchecked($type) + { + $currentProduct = Mage::getModel('Mage_Catalog_Model_Product'); + $currentProduct->setTypeInstance(new $type); + + $block = new Mage_Adminhtml_Block_Catalog_Product_Helper_Form_Weight_Renderer(); + + $form = new Varien_Data_Form(); + $form->setDataObject($currentProduct); + $block->setForm($form); + + $this->assertNotContains('checked="checked"', $block->getElementHtml(), + 'Is Virtual checkbox is selected for physical products'); + } + + /** + * @return array + */ + public static function physicalTypesDataProvider() + { + return array( + array('Mage_Catalog_Model_Product_Type_Simple'), + array('Mage_Bundle_Model_Product_Type'), + ); + } +} diff --git a/dev/tests/integration/testsuite/Mage/Adminhtml/controllers/Catalog/CategoryControllerTest.php b/dev/tests/integration/testsuite/Mage/Adminhtml/controllers/Catalog/CategoryControllerTest.php index 14cc5557ce1ca64a41a4037d4f8e4a1efe969499..290a6544207029fdf92eff8f721420028d16638a 100644 --- a/dev/tests/integration/testsuite/Mage/Adminhtml/controllers/Catalog/CategoryControllerTest.php +++ b/dev/tests/integration/testsuite/Mage/Adminhtml/controllers/Catalog/CategoryControllerTest.php @@ -18,6 +18,9 @@ * versions in the future. If you wish to customize Magento for your * needs please refer to http://www.magentocommerce.com for more information. * + * @category Magento + * @package Mage_Adminhtml + * @subpackage integration_tests * @copyright Copyright (c) 2012 X.commerce, Inc. (http://www.magentocommerce.com) * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ @@ -75,6 +78,77 @@ class Mage_Adminhtml_Catalog_CategoryControllerTest extends Mage_Adminhtml_Utili $this->assertEmpty($errors, "\n" . join("\n", $errors)); } + /** + * @param array $postData + * @dataProvider categoryCreatedFromProductCreationPageDataProvider + */ + public function testSaveActionFromProductCreationPage($postData) + { + $this->getRequest()->setPost($postData); + + $this->dispatch('backend/admin/catalog_category/save'); + $body = $this->getResponse()->getBody(); + + if (empty($postData['return_session_messages_only'])) { + $this->assertRegExp( + '~<script type="text/javascript">parent\.updateContent\("[^"]+/backend/admin/catalog_category/edit/' + . 'id/\d+/key/[0-9a-f]+/", {}, true\);</script>~', + $body + ); + } else { + $result = Mage::helper('Mage_Core_Helper_Data')->jsonDecode($body); + $this->assertArrayHasKey('messages', $result); + $this->assertFalse($result['error']); + $category = $result['category']; + $this->assertEquals('Category Created From Product Creation Page', $category['name']); + $this->assertEquals(1, $category['is_active']); + $this->assertEquals(0, $category['include_in_menu']); + $this->assertEquals(2, $category['parent_id']); + $this->assertNull($category['available_sort_by']); + $this->assertNull($category['default_sort_by']); + } + } + + /** + * @static + * @return array + */ + public static function categoryCreatedFromProductCreationPageDataProvider() + { + /* Keep in sync with /app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product/edit/category/new/js.phtml */ + $postData = array( + 'general' => array ( + 'name' => 'Category Created From Product Creation Page', + 'is_active' => 1, + 'include_in_menu' => 0, + ), + 'parent' => 2, + 'use_config' => array('available_sort_by', 'default_sort_by'), + ); + + return array( + array($postData), + array($postData + array('return_session_messages_only' => 1)), + ); + } + + public function testSuggestCategoriesActionDefaultCategoryFound() + { + $this->getRequest()->setParam('name_part', 'Default'); + $this->dispatch('backend/admin/catalog_category/suggestCategories'); + $this->assertEquals( + '[{"id":"2","children":[],"is_active":"1","name":"Default Category"}]', + $this->getResponse()->getBody() + ); + } + + public function testSuggestCategoriesActionNoSuggestions() + { + $this->getRequest()->setParam('name_part', strrev('Default')); + $this->dispatch('backend/admin/catalog_category/suggestCategories'); + $this->assertEquals('[]', $this->getResponse()->getBody()); + } + /** * @SuppressWarnings(PHPMD.ExcessiveMethodLength) * @return array diff --git a/dev/tests/integration/testsuite/Mage/Adminhtml/controllers/Catalog/Product/Action/AttributeControllerTest.php b/dev/tests/integration/testsuite/Mage/Adminhtml/controllers/Catalog/Product/Action/AttributeControllerTest.php new file mode 100644 index 0000000000000000000000000000000000000000..f5d512eaf18c1dd420d5d8696b3f5899c6a27873 --- /dev/null +++ b/dev/tests/integration/testsuite/Mage/Adminhtml/controllers/Catalog/Product/Action/AttributeControllerTest.php @@ -0,0 +1,53 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @category Mage + * @package Mage_Adminhtml + * @subpackage integration_tests + * @copyright Copyright (c) 2012 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +class Mage_Adminhtml_Catalog_Product_Action_AttributeControllerTest extends Mage_Adminhtml_Utility_Controller +{ + /** + * @covers Mage_Adminhtml_Catalog_Product_Action_AttributeController::saveAction + * + * @magentoDataFixture Mage/Catalog/_files/product_simple.php + */ + public function testSaveActionRedirectsSuccessfully() + { + /** @var $session Mage_Adminhtml_Model_Session */ + $session = Mage::getSingleton('Mage_Adminhtml_Model_Session'); + $session->setProductIds(array(1)); + + $this->dispatch('backend/admin/catalog_product_action_attribute/save/store/0'); + + $this->assertEquals(302, $this->getResponse()->getHttpResponseCode()); + $expectedUrl = Mage::getUrl('backend/admin/catalog_product/index'); + $isRedirectPresent = false; + foreach ($this->getResponse()->getHeaders() as $header) { + if ($header['name'] === 'Location' && strpos($header['value'], $expectedUrl) === 0) { + $isRedirectPresent = true; + } + } + $this->assertTrue($isRedirectPresent); + } +} diff --git a/dev/tests/integration/testsuite/Mage/Adminhtml/controllers/Catalog/Product/AttributeControllerTest.php b/dev/tests/integration/testsuite/Mage/Adminhtml/controllers/Catalog/Product/AttributeControllerTest.php new file mode 100644 index 0000000000000000000000000000000000000000..eec96c1210fba4608865eaf55a6711c3c3aa0552 --- /dev/null +++ b/dev/tests/integration/testsuite/Mage/Adminhtml/controllers/Catalog/Product/AttributeControllerTest.php @@ -0,0 +1,117 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @category Magento + * @package Mage_Adminhtml + * @subpackage integration_tests + * @copyright Copyright (c) 2012 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +class Mage_Adminhtml_Catalog_Product_AttributeControllerTest extends Mage_Adminhtml_Utility_Controller +{ + /** + * @magentoDataFixture Mage/Catalog/controllers/_files/attribute_system.php + */ + public function testSaveActionApplyToDataSystemAttribute() + { + $postData = $this->_getAttributeData() + array('attribute_id' => '2'); + $this->getRequest()->setPost($postData); + $this->dispatch('backend/admin/catalog_product_attribute/save'); + $model = new Mage_Catalog_Model_Resource_Eav_Attribute( + new Mage_Core_Model_Event_Manager(), + new Mage_Core_Model_Cache() + ); + $model->load($postData['attribute_id']); + $this->assertNull($model->getData('apply_to')); + } + + /** + * @magentoDataFixture Mage/Catalog/controllers/_files/attribute_user_defined.php + */ + public function testSaveActionApplyToDataUserDefinedAttribute() + { + $postData = $this->_getAttributeData() + array('attribute_id' => '1'); + $this->getRequest()->setPost($postData); + $this->dispatch('backend/admin/catalog_product_attribute/save'); + $model = new Mage_Catalog_Model_Resource_Eav_Attribute( + new Mage_Core_Model_Event_Manager(), + new Mage_Core_Model_Cache() + ); + $model->load($postData['attribute_id']); + $this->assertEquals('simple,configurable', $model->getData('apply_to')); + } + + /** + * @magentoDataFixture Mage/Catalog/controllers/_files/attribute_system_with_applyto_data.php + */ + public function testSaveActionApplyToData() + { + $postData = $this->_getAttributeData() + array('attribute_id' => '3'); + unset($postData['apply_to']); + $this->getRequest()->setPost($postData); + $this->dispatch('backend/admin/catalog_product_attribute/save'); + $model = new Mage_Catalog_Model_Resource_Eav_Attribute( + new Mage_Core_Model_Event_Manager(), + new Mage_Core_Model_Cache() + ); + $model->load($postData['attribute_id']); + $this->assertEquals(array('simple', 'configurable'), $model->getApplyTo()); + } + + /** + * Get attribute data for post + * + * @return array + */ + protected function _getAttributeData() + { + return array( + 'is_global' => '2', + 'default_value_text' => '0', + 'default_value_yesno' => '0', + 'default_value_date' => '', + 'default_value_textarea' => '0', + 'is_required' => '1', + 'frontend_class' => '', + 'is_configurable' => '0', + 'is_searchable' => '0', + 'is_visible_in_advanced_search' => '0', + 'is_comparable' => '0', + 'is_filterable' => '0', + 'is_filterable_in_search' => '0', + 'is_used_for_promo_rules' => '0', + 'is_html_allowed_on_front' => '0', + 'is_visible_on_front' => '0', + 'used_in_product_listing' => '1', + 'used_for_sort_by' => '0', + 'apply_to' => array( + 'simple', 'configurable'), + 'frontend_label' => array( + 0 => 'Allow Open Amount', + 1 => ''), + 'default' => array( + 0 => '0'), + 'option' => array( + 'delete' => array( + 0 => '', + 1 => ''))); + } +} diff --git a/dev/tests/integration/testsuite/Mage/Adminhtml/controllers/Catalog/Product/ReviewControllerTest.php b/dev/tests/integration/testsuite/Mage/Adminhtml/controllers/Catalog/Product/ReviewControllerTest.php new file mode 100644 index 0000000000000000000000000000000000000000..9ee37cff34bd272254f9b9314bf8f8bd84f44e95 --- /dev/null +++ b/dev/tests/integration/testsuite/Mage/Adminhtml/controllers/Catalog/Product/ReviewControllerTest.php @@ -0,0 +1,41 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @category Magento + * @package Mage_Adminhtml + * @subpackage integration_tests + * @copyright Copyright (c) 2012 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +class Mage_Adminhtml_Catalog_Product_ReviewControllerTest extends Mage_Adminhtml_Utility_Controller +{ + /** + * @magentoDataFixture Mage/Review/_files/review_xss.php + */ + public function testEditActionProductNameXss() + { + $this->markTestIncomplete('MAGETWO-5900'); + $this->dispatch('backend/admin/catalog_product_review/edit/id/1'); + $responseBody = $this->getResponse()->getBody(); + $this->assertContains('<script>alert("xss");</script>', $responseBody); + $this->assertNotContains('<script>alert("xss");</script>', $responseBody); + } +} diff --git a/dev/tests/integration/testsuite/Mage/Adminhtml/controllers/Catalog/ProductControllerTest.php b/dev/tests/integration/testsuite/Mage/Adminhtml/controllers/Catalog/ProductControllerTest.php new file mode 100644 index 0000000000000000000000000000000000000000..c65a9c1fc0444b4902925c35e4e28db98e679e25 --- /dev/null +++ b/dev/tests/integration/testsuite/Mage/Adminhtml/controllers/Catalog/ProductControllerTest.php @@ -0,0 +1,92 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @category Magento + * @package Mage_Adminhtml + * @subpackage integration_tests + * @copyright Copyright (c) 2012 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +class Mage_Adminhtml_Catalog_ProductControllerTest extends Mage_Adminhtml_Utility_Controller +{ + /** + * @magentoDataFixture Mage/Catalog/_files/product_configurable.php + */ + public function testSaveActionAssociatedProductIds() + { + $associatedProductIds = array(3, 14, 15, 92); + $this->getRequest()->setPost(array( + 'attributes' => array($this->_getConfigurableAttribute()->getId()), + 'associated_product_ids' => $associatedProductIds, + )); + + $this->dispatch('backend/admin/catalog_product/save'); + + /** @var $product Mage_Catalog_Model_Product */ + $product = Mage::registry('current_product'); + $this->assertEquals($associatedProductIds, $product->getAssociatedProductIds()); + } + + /** + * Retrieve configurable attribute instance + * + * @return Mage_Catalog_Model_Entity_Attribute + */ + protected function _getConfigurableAttribute() + { + return Mage::getModel('Mage_Catalog_Model_Entity_Attribute')->loadByCode( + Mage::getSingleton('Mage_Eav_Model_Config')->getEntityType('catalog_product')->getId(), + 'test_configurable' + ); + } + + public function testSaveActionWithDangerRequest() + { + $this->getRequest()->setPost(array( + 'product' => array( + 'entity_id' => 15 + ), + )); + $this->dispatch('backend/admin/catalog_product/save'); + /** @var Mage_Backend_Model_Session $session */ + $session = Mage::getSingleton('Mage_Backend_Model_Session'); + $errorMessages = $session->getMessages()->getErrors(); + $this->assertCount(1, $errorMessages); + $this->assertEquals('Unable to save product', $errorMessages[0]->getCode()); + $this->assertRedirect($this->stringContains('/backend/admin/catalog_product/edit')); + } + + /** + * @magentoDataFixture Mage/Catalog/_files/product_configurable.php + */ + public function testQuickCreateActionWithDangerRequest() + { + $this->getRequest()->setPost(array( + 'simple_product' => array( + 'entity_id' => 15 + ), + 'product' => 1 + )); + $this->dispatch('backend/admin/catalog_product/quickcreate'); + $this->assertContains('"error":{"message":"Unable to create product","fields":{"sku":null}}', + $this->getResponse()->getBody()); + } +} diff --git a/dev/tests/integration/testsuite/Mage/Backend/Block/Widget/Grid/MassactionTest.php b/dev/tests/integration/testsuite/Mage/Backend/Block/Widget/Grid/MassactionTest.php index b1f2d598d71068110eb5c1bf32c1b4b7248f372e..311fdfb1b2e9c758b6fe0e8716602ced80378c62 100644 --- a/dev/tests/integration/testsuite/Mage/Backend/Block/Widget/Grid/MassactionTest.php +++ b/dev/tests/integration/testsuite/Mage/Backend/Block/Widget/Grid/MassactionTest.php @@ -26,9 +26,9 @@ */ /** - * * @magentoAppIsolation enabled * @magentoDbIsolation enabled + * @magentoDataFixture Mage/Backend/Block/_files/theme_registration.php */ class Mage_Backend_Block_Widget_Grid_MassactionTest extends PHPUnit_Framework_TestCase { @@ -42,23 +42,6 @@ class Mage_Backend_Block_Widget_Grid_MassactionTest extends PHPUnit_Framework_Te */ protected $_layout; - public static function setUpBeforeClass() - { - /* Point application to predefined layout fixtures */ - Mage::getConfig()->setOptions(array( - 'design_dir' => realpath( __DIR__ . '/../../_files/design'), - )); - - /** @var $themeRegistration Mage_Core_Model_Theme_Registration */ - $themeRegistration = Mage::getObjectManager()->create('Mage_Core_Model_Theme_Registration'); - $themeRegistration->register(); - - Mage::getDesign()->setDesignTheme('test/default', 'adminhtml'); - - /* Disable loading and saving layout cache */ - Mage::app()->getCacheInstance()->banUse('layout'); - } - protected function setUp() { $this->_layout = Mage::getModel('Mage_Core_Model_Layout', array('area' => 'adminhtml')); @@ -76,10 +59,11 @@ class Mage_Backend_Block_Widget_Grid_MassactionTest extends PHPUnit_Framework_Te } /** - * @covers getItems - * @covers getCount - * @covers getItemsJson - * @covers isAvailable + * @covers Mage_Backend_Block_Widget_Grid_Massaction::getItems + * @covers Mage_Backend_Block_Widget_Grid_Massaction::getCount + * @covers Mage_Backend_Block_Widget_Grid_Massaction::getItemsJson + * @covers Mage_Backend_Block_Widget_Grid_Massaction::isAvailable + * @magentoConfigFixture adminhtml/design/theme/full_name test/default */ public function testMassactionDefaultValues() { @@ -92,6 +76,9 @@ class Mage_Backend_Block_Widget_Grid_MassactionTest extends PHPUnit_Framework_Te $this->assertFalse($blockEmpty->isAvailable()); } + /** + * @magentoConfigFixture adminhtml/design/theme/full_name test/default + */ public function testJavascript() { $javascript = $this->_block->getJavaScript(); @@ -107,6 +94,9 @@ class Mage_Backend_Block_Widget_Grid_MassactionTest extends PHPUnit_Framework_Te $this->assertRegExp($expectedItemSecond, $javascript); } + /** + * @magentoConfigFixture adminhtml/design/theme/full_name test/default + */ public function testJavascriptWithAddedItem() { $input = array( @@ -123,6 +113,9 @@ class Mage_Backend_Block_Widget_Grid_MassactionTest extends PHPUnit_Framework_Te $this->assertRegExp($expected, $this->_block->getJavaScript()); } + /** + * @magentoConfigFixture adminhtml/design/theme/full_name test/default + */ public function testItemsCount() { $this->assertEquals(2, count($this->_block->getItems())); @@ -133,6 +126,7 @@ class Mage_Backend_Block_Widget_Grid_MassactionTest extends PHPUnit_Framework_Te * @param $itemId * @param $expectedItem * @dataProvider itemsDataProvider + * @magentoConfigFixture adminhtml/design/theme/full_name test/default */ public function testItems($itemId, $expectedItem) { @@ -176,6 +170,9 @@ class Mage_Backend_Block_Widget_Grid_MassactionTest extends PHPUnit_Framework_Te ); } + /** + * @magentoConfigFixture adminhtml/design/theme/full_name test/default + */ public function testGridContainsMassactionColumn() { $this->_layout->getBlock('admin.test.grid')->toHtml(); diff --git a/dev/tests/integration/testsuite/Mage/Backend/Block/_files/theme_registration.php b/dev/tests/integration/testsuite/Mage/Backend/Block/_files/theme_registration.php new file mode 100644 index 0000000000000000000000000000000000000000..b20be409a2952deab7a3665e4a9d3b17632986e1 --- /dev/null +++ b/dev/tests/integration/testsuite/Mage/Backend/Block/_files/theme_registration.php @@ -0,0 +1,39 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @category Mage + * @package Mage_Core + * @copyright Copyright (c) 2012 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +/* Point application to predefined layout fixtures */ +Mage::getConfig()->setOptions(array( + 'design_dir' => realpath( __DIR__ . '/design'), +)); + +/** @var $themeRegistration Mage_Core_Model_Theme_Registration */ +$themeRegistration = Mage::getObjectManager()->create('Mage_Core_Model_Theme_Registration'); +$themeRegistration->register(); + +Mage::getDesign()->setDesignTheme('test/default', 'adminhtml'); + +/* Disable loading and saving layout cache */ +Mage::app()->getCacheInstance()->banUse('layout'); diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Block/Product/Configurable/AssociatedSelector/Backend/Grid/ColumnSetTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Block/Product/Configurable/AssociatedSelector/Backend/Grid/ColumnSetTest.php new file mode 100644 index 0000000000000000000000000000000000000000..6ee75831ba153c894c5e54fdd8e61ea50ccf55e5 --- /dev/null +++ b/dev/tests/integration/testsuite/Mage/Catalog/Block/Product/Configurable/AssociatedSelector/Backend/Grid/ColumnSetTest.php @@ -0,0 +1,55 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @category Magento + * @package Mage_Catalog + * @subpackage integration_tests + * @copyright Copyright (c) 2012 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +class Mage_Catalog_Block_Product_Configurable_AssociatedSelector_Backend_Grid_ColumnSetTest + extends PHPUnit_Framework_TestCase +{ + + /** + * Testing adding column with configurable attribute to column set + * + * @magentoAppIsolation enabled + * @magentoDataFixture Mage/Catalog/_files/product_configurable.php + */ + public function testPrepareSelect() + { + $product = Mage::getModel('Mage_Catalog_Model_Product'); + $product->load(1); // fixture + Mage::register('current_product', $product); + + /** @var $layout Mage_Core_Model_Layout */ + $layout = Mage::getSingleton('Mage_Core_Model_Layout'); + /** @var $block Mage_Catalog_Block_Product_Configurable_AssociatedSelector_Backend_Grid_ColumnSet */ + $block = $layout->createBlock( + 'Mage_Catalog_Block_Product_Configurable_AssociatedSelector_Backend_Grid_ColumnSet', + 'block' + ); + $assertBlock = $block->getLayout()->getBlock('block.test_configurable'); + $this->assertEquals('Test Configurable', $assertBlock->getHeader()); + $this->assertEquals('test_configurable', $assertBlock->getId()); + } +} diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Block/Product/NewTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Block/Product/NewTest.php index bb9d7f14d88249153265427511631fcea697fdd7..67d04335cf594f4cbdb5ecfda9e2e4cbd2298ef9 100644 --- a/dev/tests/integration/testsuite/Mage/Catalog/Block/Product/NewTest.php +++ b/dev/tests/integration/testsuite/Mage/Catalog/Block/Product/NewTest.php @@ -61,7 +61,7 @@ class Mage_Catalog_Block_Product_NewTest extends PHPUnit_Framework_TestCase $this->assertEquals(Mage::app()->getStore()->getId(), $info[1]); $this->assertSame(2, array_shift($keys)); - $this->assertEquals(Mage::getDesign()->getDesignTheme()->getId(), $info[2]); + $this->assertEquals(Mage_Core_Model_Theme::CACHE_TAG_NO_THEME, $info[2]); $this->assertSame(3, array_shift($keys)); $this->assertEquals(Mage::getSingleton('Mage_Customer_Model_Session')->getCustomerGroupId(), $info[3]); diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Type/AbstractTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Type/AbstractTest.php index f046253d195c48ca3f68975cf1924e70f575dda4..2bb839978e66dbefa17e53c574bc9fd58a154fb7 100644 --- a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Type/AbstractTest.php +++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Type/AbstractTest.php @@ -101,9 +101,15 @@ class Mage_Catalog_Model_Product_Type_AbstractTest extends PHPUnit_Framework_Tes // not clear how to test what is apply_to and what does it have to do with "editable" term + $isTypeExists = false; foreach ($attributes as $attribute) { $this->assertInstanceOf('Mage_Catalog_Model_Resource_Eav_Attribute', $attribute); + $applyTo = $attribute->getApplyTo(); + if (count($applyTo) > 0 && !in_array('simple', $applyTo)) { + $isTypeExists = true; + } } + $this->assertTrue($isTypeExists); } public function testGetAttributeById() diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Type/ConfigurableTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Type/ConfigurableTest.php index c3d6e73bff7bfe400dafd5c03b4a5f2c72bc05f8..30c75daa9bd482c9b89a35276752f9374f5dde49 100644 --- a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Type/ConfigurableTest.php +++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Type/ConfigurableTest.php @@ -38,7 +38,7 @@ class Mage_Catalog_Model_Product_Type_ConfigurableTest extends PHPUnit_Framework /** * @var Mage_Catalog_Model_Product */ - protected $_product = null; + protected $_product; protected function setUp() { @@ -75,23 +75,6 @@ class Mage_Catalog_Model_Product_Type_ConfigurableTest extends PHPUnit_Framework $this->assertTrue(2 === count($ids[0])); } - // testGetParentIdsByChild is after testGetConfigurableAttributesAsArray, because depends on it. - - public function testGetEditableAttributes() - { - $attributes = $this->_model->getEditableAttributes($this->_product); - - // applicable to all types - $this->assertArrayHasKey('sku', $attributes); - $this->assertArrayHasKey('name', $attributes); - - // applicable to configurable - $this->assertArrayHasKey('price', $attributes); - - // not applicable to configurable - $this->assertArrayNotHasKey('weight', $attributes); - } - public function testCanUseAttribute() { $this->assertFalse($this->_model->canUseAttribute($this->_getAttributeByCode('sku'))); @@ -384,6 +367,39 @@ class Mage_Catalog_Model_Product_Type_ConfigurableTest extends PHPUnit_Framework $this->assertEquals(array('super_attribute' => array(10)), $result); } + public function testSaveProductRelationsOneChild() + { + $oldChildrenIds = $this->_product->getTypeInstance()->getChildrenIds(1); + $oldChildrenIds = reset($oldChildrenIds); + $oneChildId = reset($oldChildrenIds); + $this->assertNotEmpty($oldChildrenIds); + $this->assertNotEmpty($oneChildId); + + $this->_product->setAssociatedProductIds(array($oneChildId)); + $this->_model->save($this->_product); + $this->_product->load(1); + + $this->assertEquals( + array(array($oneChildId => $oneChildId)), + $this->_product->getTypeInstance()->getChildrenIds(1) + ); + } + + public function testSaveProductRelationsNoChildren() + { + $childrenIds = $this->_product->getTypeInstance()->getChildrenIds(1); + $this->assertNotEmpty(reset($childrenIds)); + + $this->_product->setAssociatedProductIds(array()); + $this->_model->save($this->_product); + $this->_product->load(1); + + $this->assertEquals( + array(array()), + $this->_product->getTypeInstance()->getChildrenIds(1) + ); + } + /** * Find and instantiate a catalog attribute model by attribute code * diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Resource/Product/Collection/AssociatedProductTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Resource/Product/Collection/AssociatedProductTest.php new file mode 100644 index 0000000000000000000000000000000000000000..8852565897334f933f9b01f704ac148e1f395fd2 --- /dev/null +++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Resource/Product/Collection/AssociatedProductTest.php @@ -0,0 +1,62 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @category Magento + * @package Mage_Catalog + * @subpackage integration_tests + * @copyright Copyright (c) 2012 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +class Mage_Catalog_Model_Resource_Product_Collection_AssociatedProductTest extends PHPUnit_Framework_TestCase +{ + /** + * @magentoAppIsolation enabled + * @magentoDataFixture Mage/Catalog/_files/product_associated.php + */ + public function testPrepareSelect() + { + $product = Mage::getModel('Mage_Catalog_Model_Product'); + $product->load(1); // fixture + $product->setId(10); + Mage::register('current_product', $product); + $collection = Mage::getResourceModel('Mage_Catalog_Model_Resource_Product_Collection_AssociatedProduct'); + $collectionProduct = $collection->getFirstItem(); + $this->assertEquals($product->getName(), $collectionProduct->getName()); + $this->assertEquals($product->getSku(), $collectionProduct->getSku()); + $this->assertEquals($product->getPrice(), $collectionProduct->getPrice()); + $this->assertEquals($product->getWeight(), $collectionProduct->getWeight()); + $this->assertEquals($product->getTypeId(), $collectionProduct->getTypeId()); + $this->assertEquals($product->getAttributeSetId(), $collectionProduct->getAttributeSetId()); + } + + /** + * @magentoAppIsolation enabled + * @magentoDataFixture Mage/Catalog/_files/product_associated.php + */ + public function testPrepareSelectForSameProduct() + { + $product = Mage::getModel('Mage_Catalog_Model_Product'); + $product->load(1); // fixture + Mage::register('current_product', $product); + $collection = Mage::getResourceModel('Mage_Catalog_Model_Resource_Product_Collection_AssociatedProduct'); + $this->assertEmpty($collection->count()); + } +} diff --git a/dev/tests/integration/testsuite/Mage/Catalog/_files/product_associated.php b/dev/tests/integration/testsuite/Mage/Catalog/_files/product_associated.php new file mode 100644 index 0000000000000000000000000000000000000000..8755a943acda4674e79894f872ead03a8a2c7e5c --- /dev/null +++ b/dev/tests/integration/testsuite/Mage/Catalog/_files/product_associated.php @@ -0,0 +1,50 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @category Magento + * @package Mage_Catalog + * @subpackage integration_tests + * @copyright Copyright (c) 2012 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +/* Create simple product */ +/** @var $product Mage_Catalog_Model_Product */ +$product = Mage::getModel('Mage_Catalog_Model_Product'); +$product->setTypeId('simple') + ->setId(1) + ->setAttributeSetId(4) + ->setWebsiteIds(array(1)) + ->setName('Simple Product') + ->setSku('simple') + ->setPrice(10) + ->setWeight(1) + + ->setMetaTitle('meta title') + ->setMetaKeyword('meta keyword') + ->setMetaDescription('meta description') + + ->setVisibility(Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH) + ->setStatus(Mage_Catalog_Model_Product_Status::STATUS_ENABLED) + + ->setStockData(array( + 'use_config_manage_stock' => 0, + )) + ->save(); diff --git a/dev/tests/integration/testsuite/Mage/Catalog/_files/product_configurable.php b/dev/tests/integration/testsuite/Mage/Catalog/_files/product_configurable.php index 2782e697bfa6c7481b984887b368491537a64278..0d6369588377c5b29b3db3cd276744eba400d61e 100644 --- a/dev/tests/integration/testsuite/Mage/Catalog/_files/product_configurable.php +++ b/dev/tests/integration/testsuite/Mage/Catalog/_files/product_configurable.php @@ -30,42 +30,38 @@ $installer = Mage::getResourceModel('Mage_Catalog_Model_Resource_Setup', array('resourceName' => 'catalog_setup')); /** @var $attribute Mage_Catalog_Model_Resource_Eav_Attribute */ $attribute = Mage::getResourceModel('Mage_Catalog_Model_Resource_Eav_Attribute'); -$attribute->setData( - array( - 'attribute_code' => 'test_configurable', - 'entity_type_id' => $installer->getEntityTypeId('catalog_product'), - 'is_global' => 1, - 'is_user_defined' => 1, - 'frontend_input' => 'select', - 'is_unique' => 0, - 'is_required' => 1, - 'is_configurable' => 1, - 'is_searchable' => 0, - 'is_visible_in_advanced_search' => 0, - 'is_comparable' => 0, - 'is_filterable' => 0, - 'is_filterable_in_search' => 0, - 'is_used_for_promo_rules' => 0, - 'is_html_allowed_on_front' => 1, - 'is_visible_on_front' => 0, - 'used_in_product_listing' => 0, - 'used_for_sort_by' => 0, - 'frontend_label' => array( - 0 => 'Test Configurable' +$attribute->setData(array( + 'attribute_code' => 'test_configurable', + 'entity_type_id' => $installer->getEntityTypeId('catalog_product'), + 'is_global' => 1, + 'is_user_defined' => 1, + 'frontend_input' => 'select', + 'is_unique' => 0, + 'is_required' => 1, + 'is_configurable' => 1, + 'is_searchable' => 0, + 'is_visible_in_advanced_search' => 0, + 'is_comparable' => 0, + 'is_filterable' => 0, + 'is_filterable_in_search' => 0, + 'is_used_for_promo_rules' => 0, + 'is_html_allowed_on_front' => 1, + 'is_visible_on_front' => 0, + 'used_in_product_listing' => 0, + 'used_for_sort_by' => 0, + 'frontend_label' => array('Test Configurable'), + 'backend_type' => 'int', + 'option' => array( + 'value' => array( + 'option_0' => array('Option 1'), + 'option_1' => array('Option 2'), ), - 'option' => array( - 'value' => array( - 'option_0' => array(0 => 'Option 1'), - 'option_1' => array(0 => 'Option 2'), - ), - 'order' => array( - 'option_0' => 1, - 'option_1' => 2, - ) - ), - 'backend_type' => 'int', - ) -); + 'order' => array( + 'option_0' => 1, + 'option_1' => 2, + ) + ), +)); $attribute->save(); /* Assign attribute to attribute set */ @@ -77,38 +73,35 @@ $options = Mage::getResourceModel('Mage_Eav_Model_Resource_Entity_Attribute_Opti $options->setAttributeFilter($attribute->getId()); $attributeValues = array(); -$productsData = array(); +$productIds = array(); foreach ($options as $option) { /** @var $product Mage_Catalog_Model_Product */ $product = Mage::getModel('Mage_Catalog_Model_Product'); $product->setTypeId(Mage_Catalog_Model_Product_Type::TYPE_SIMPLE) - ->setId($option->getId()*10) + ->setId($option->getId() * 10) ->setAttributeSetId($installer->getAttributeSetId('catalog_product', 'Default')) ->setWebsiteIds(array(1)) - ->setName('Configurable Option'.$option->getId()) - ->setSku('simple_'.$option->getId()) + ->setName('Configurable Option' . $option->getId()) + ->setSku('simple_' . $option->getId()) ->setPrice(10) ->setTestConfigurable($option->getId()) ->setVisibility(Mage_Catalog_Model_Product_Visibility::VISIBILITY_NOT_VISIBLE) ->setStatus(Mage_Catalog_Model_Product_Status::STATUS_ENABLED) - ->setStockData( - array( - 'use_config_manage_stock' => 1, - 'qty' => 100, - 'is_qty_decimal' => 0, - 'is_in_stock' => 1, - ) - ) + ->setStockData(array( + 'use_config_manage_stock' => 1, + 'qty' => 100, + 'is_qty_decimal' => 0, + 'is_in_stock' => 1, + )) ->save(); - $dataOption = array( + $attributeValues[] = array( 'label' => 'test', 'attribute_id' => $attribute->getId(), 'value_index' => $option->getId(), 'is_percent' => false, 'pricing_value' => 5, ); - $productsData[$product->getId()] = array($dataOption); - $attributeValues[] = $dataOption; + $productIds[] = $product->getId(); } /** @var $product Mage_Catalog_Model_Product */ @@ -122,21 +115,15 @@ $product->setTypeId(Mage_Catalog_Model_Product_Type::TYPE_CONFIGURABLE) ->setPrice(100) ->setVisibility(Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH) ->setStatus(Mage_Catalog_Model_Product_Status::STATUS_ENABLED) - ->setStockData( - array( - 'use_config_manage_stock' => 1, - 'is_in_stock' => 1, - ) - ) - ->setConfigurableProductsData($productsData) - ->setConfigurableAttributesData( - array( - array( - 'attribute_id' => $attribute->getId(), - 'attribute_code'=> $attribute->getAttributeCode(), - 'frontend_label'=> 'test', - 'values' => $attributeValues, - ) - ) - ) + ->setStockData(array( + 'use_config_manage_stock' => 1, + 'is_in_stock' => 1, + )) + ->setAssociatedProductIds($productIds) + ->setConfigurableAttributesData(array(array( + 'attribute_id' => $attribute->getId(), + 'attribute_code' => $attribute->getAttributeCode(), + 'frontend_label' => 'test', + 'values' => $attributeValues, + ))) ->save(); diff --git a/dev/tests/integration/testsuite/Mage/Catalog/_files/product_simple_xss.php b/dev/tests/integration/testsuite/Mage/Catalog/_files/product_simple_xss.php new file mode 100644 index 0000000000000000000000000000000000000000..0b9c3792e121f415699b578adfadda8748a5509b --- /dev/null +++ b/dev/tests/integration/testsuite/Mage/Catalog/_files/product_simple_xss.php @@ -0,0 +1,46 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @category Magento + * @package Mage_Catalog + * @subpackage integration_tests + * @copyright Copyright (c) 2012 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +$product = Mage::getModel('Mage_Catalog_Model_Product'); +$product->setTypeId(Mage_Catalog_Model_Product_Type::TYPE_SIMPLE) + ->setId(1) + ->setAttributeSetId(4) + ->setWebsiteIds(array(1)) + ->setName('<script>alert("xss");</script>') + ->setSku('<script>alert("xss");</script>') + ->setPrice(10) + ->setDescription('Description with <b>html tag</b>') + ->setVisibility(Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH) + ->setStatus(Mage_Catalog_Model_Product_Status::STATUS_ENABLED) + ->setCategoryIds(array(2)) + ->setStockData(array( + 'use_config_manage_stock' => 1, + 'qty' => 100, + 'is_qty_decimal' => 0, + 'is_in_stock' => 1, + )) + ->save(); diff --git a/dev/tests/integration/testsuite/Mage/Catalog/controllers/Product/CompareControllerTest.php b/dev/tests/integration/testsuite/Mage/Catalog/controllers/Product/CompareControllerTest.php index 4e51a35f44ba9776e7d0d3df37c309a7420b4981..79ab75bc13327f52345cd99bd8d1e42720861177 100644 --- a/dev/tests/integration/testsuite/Mage/Catalog/controllers/Product/CompareControllerTest.php +++ b/dev/tests/integration/testsuite/Mage/Catalog/controllers/Product/CompareControllerTest.php @@ -19,78 +19,17 @@ * needs please refer to http://www.magentocommerce.com for more information. * * @category Magento - * @package Magento_Catalog + * @package Mage_Catalog * @subpackage integration_tests * @copyright Copyright (c) 2012 X.commerce, Inc. (http://www.magentocommerce.com) * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ /** - * Test class for Mage_Catalog_Product_CompareController. - * * @magentoDataFixture Mage/Catalog/controllers/_files/products.php */ class Mage_Catalog_Product_CompareControllerTest extends Magento_Test_TestCase_ControllerAbstract { - protected function _requireVisitorWithNoProducts() - { - /** @var $visitor Mage_Log_Model_Visitor */ - $visitor = Mage::getModel('Mage_Log_Model_Visitor'); - $visitor->setSessionId(md5(time()) . md5(microtime())) - ->setLastVisitAt(now()) - ->save(); - - Mage::getSingleton('Mage_Log_Model_Visitor')->load($visitor->getId()); - - $this->_assertCompareListEquals(array()); - } - - protected function _requireVisitorWithTwoProducts() - { - /** @var $visitor Mage_Log_Model_Visitor */ - $visitor = Mage::getModel('Mage_Log_Model_Visitor'); - $visitor->setSessionId(md5(time()) . md5(microtime())) - ->setLastVisitAt(now()) - ->save(); - - /** @var $item Mage_Catalog_Model_Product_Compare_Item */ - $item = Mage::getModel('Mage_Catalog_Model_Product_Compare_Item'); - $item->setVisitorId($visitor->getId()) - ->setProductId(1) - ->save(); - - /** @var $item Mage_Catalog_Model_Product_Compare_Item */ - $item = Mage::getModel('Mage_Catalog_Model_Product_Compare_Item'); - $item->setVisitorId($visitor->getId()) - ->setProductId(2) - ->save(); - - Mage::getSingleton('Mage_Log_Model_Visitor')->load($visitor->getId()); - - $this->_assertCompareListEquals(array(1, 2)); - } - - /** - * Assert that current visitor has exactly expected products in compare list - * - * @param array $expectedProductIds - */ - protected function _assertCompareListEquals(array $expectedProductIds) - { - /** @var $compareItems Mage_Catalog_Model_Resource_Product_Compare_Item_Collection */ - $compareItems = Mage::getResourceModel('Mage_Catalog_Model_Resource_Product_Compare_Item_Collection'); - $compareItems->useProductItem(true); // important - $compareItems->setVisitorId( - Mage::getSingleton('Mage_Log_Model_Visitor')->getId() - ); - $actualProductIds = array(); - foreach ($compareItems as $compareItem) { - /** @var $compareItem Mage_Catalog_Model_Product_Compare_Item */ - $actualProductIds[] = $compareItem->getProductId(); - } - $this->assertEquals($expectedProductIds, $actualProductIds, "Products in current visitor's compare list."); - } - public function testAddAction() { $this->_requireVisitorWithNoProducts(); @@ -171,4 +110,96 @@ class Mage_Catalog_Product_CompareControllerTest extends Magento_Test_TestCase_C $this->_assertCompareListEquals(array()); } + + /** + * @magentoDataFixture Mage/Catalog/_files/product_simple_xss.php + */ + public function testRemoveActionProductNameXss() + { + $this->_prepareCompareListWithProductNameXss(); + $this->dispatch('catalog/product_compare/remove/product/1?nocookie=1'); + $messages = Mage::getSingleton('Mage_Catalog_Model_Session')->getMessages()->getItems(); + $isProductNamePresent = false; + foreach ($messages as $message) { + if (strpos($message->getCode(), '<script>alert("xss");</script>') !== false) { + $isProductNamePresent = true; + } + $this->assertNotContains('<script>alert("xss");</script>', $message->getCode()); + } + $this->assertTrue($isProductNamePresent, 'Product name was not found in session messages'); + } + + protected function _prepareCompareListWithProductNameXss() + { + /** @var $visitor Mage_Log_Model_Visitor */ + $visitor = Mage::getModel('Mage_Log_Model_Visitor'); + $visitor->setSessionId(md5(time()) . md5(microtime())) + ->setLastVisitAt(now()) + ->save(); + /** @var $item Mage_Catalog_Model_Product_Compare_Item */ + $item = Mage::getModel('Mage_Catalog_Model_Product_Compare_Item'); + $item->setVisitorId($visitor->getId()) + ->setProductId(1) + ->save(); + Mage::getSingleton('Mage_Log_Model_Visitor')->load($visitor->getId()); + } + + protected function _requireVisitorWithNoProducts() + { + /** @var $visitor Mage_Log_Model_Visitor */ + $visitor = Mage::getModel('Mage_Log_Model_Visitor'); + $visitor->setSessionId(md5(time()) . md5(microtime())) + ->setLastVisitAt(now()) + ->save(); + + Mage::getSingleton('Mage_Log_Model_Visitor')->load($visitor->getId()); + + $this->_assertCompareListEquals(array()); + } + + protected function _requireVisitorWithTwoProducts() + { + /** @var $visitor Mage_Log_Model_Visitor */ + $visitor = Mage::getModel('Mage_Log_Model_Visitor'); + $visitor->setSessionId(md5(time()) . md5(microtime())) + ->setLastVisitAt(now()) + ->save(); + + /** @var $item Mage_Catalog_Model_Product_Compare_Item */ + $item = Mage::getModel('Mage_Catalog_Model_Product_Compare_Item'); + $item->setVisitorId($visitor->getId()) + ->setProductId(1) + ->save(); + + /** @var $item Mage_Catalog_Model_Product_Compare_Item */ + $item = Mage::getModel('Mage_Catalog_Model_Product_Compare_Item'); + $item->setVisitorId($visitor->getId()) + ->setProductId(2) + ->save(); + + Mage::getSingleton('Mage_Log_Model_Visitor')->load($visitor->getId()); + + $this->_assertCompareListEquals(array(1, 2)); + } + + /** + * Assert that current visitor has exactly expected products in compare list + * + * @param array $expectedProductIds + */ + protected function _assertCompareListEquals(array $expectedProductIds) + { + /** @var $compareItems Mage_Catalog_Model_Resource_Product_Compare_Item_Collection */ + $compareItems = Mage::getResourceModel('Mage_Catalog_Model_Resource_Product_Compare_Item_Collection'); + $compareItems->useProductItem(true); // important + $compareItems->setVisitorId( + Mage::getSingleton('Mage_Log_Model_Visitor')->getId() + ); + $actualProductIds = array(); + foreach ($compareItems as $compareItem) { + /** @var $compareItem Mage_Catalog_Model_Product_Compare_Item */ + $actualProductIds[] = $compareItem->getProductId(); + } + $this->assertEquals($expectedProductIds, $actualProductIds, "Products in current visitor's compare list."); + } } diff --git a/dev/tests/integration/testsuite/Mage/Catalog/controllers/_files/attribute_system.php b/dev/tests/integration/testsuite/Mage/Catalog/controllers/_files/attribute_system.php new file mode 100644 index 0000000000000000000000000000000000000000..8ab6f16cb550d66ec9e01cc816a6c28fb7c359d6 --- /dev/null +++ b/dev/tests/integration/testsuite/Mage/Catalog/controllers/_files/attribute_system.php @@ -0,0 +1,36 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @category Magento + * @package Mage_Catalog + * @subpackage integration_tests + * @copyright Copyright (c) 2012 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +$model = new Mage_Catalog_Model_Resource_Eav_Attribute( + new Mage_Core_Model_Event_Manager(), + new Mage_Core_Model_Cache() +); +$model->setName('system_attribute') + ->setId(2) + ->setEntityTypeId(4) + ->setIsUserDefined(0); +$model->save(); \ No newline at end of file diff --git a/dev/tests/integration/testsuite/Mage/Catalog/controllers/_files/attribute_system_with_applyto_data.php b/dev/tests/integration/testsuite/Mage/Catalog/controllers/_files/attribute_system_with_applyto_data.php new file mode 100644 index 0000000000000000000000000000000000000000..029aea37338380030463c326f2bd5292af036213 --- /dev/null +++ b/dev/tests/integration/testsuite/Mage/Catalog/controllers/_files/attribute_system_with_applyto_data.php @@ -0,0 +1,37 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @category Magento + * @package Mage_Catalog + * @subpackage integration_tests + * @copyright Copyright (c) 2012 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +$model = new Mage_Catalog_Model_Resource_Eav_Attribute( + new Mage_Core_Model_Event_Manager(), + new Mage_Core_Model_Cache() +); +$model->setName('system_attribute') + ->setId(3) + ->setEntityTypeId(4) + ->setIsUserDefined(0) + ->setApplyTo(array('simple', 'configurable')); +$model->save(); \ No newline at end of file diff --git a/dev/tests/integration/testsuite/Mage/Catalog/controllers/_files/attribute_user_defined.php b/dev/tests/integration/testsuite/Mage/Catalog/controllers/_files/attribute_user_defined.php new file mode 100644 index 0000000000000000000000000000000000000000..3c4fc82f0449221f77c85173b5be62fc48b4bc69 --- /dev/null +++ b/dev/tests/integration/testsuite/Mage/Catalog/controllers/_files/attribute_user_defined.php @@ -0,0 +1,36 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @category Magento + * @package Mage_Catalog + * @subpackage integration_tests + * @copyright Copyright (c) 2012 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +$model = new Mage_Catalog_Model_Resource_Eav_Attribute( + new Mage_Core_Model_Event_Manager(), + new Mage_Core_Model_Cache() +); +$model->setName('user_attribute') + ->setId(1) + ->setEntityTypeId(4) + ->setIsUserDefined(1); +$model->save(); diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/Email/Template/FilterTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/Email/Template/FilterTest.php index 16fe680c294b2db0aa66ffd2fc47d4881212b944..71e586efa193800587ac642fc4b1be403614379f 100644 --- a/dev/tests/integration/testsuite/Mage/Core/Model/Email/Template/FilterTest.php +++ b/dev/tests/integration/testsuite/Mage/Core/Model/Email/Template/FilterTest.php @@ -117,16 +117,12 @@ class Mage_Core_Model_Email_Template_FilterTest extends PHPUnit_Framework_TestCa */ public function testLayoutDirective($currentArea, $directiveParams, $expectedOutput) { - $this->markTestIncomplete('MAGETWO-5812'); - /** @var $themeUtility Mage_Core_Utility_Theme */ - $themeUtility = Mage::getModel('Mage_Core_Utility_Theme', array(dirname(__DIR__) . '/_files/design')); + $themeUtility = Mage::getModel('Mage_Core_Utility_Theme', array( + dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'design' + )); $themeUtility->registerThemes()->setDesignTheme('test/default', $currentArea); - Mage::getConfig()->cleanCache(); - $themeFrontend = $themeUtility->getThemeByParams('test/default', 'frontend'); - Mage::app()->getStore('default')->setConfig('design/theme/theme_id', $themeFrontend->getId()); - $this->_emulateCurrentArea($currentArea); $actualOutput = $this->_model->layoutDirective(array( '{{layout ' . $directiveParams . '}}', diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/Email/TemplateTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/Email/TemplateTest.php index dff6a6037abcc523e44a259628f159b3eff77ac5..6037e00e2117b28688258f068bd3d34d7942a830 100644 --- a/dev/tests/integration/testsuite/Mage/Core/Model/Email/TemplateTest.php +++ b/dev/tests/integration/testsuite/Mage/Core/Model/Email/TemplateTest.php @@ -82,8 +82,7 @@ class Mage_Core_Model_Email_TemplateTest extends PHPUnit_Framework_TestCase public function testLoadDefault() { Mage::app()->getConfig()->getOptions() - ->setLocaleDir(dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'locale') - ; + ->setLocaleDir(dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'locale'); $this->_model->loadDefault('customer_create_account_email_template'); $this->assertNotEmpty($this->_model->getTemplateText()); @@ -108,11 +107,12 @@ class Mage_Core_Model_Email_TemplateTest extends PHPUnit_Framework_TestCase /** * @magentoAppIsolation enabled * @magentoDataFixture Mage/Core/_files/store.php - * @magentoConfigFixture fixturestore_store design/theme/full_name default/demo_blue + * @magentoConfigFixture fixturestore_store design/theme/full_name test/default + * @magentoDataFixture Mage/Core/Model/Email/_files/theme_registration.php */ public function testGetProcessedTemplate() { - $expectedViewUrl = 'theme/frontend/default/demo_blue/en_US/Mage_Page/favicon.ico'; + $expectedViewUrl = 'theme/frontend/test/default/en_US/Mage_Page/favicon.ico'; $this->_model->setTemplateText('{{view url="Mage_Page::favicon.ico"}}'); $this->assertStringEndsNotWith($expectedViewUrl, $this->_model->getProcessedTemplate()); $this->_model->setDesignConfig(array( @@ -137,11 +137,12 @@ class Mage_Core_Model_Email_TemplateTest extends PHPUnit_Framework_TestCase /** * @magentoAppIsolation enabled * @magentoDataFixture Mage/Core/_files/store.php - * @magentoConfigFixture fixturestore_store design/theme/full_name default/demo_blue + * @magentoConfigFixture fixturestore_store design/theme/full_name test/default + * @magentoDataFixture Mage/Core/Model/Email/_files/theme_registration.php */ public function testGetProcessedTemplateSubject() { - $expectedViewUrl = 'theme/frontend/default/demo_blue/en_US/Mage_Page/favicon.ico'; + $expectedViewUrl = 'theme/frontend/test/default/en_US/Mage_Page/favicon.ico'; $this->_model->setTemplateSubject('{{view url="Mage_Page::favicon.ico"}}'); $this->assertStringEndsNotWith($expectedViewUrl, $this->_model->getProcessedTemplateSubject(array())); $this->_model->setDesignConfig(array( diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/Email/_files/theme_registration.php b/dev/tests/integration/testsuite/Mage/Core/Model/Email/_files/theme_registration.php new file mode 100644 index 0000000000000000000000000000000000000000..15d20d22664f87a60b1d8484c095673e2e27c256 --- /dev/null +++ b/dev/tests/integration/testsuite/Mage/Core/Model/Email/_files/theme_registration.php @@ -0,0 +1,40 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @category Magento + * @package Mage_Core + * @subpackage integration_tests + * @copyright Copyright (c) 2012 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +/* Point application to predefined layout fixtures */ +Mage::getConfig()->setOptions(array( + 'design_dir' => realpath( __DIR__ . '/design'), +)); + +/** @var $themeRegistration Mage_Core_Model_Theme_Registration */ +$themeRegistration = Mage::getObjectManager()->create('Mage_Core_Model_Theme_Registration'); +$themeRegistration->register(); + +Mage::getDesign()->setDesignTheme('test/default', 'adminhtml'); + +/* Disable loading and saving layout cache */ +Mage::app()->getCacheInstance()->banUse('layout'); diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/Layout/MergeTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/Layout/MergeTest.php index c9eaddfe5b7312377b95ce23008f554cc86707cc..3c060317fe6be4c22a68b965cc98b1150d2aafe5 100644 --- a/dev/tests/integration/testsuite/Mage/Core/Model/Layout/MergeTest.php +++ b/dev/tests/integration/testsuite/Mage/Core/Model/Layout/MergeTest.php @@ -44,7 +44,7 @@ class Mage_Core_Model_Layout_MergeTest extends PHPUnit_Framework_TestCase protected function setUp() { $this->_themeUtility = Mage::getModel('Mage_Core_Utility_Theme', array( - dirname(dirname(__FILE__)) . '/_files/design', + dirname(__DIR__) . '/_files/design', Mage::getDesign() )); $this->_themeUtility->registerThemes()->setDesignTheme('test/default', 'frontend'); @@ -215,10 +215,14 @@ class Mage_Core_Model_Layout_MergeTest extends PHPUnit_Framework_TestCase ); } + /** + * @magentoAppIsolation enabled + */ public function testLoad() { $layoutHandle = 'layout_test_handle'; $expectedText = 'Text declared in the frontend/test/test_theme'; + /** @var $model Mage_Core_Model_Layout_Merge */ $model = Mage::getModel('Mage_Core_Model_Layout_Merge', array('arguments' => array( 'area' => 'frontend', 'themeId' => $this->_themeUtility->getThemeByParams('test/test_theme', 'frontend')->getId() diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/LayoutArgumentTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/LayoutArgumentTest.php index 828962340525d5f3ab04a7368f6b95c64c665a8b..949dc10da51abfe5a919cdf1b81ac5bd8366877c 100644 --- a/dev/tests/integration/testsuite/Mage/Core/Model/LayoutArgumentTest.php +++ b/dev/tests/integration/testsuite/Mage/Core/Model/LayoutArgumentTest.php @@ -33,6 +33,9 @@ */ class Mage_Core_Model_LayoutArgumentTest extends Mage_Core_Model_LayoutTestBase { + /** + * @magentoConfigFixture default_store design/theme/full_name test/default + */ public function testLayoutArgumentsDirective() { $this->_layout->getUpdate()->load(array('layout_test_handle_arguments')); @@ -42,6 +45,9 @@ class Mage_Core_Model_LayoutArgumentTest extends Mage_Core_Model_LayoutTestBase $this->assertEquals('3', $this->_layout->getBlock('block_with_args')->getThree()); } + /** + * @magentoConfigFixture default_store design/theme/full_name test/default + */ public function testLayoutArgumentsDirectiveIfComplexValues() { $this->_layout->getUpdate()->load(array('layout_test_handle_arguments_complex_values')); @@ -56,6 +62,9 @@ class Mage_Core_Model_LayoutArgumentTest extends Mage_Core_Model_LayoutTestBase $this->_layout->getBlock('block_with_args_complex_values')->getThree()); } + /** + * @magentoConfigFixture default_store design/theme/full_name test/default + */ public function testLayoutObjectArgumentsDirective() { $this->_layout->getUpdate()->load(array('layout_test_handle_arguments_object_type')); @@ -67,6 +76,9 @@ class Mage_Core_Model_LayoutArgumentTest extends Mage_Core_Model_LayoutTestBase $this->assertEquals(3, $this->_layout->getBlock('block_with_object_args')->getThree()); } + /** + * @magentoConfigFixture default_store design/theme/full_name test/default + */ public function testLayoutUrlArgumentsDirective() { $this->_layout->getUpdate()->load(array('layout_test_handle_arguments_url_type')); @@ -76,6 +88,9 @@ class Mage_Core_Model_LayoutArgumentTest extends Mage_Core_Model_LayoutTestBase $this->assertContains('customer_id/3', $this->_layout->getBlock('block_with_url_args')->getTwo()); } + /** + * @magentoConfigFixture default_store design/theme/full_name test/default + */ public function testLayoutObjectArgumentUpdatersDirective() { $this->_layout->getUpdate()->load(array('layout_test_handle_arguments_object_type_updaters')); diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/LayoutTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/LayoutTest.php index 17ca5dc43befcf7d7ad7bc93f554809031aea073..fd67a8d8b6f1a63d808de00a35530b4b5f30c32d 100644 --- a/dev/tests/integration/testsuite/Mage/Core/Model/LayoutTest.php +++ b/dev/tests/integration/testsuite/Mage/Core/Model/LayoutTest.php @@ -85,13 +85,15 @@ class Mage_Core_Model_LayoutTest extends Mage_Core_Model_LayoutTestBase * @covers Mage_Core_Model_Layout::getAllBlocks * @covers Mage_Core_Model_Layout::generateBlocks * @covers Mage_Core_Model_Layout::getBlock + * @magentoConfigFixture default_store design/theme/full_name test/default */ public function testGenerateXmlAndElements() { $this->_layout->generateXml(); - /* Generate fixture - file_put_contents(dirname(__FILE__) . '/_files/_layout_update.xml', $this->_model->getNode()->asNiceXml()); - */ + /** + * Generate fixture + * file_put_contents(dirname(__FILE__) . '/_files/_layout_update.xml', $this->_model->getNode()->asNiceXml()); + */ $this->assertXmlStringEqualsXmlFile(__DIR__ . '/_files/_layout_update.xml', $this->_layout->getXmlString()); $this->assertEquals(array(), $this->_layout->getAllBlocks()); @@ -129,6 +131,9 @@ class Mage_Core_Model_LayoutTest extends Mage_Core_Model_LayoutTestBase $this->assertFalse($this->_layout->getBlock('test.nonexisting.block')); } + /** + * @magentoConfigFixture default_store design/theme/full_name test/default + */ public function testLayoutDirectives() { /** @@ -193,6 +198,7 @@ class Mage_Core_Model_LayoutTest extends Mage_Core_Model_LayoutTestBase } /** + * @magentoConfigFixture default_store design/theme/full_name test/default * @expectedException Magento_Exception */ public function testLayoutMoveDirectiveBroken() @@ -203,6 +209,7 @@ class Mage_Core_Model_LayoutTest extends Mage_Core_Model_LayoutTestBase } /** + * @magentoConfigFixture default_store design/theme/full_name test/default * @expectedException Magento_Exception */ public function testLayoutMoveAliasBroken() @@ -213,6 +220,7 @@ class Mage_Core_Model_LayoutTest extends Mage_Core_Model_LayoutTestBase } /** + * @magentoConfigFixture default_store design/theme/full_name test/default * @expectedException Magento_Exception */ public function testGenerateElementsBroken() diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/ObserverTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/ObserverTest.php index 44d21ebcb334b47089c10a6765f67eb357b3f8e8..93288b65447b92d691fc9d52d3567dfc4e464ce2 100644 --- a/dev/tests/integration/testsuite/Mage/Core/Model/ObserverTest.php +++ b/dev/tests/integration/testsuite/Mage/Core/Model/ObserverTest.php @@ -33,6 +33,7 @@ class Mage_Core_Model_ObserverTest extends PHPUnit_Framework_TestCase /** * Theme registration test * + * @magentoDbIsolation enabled * @magentoAppIsolation enabled */ public function testThemeRegistration() diff --git a/dev/tests/integration/testsuite/Mage/Core/Utility/Theme.php b/dev/tests/integration/testsuite/Mage/Core/Utility/Theme.php index cc868519cd4cbfe2899faa7f5bf966d61d3b9753..7809d33353a570a2c6c7a5f8a5e4052e28a5bbaa 100644 --- a/dev/tests/integration/testsuite/Mage/Core/Utility/Theme.php +++ b/dev/tests/integration/testsuite/Mage/Core/Utility/Theme.php @@ -96,7 +96,7 @@ class Mage_Core_Utility_Theme $callBackFixture = function ($area, $params) use ($package, $packageMock) { $area = $area ? $area : $packageMock->getArea(); - if (isset($params['useId']) && $params['useId'] == false) { + if (isset($params['useId']) && $params['useId'] === false) { return $package->getConfigurationDesignTheme($area, $params); } else { $params['useId'] = false; diff --git a/dev/tests/integration/testsuite/Mage/Downloadable/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable/LinksTest.php b/dev/tests/integration/testsuite/Mage/Downloadable/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable/LinksTest.php index 5e388db2a29ae0c9c309d491c59680ad383e3f9f..aeb1701704e0db96aba805de6187ac2ccbbb54c9 100644 --- a/dev/tests/integration/testsuite/Mage/Downloadable/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable/LinksTest.php +++ b/dev/tests/integration/testsuite/Mage/Downloadable/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable/LinksTest.php @@ -54,4 +54,55 @@ class Mage_Downloadable_Block_Adminhtml_Catalog_Product_Edit_Tab_Downloadable_Li $layout->addBlock($text, 'upload_button', 'links'); self::assertEquals($expected, $block->getUploadButtonHtml()); } + + /** + * @magentoAppIsolation enabled + */ + public function testGetLinkData() + { + Mage::register('product', new Varien_Object(array('type_id' => 'simple'))); + $block = Mage::app()->getLayout() + ->createBlock('Mage_Downloadable_Block_Adminhtml_Catalog_Product_Edit_Tab_Downloadable_Links'); + $this->assertEmpty($block->getLinkData()); + } + + /** + * Get Links Title for simple/virtual/downloadable product + * + * @magentoConfigFixture current_store catalog/downloadable/links_title Links Title Test + * @magentoAppIsolation enabled + * @dataProvider productLinksTitleDataProvider + * + * @param string $productType + * @param string $linksTitle + * @param string $expectedResult + */ + public function testGetLinksTitle($productType, $linksTitle, $expectedResult) + { + Mage::register('product', new Varien_Object(array( + 'type_id' => $productType, + 'id' => '1', + 'links_title' => $linksTitle + ))); + $block = Mage::app()->getLayout() + ->createBlock('Mage_Downloadable_Block_Adminhtml_Catalog_Product_Edit_Tab_Downloadable_Links'); + $this->assertEquals($expectedResult, $block->getLinksTitle()); + } + + /** + * Data Provider with product types + * + * @return array + */ + public function productLinksTitleDataProvider() + { + return array ( + array('simple', null, 'Links Title Test'), + array('simple', 'Links Title', 'Links Title Test'), + array('virtual', null, 'Links Title Test'), + array('virtual', 'Links Title', 'Links Title Test'), + array('downloadable', null, null), + array('downloadable', 'Links Title', 'Links Title') + ); + } } diff --git a/dev/tests/integration/testsuite/Mage/Downloadable/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable/SamplesTest.php b/dev/tests/integration/testsuite/Mage/Downloadable/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable/SamplesTest.php index 6442ee2430004ff6bc90957a5046216333590281..da71100d9d44f4a411af2156c67e3e282035562b 100644 --- a/dev/tests/integration/testsuite/Mage/Downloadable/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable/SamplesTest.php +++ b/dev/tests/integration/testsuite/Mage/Downloadable/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable/SamplesTest.php @@ -36,4 +36,55 @@ class Mage_Downloadable_Block_Adminhtml_Catalog_Product_Edit_Tab_Downloadable_Sa Mage_Downloadable_Block_Adminhtml_Catalog_Product_Edit_Tab_Downloadable_LinksTest ::performUploadButtonTest($block); } + + /** + * @magentoAppIsolation enabled + */ + public function testGetSampleData() + { + Mage::register('current_product', new Varien_Object(array('type_id' => 'simple'))); + $block = Mage::app()->getLayout() + ->createBlock('Mage_Downloadable_Block_Adminhtml_Catalog_Product_Edit_Tab_Downloadable_Samples'); + $this->assertEmpty($block->getSampleData()); + } + + /** + * Get Samples Title for simple/virtual/downloadable product + * + * @magentoConfigFixture current_store catalog/downloadable/samples_title Samples Title Test + * @magentoAppIsolation enabled + * @dataProvider productSamplesTitleDataProvider + * + * @param string $productType + * @param string $samplesTitle + * @param string $expectedResult + */ + public function testGetSamplesTitle($productType, $samplesTitle, $expectedResult) + { + Mage::register('current_product', new Varien_Object(array( + 'type_id' => $productType, + 'id' => '1', + 'samples_title' => $samplesTitle + ))); + $block = Mage::app()->getLayout() + ->createBlock('Mage_Downloadable_Block_Adminhtml_Catalog_Product_Edit_Tab_Downloadable_Samples'); + $this->assertEquals($expectedResult, $block->getSamplesTitle()); + } + + /** + * Data Provider with product types + * + * @return array + */ + public function productSamplesTitleDataProvider() + { + return array ( + array('simple', null, 'Samples Title Test'), + array('simple', 'Samples Title', 'Samples Title Test'), + array('virtual', null, 'Samples Title Test'), + array('virtual', 'Samples Title', 'Samples Title Test'), + array('downloadable', null, null), + array('downloadable', 'Samples Title', 'Samples Title') + ); + } } diff --git a/dev/tests/integration/testsuite/Mage/Downloadable/Model/Product/TypeTest.php b/dev/tests/integration/testsuite/Mage/Downloadable/Model/Product/TypeTest.php new file mode 100644 index 0000000000000000000000000000000000000000..69228ebd2ef27b1c863cc0725000add169894817 --- /dev/null +++ b/dev/tests/integration/testsuite/Mage/Downloadable/Model/Product/TypeTest.php @@ -0,0 +1,75 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @category Magento + * @package Magento_Downloadable + * @subpackage integration_tests + * @copyright Copyright (c) 2012 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +/** + * Test class for Mage_Downloadable_Model_Product_Type + */ +class Mage_Downloadable_Model_Product_TypeTest extends PHPUnit_Framework_TestCase +{ + /** + * @var Mage_Downloadable_Model_Product_Type + */ + protected $_model; + + protected function setUp() + { + $this->_model = new Mage_Downloadable_Model_Product_Type(); + } + + /** + * @magentoDataFixture Mage/Downloadable/_files/product_with_files.php + */ + public function testDeleteTypeSpecificData() + { + $product = Mage::getModel('Mage_Catalog_Model_Product'); + $product->load(1); + Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID); + $product->setOrigData(); + $downloadableData = array(); + + $links = $this->_model->getLinks($product); + $this->assertNotEmpty($links); + $samples = $this->_model->getSamples($product); + $this->assertNotEmpty($samples->getData()); + foreach ($links as $link) { + $downloadableData['link'][] = $link->getData(); + } + foreach ($samples as $sample) { + $downloadableData['sample'][] = $sample->getData(); + } + + $product->setDownloadableData($downloadableData); + $this->_model->deleteTypeSpecificData($product); + $product = Mage::getModel('Mage_Catalog_Model_Product'); + $product->load(1); + + $links = $this->_model->getLinks($product); + $this->assertEmpty($links); + $samples = $this->_model->getSamples($product); + $this->assertEmpty($samples->getData()); + } +} diff --git a/dev/tests/integration/testsuite/Mage/GoogleShopping/controllers/Adminhtml/GoogleShopping/ItemsControllerTest.php b/dev/tests/integration/testsuite/Mage/GoogleShopping/controllers/Adminhtml/GoogleShopping/ItemsControllerTest.php new file mode 100644 index 0000000000000000000000000000000000000000..9c2b16ee419c776e4d031c4933bca014a2ad657e --- /dev/null +++ b/dev/tests/integration/testsuite/Mage/GoogleShopping/controllers/Adminhtml/GoogleShopping/ItemsControllerTest.php @@ -0,0 +1,36 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @category Magento + * @package Mage_GoogleShopping + * @subpackage integration_tests + * @copyright Copyright (c) 2012 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ +class Mage_GoogleShopping_Adminhtml_GoogleShopping_ItemsControllerTest extends Mage_Adminhtml_Utility_Controller +{ + public function testIndexAction() + { + $this->dispatch('backend/admin/googleshopping_items/index/store/1/'); + $body = $this->getResponse()->getBody(); + $this->assertSelectCount('div#items', 1, $body); + $this->assertSelectCount('div#googleshopping_selection_search_grid_', 1, $body); + } +} \ No newline at end of file diff --git a/dev/tests/integration/testsuite/Mage/Review/_files/review_xss.php b/dev/tests/integration/testsuite/Mage/Review/_files/review_xss.php new file mode 100644 index 0000000000000000000000000000000000000000..d3f76ff2bac29521730f47b795c55846a39057ff --- /dev/null +++ b/dev/tests/integration/testsuite/Mage/Review/_files/review_xss.php @@ -0,0 +1,39 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @category Mage + * @package Mage_Review + * @subpackage integration_tests + * @copyright Copyright (c) 2012 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +require __DIR__ . '/../../Catalog/_files/product_simple_xss.php'; + +$review = Mage::getModel('Mage_Review_Model_Review'); +$review->setEntityId($review->getEntityIdByCode(Mage_Review_Model_Review::ENTITY_PRODUCT_CODE)) + ->setEntityPkValue(1) // the last product from the fixture file included above + ->setStatusId(Mage_Review_Model_Review::STATUS_PENDING) + ->setStoreId(Mage::app()->getStore()->getId()) + ->setStores(array(Mage::app()->getStore()->getId())) + ->setNickname('Nickname') + ->setTitle('Review Summary') + ->setDetail('Review text') + ->save(); diff --git a/dev/tests/integration/testsuite/Mage/Wishlist/controllers/IndexControllerTest.php b/dev/tests/integration/testsuite/Mage/Wishlist/controllers/IndexControllerTest.php index 2a5cbf9b847ad256ac6308f950b53549e4893ec2..89e2602b1c85ad77b8434cb69c70476065f66904 100644 --- a/dev/tests/integration/testsuite/Mage/Wishlist/controllers/IndexControllerTest.php +++ b/dev/tests/integration/testsuite/Mage/Wishlist/controllers/IndexControllerTest.php @@ -27,6 +27,25 @@ class Mage_Wishlist_IndexControllerTest extends Magento_Test_TestCase_ControllerAbstract { + /** + * @var Mage_Customer_Model_Session + */ + protected $_customerSession; + + protected function setUp() + { + parent::setUp(); + $this->_customerSession = Mage::getModel('Mage_Customer_Model_Session'); + $this->_customerSession->login('customer@example.com', 'password'); + } + + protected function tearDown() + { + $this->_customerSession->logout(); + $this->_customerSession = null; + parent::tearDown(); + } + /** * Verify wishlist view action * @@ -44,8 +63,6 @@ class Mage_Wishlist_IndexControllerTest extends Magento_Test_TestCase_Controller */ public function testItemColumnBlock() { - $session = Mage::getModel('Mage_Customer_Model_Session'); - $session->login('customer@example.com', 'password'); $this->dispatch('wishlist/index/index'); $body = $this->getResponse()->getBody(); $this->assertStringMatchesFormat('%A<img src="%Asmall_image.jpg" %A alt="Simple Product"%A/>%A', $body); @@ -54,4 +71,22 @@ class Mage_Wishlist_IndexControllerTest extends Magento_Test_TestCase_Controller $this->assertStringMatchesFormat('%A<textarea name="description[%d]"%A', $body); $this->assertStringMatchesFormat('%A<button%Aonclick="addAllWItemsToCart()"%A', $body); } + + /** + * @magentoDataFixture Mage/Catalog/_files/product_simple_xss.php + * @magentoDataFixture Mage/Customer/_files/customer.php + */ + public function testAddActionProductNameXss() + { + $this->dispatch('wishlist/index/add/product/1?nocookie=1'); + $messages = $this->_customerSession->getMessages()->getItems(); + $isProductNamePresent = false; + foreach ($messages as $message) { + if (strpos($message->getCode(), '<script>alert("xss");</script>') !== false) { + $isProductNamePresent = true; + } + $this->assertNotContains('<script>alert("xss");</script>', $message->getCode()); + } + $this->assertTrue($isProductNamePresent, 'Product name was not found in session messages'); + } } diff --git a/dev/tests/static/framework/CodingStandard/Tool/CodeSniffer.php b/dev/tests/static/framework/CodingStandard/Tool/CodeSniffer.php new file mode 100644 index 0000000000000000000000000000000000000000..88e22c6e23bfbb5f3f805e11b7dc68114488bea3 --- /dev/null +++ b/dev/tests/static/framework/CodingStandard/Tool/CodeSniffer.php @@ -0,0 +1,114 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @category Magento + * @package Magento + * @subpackage static_tests + * @copyright Copyright (c) 2012 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +/** + * PHP Code Sniffer tool wrapper + */ +class CodingStandard_Tool_CodeSniffer implements CodingStandard_ToolInterface +{ + /** + * Ruleset directory + * + * @var string + */ + protected $_rulesetDir; + + /** + * Report file + * + * @var string + */ + protected $_reportFile; + + /** + * PHPCS cli tool wrapper + * + * @var CodingStandard_Tool_CodeSniffer_Wrapper + */ + protected $_wrapper; + + /** + * Constructor + * + * @param string $rulesetDir Directory that locates the inspection rules + * @param string $reportFile Destination file to write inspection report to + */ + public function __construct($rulesetDir, $reportFile, CodingStandard_Tool_CodeSniffer_Wrapper $wrapper) + { + $this->_reportFile = $reportFile; + $this->_rulesetDir = $rulesetDir; + $this->_wrapper = $wrapper; + } + + /** + * Whether the tool can be ran on the current environment + * + * @return bool + */ + public function canRun() + { + return class_exists('PHP_CodeSniffer_CLI'); + } + + /** + * Run tool for files cpecified + * + * @param array $whiteList Files/directories to be inspected + * @param array $blackList Files/directories to be excluded from the inspection + * @param array $extensions Array of alphanumeric strings, for example: 'php', 'xml', 'phtml', 'css'... + * + * @return int + */ + public function run(array $whiteList, array $blackList = array(), array $extensions = array()) + { + $whiteList = array_map(function($item) { + return str_replace('/', DIRECTORY_SEPARATOR, $item); + }, $whiteList); + + $blackList = array_map(function($item) { + return preg_quote(str_replace('/', DIRECTORY_SEPARATOR, $item)); + }, $blackList); + + + $this->_wrapper->checkRequirements(); + $settings = $this->_wrapper->getDefaults(); + $settings['files'] = $whiteList; + $settings['standard'] = $this->_rulesetDir; + $settings['ignored'] = $blackList; + $settings['extensions'] = $extensions; + $settings['reportFile'] = $this->_reportFile; + $settings['warningSeverity'] = 0; + $settings['reports']['checkstyle'] = null; + $this->_wrapper->setValues($settings); + + ob_start(); + $result = $this->_wrapper->process(); + ob_end_clean(); + return $result; + } + +} diff --git a/dev/tests/static/framework/CodingStandard/Tool/CodeSniffer/Wrapper.php b/dev/tests/static/framework/CodingStandard/Tool/CodeSniffer/Wrapper.php new file mode 100644 index 0000000000000000000000000000000000000000..aee209c004a4759b5c7a3cca1020967376162a9e --- /dev/null +++ b/dev/tests/static/framework/CodingStandard/Tool/CodeSniffer/Wrapper.php @@ -0,0 +1,44 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @category Magento + * @package Magento + * @subpackage static_tests + * @copyright Copyright (c) 2012 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +/** + * PHP Code Sniffer Cli wrapper + */ +class CodingStandard_Tool_CodeSniffer_Wrapper extends PHP_CodeSniffer_CLI +{ + /** + * Emulate console arguments + * + * @param $values + * @return Inspection_CodeSniffer_Cli_Wrapper + */ + public function setValues($values) + { + $this->values = $values; + return $this; + } +} diff --git a/dev/tests/static/framework/CodingStandard/ToolInterface.php b/dev/tests/static/framework/CodingStandard/ToolInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..6a4122054084f430f5c112fe7ccef0548e52a86f --- /dev/null +++ b/dev/tests/static/framework/CodingStandard/ToolInterface.php @@ -0,0 +1,50 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @category Magento + * @package Magento + * @subpackage static_tests + * @copyright Copyright (c) 2012 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +/** + * Code standard tool wrapper interface + */ +interface CodingStandard_ToolInterface +{ + /** + * Whether the tool can be ran on the current environment + * + * @return bool + */ + public function canRun(); + + /** + * Run tool for files cpecified + * + * @param array $whiteList Files/directories to be inspected + * @param array $blackList Files/directories to be excluded from the inspection + * @param array $extensions Array of alphanumeric strings, for example: 'php', 'xml', 'phtml', 'css'... + * + * @return int + */ + public function run(array $whiteList, array $blackList = array(), array $extensions = array()); +} diff --git a/dev/tests/static/framework/Inspection/CodeSniffer/Command.php b/dev/tests/static/framework/Inspection/CodeSniffer/Command.php deleted file mode 100644 index 1d17e571a3c6edcbc820dfe50f9cd047ccc4dc75..0000000000000000000000000000000000000000 --- a/dev/tests/static/framework/Inspection/CodeSniffer/Command.php +++ /dev/null @@ -1,107 +0,0 @@ -<?php -/** - * Magento - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://opensource.org/licenses/osl-3.0.php - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@magentocommerce.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade Magento to newer - * versions in the future. If you wish to customize Magento for your - * needs please refer to http://www.magentocommerce.com for more information. - * - * @category Magento - * @package Magento - * @subpackage static_tests - * @copyright Copyright (c) 2012 X.commerce, Inc. (http://www.magentocommerce.com) - * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) - */ - -/** - * PHP Code Sniffer shell command - */ -class Inspection_CodeSniffer_Command extends Inspection_CommandAbstract -{ - /** - * @var string - */ - protected $_rulesetDir; - - /** - * @var array - */ - protected $_extensions = array(); - - /** - * Constructor - * - * @param string $rulesetDir Directory that locates the inspection rules - * @param string $reportFile Destination file to write inspection report to - */ - public function __construct($rulesetDir, $reportFile) - { - parent::__construct($reportFile); - $this->_rulesetDir = $rulesetDir; - } - - /** - * Limit scanning folders by file extensions - * - * Array of alphanumeric strings, for example: 'php', 'xml', 'phtml', 'css'... - * - * @param array $extensions - * @return Inspection_CodeSniffer_Command - */ - public function setExtensions(array $extensions) - { - $this->_extensions = $extensions; - return $this; - } - - /** - * @return string - */ - public function _buildVersionShellCmd() - { - return 'phpcs --version'; - } - - /** - * @param array $whiteList - * @param array $blackList - * @return string - */ - protected function _buildShellCmd($whiteList, $blackList) - { - $whiteList = array_map('escapeshellarg', $whiteList); - $whiteList = implode(' ', $whiteList); - - /* Note: phpcs allows regular expressions for the ignore list */ - $blackListStr = ''; - if ($blackList) { - foreach ($blackList as $fileOrDir) { - $fileOrDir = str_replace('/', DIRECTORY_SEPARATOR, $fileOrDir); - $blackListStr .= ($blackListStr ? ',' : '') . preg_quote($fileOrDir); - } - $blackListStr = '--ignore=' . escapeshellarg($blackListStr); - } - - return 'phpcs' - . ($blackListStr ? ' ' . $blackListStr : '') - . ' --standard=' . escapeshellarg($this->_rulesetDir) - . ' --report=checkstyle' - . ($this->_extensions ? ' --extensions=' . implode(',', $this->_extensions) : '') - . ' --report-file=' . escapeshellarg($this->_reportFile) - . ' -n' - . ' ' . $whiteList - ; - } -} diff --git a/dev/tests/static/framework/tests/unit/testsuite/CodingStandard/Tool/CodeSniffer/WrapperTest.php b/dev/tests/static/framework/tests/unit/testsuite/CodingStandard/Tool/CodeSniffer/WrapperTest.php new file mode 100644 index 0000000000000000000000000000000000000000..0498f55ecf81381833ccdb3cba6fee94a4e449d8 --- /dev/null +++ b/dev/tests/static/framework/tests/unit/testsuite/CodingStandard/Tool/CodeSniffer/WrapperTest.php @@ -0,0 +1,37 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @category Magento + * @package Magento + * @subpackage static_tests + * @copyright Copyright (c) 2012 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +class CodingStandard_Tool_CodeSniffer_WrapperTest extends PHPUnit_Framework_TestCase +{ + public function testSetValues() + { + $wrapper = new CodingStandard_Tool_CodeSniffer_Wrapper(); + $expected = array('some_key' => 'some_value'); + $wrapper->setValues($expected); + $this->assertEquals($expected, $wrapper->getCommandLineValues()); + } +} diff --git a/dev/tests/static/framework/tests/unit/testsuite/CodingStandard/Tool/CodeSnifferTest.php b/dev/tests/static/framework/tests/unit/testsuite/CodingStandard/Tool/CodeSnifferTest.php new file mode 100644 index 0000000000000000000000000000000000000000..09c2334e80c530388b46701679b44f26c07e5cfd --- /dev/null +++ b/dev/tests/static/framework/tests/unit/testsuite/CodingStandard/Tool/CodeSnifferTest.php @@ -0,0 +1,85 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @category Magento + * @package Magento + * @subpackage static_tests + * @copyright Copyright (c) 2012 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +class CodingStandard_Tool_CodeSnifferTest extends PHPUnit_Framework_TestCase +{ + /** + * @var CodingStandard_Tool_CodeSniffer + */ + protected $_tool; + + /** + * @var PHP_CodeSniffer_CLI + */ + protected $_wrapper; + + /** + * Rule set directory + */ + const RULE_SET = 'some/ruleset/directory'; + + /** + * Report file + */ + const REPORT_FILE = 'some/report/file.xml'; + + protected function setUp() + { + $this->_wrapper = $this->getMock('CodingStandard_Tool_CodeSniffer_Wrapper'); + $this->_tool = new CodingStandard_Tool_CodeSniffer(self::RULE_SET, self::REPORT_FILE, $this->_wrapper); + } + + public function testRun() + { + $whiteList = array('test' . rand(), 'test' . rand()); + $blackList = array('test' . rand(), 'test' . rand()); + $extensions = array('test' . rand(), 'test' . rand()); + + $this->_wrapper->expects($this->once()) + ->method('getDefaults') + ->will($this->returnValue(array())); + + $expectedCliEmulation = array( + 'files' => $whiteList, + 'standard' => self::RULE_SET, + 'ignored' => $blackList, + 'extensions' => $extensions, + 'reportFile' => self::REPORT_FILE, + 'warningSeverity' => 0, + 'reports' => array('checkstyle' => null) + ); + + $this->_wrapper->expects($this->once()) + ->method('setValues') + ->with($this->equalTo($expectedCliEmulation)); + + $this->_wrapper->expects($this->once()) + ->method('process'); + + $this->_tool->run($whiteList, $blackList, $extensions); + } +} diff --git a/dev/tests/static/framework/tests/unit/testsuite/Inspection/CodeSniffer/CommandTest.php b/dev/tests/static/framework/tests/unit/testsuite/Inspection/CodeSniffer/CommandTest.php deleted file mode 100644 index a47122f339f1a30fcf365013f378b1d95b78cc02..0000000000000000000000000000000000000000 --- a/dev/tests/static/framework/tests/unit/testsuite/Inspection/CodeSniffer/CommandTest.php +++ /dev/null @@ -1,121 +0,0 @@ -<?php -/** - * Magento - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://opensource.org/licenses/osl-3.0.php - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@magentocommerce.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade Magento to newer - * versions in the future. If you wish to customize Magento for your - * needs please refer to http://www.magentocommerce.com for more information. - * - * @category Magento - * @package Magento - * @subpackage static_tests - * @copyright Copyright (c) 2012 X.commerce, Inc. (http://www.magentocommerce.com) - * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) - */ - -class Inspection_CodeSniffer_CommandTest extends PHPUnit_Framework_TestCase -{ - /** - * @var Inspection_CodeSniffer_Command|PHPUnit_Framework_MockObject_MockObject - */ - protected $_cmd; - - protected function setUp() - { - $this->_cmd = $this->getMock( - 'Inspection_CodeSniffer_Command', - array('_execShellCmd'), - array('some/ruleset/dir', 'some/report/file.xml') - ); - } - - /** - * @dataProvider canRunDataProvider - */ - public function testCanRun($cmdOutput, $expectedResult) - { - $this->_cmd - ->expects($this->once()) - ->method('_execShellCmd') - ->with($this->stringContains('phpcs')) - ->will($this->returnValue($cmdOutput)) - ; - $this->assertEquals($expectedResult, $this->_cmd->canRun()); - } - - public function canRunDataProvider() - { - return array( - 'success' => array('PHP_CodeSniffer version X.Y.Z', true), - 'failure' => array(false, false), - ); - } - - /** - * @dataProvider getVersionDataProvider - */ - public function testGetVersion($versionCmdOutput, $expectedVersion) - { - $this->_cmd - ->expects($this->once()) - ->method('_execShellCmd') - ->with($this->stringContains('phpcs')) - ->will($this->returnValue($versionCmdOutput)) - ; - $this->assertEquals($expectedVersion, $this->_cmd->getVersion()); - } - - public function getVersionDataProvider() - { - return array( - array('PHP_CodeSniffer version 1.3.0RC2 (beta) by Squiz Pty Ltd. (http://www.squiz.net)', '1.3.0RC2'), - array('PHP_CodeSniffer version 1.3.0 (stable) by Squiz Pty Ltd. (http://www.squiz.net)', '1.3.0'), - ); - } - - public function testRun() - { - $expectedQuoteChar = substr(escapeshellarg(' '), 0, 1); - $expectedCmd = 'phpcs' - . ' --standard="some/ruleset/dir"' - . ' --report=checkstyle' - . ' --report-file="some/report/file.xml"' - . ' -n' - . ' "some/test/dir with space"' - . ' "some/test/file with space.php"' - ; - $expectedCmd = str_replace('"', $expectedQuoteChar, $expectedCmd); - $this->_cmd - ->expects($this->once()) - ->method('_execShellCmd') - ->with($expectedCmd) - ; - $this->_cmd->run(array('some/test/dir with space', 'some/test/file with space.php')); - } - - /** - * @depends testRun - */ - public function testRunWithExtensions() - { - $this->assertSame($this->_cmd, $this->_cmd->setExtensions(array('txt', 'xml'))); - $this->_cmd - ->expects($this->once()) - ->method('_execShellCmd') - ->with($this->stringContains(' --extensions=txt,xml ')) - ; - $this->_cmd->run(array()); - } -} diff --git a/dev/tests/static/testsuite/Legacy/_files/obsolete_classes.php b/dev/tests/static/testsuite/Legacy/_files/obsolete_classes.php index 16a02821ee026e1a7d6cb3d18c1dbd88a43ee7e1..41c1166c5b2b6f9f5be6a3c6ae3945d014efa544 100644 --- a/dev/tests/static/testsuite/Legacy/_files/obsolete_classes.php +++ b/dev/tests/static/testsuite/Legacy/_files/obsolete_classes.php @@ -58,6 +58,7 @@ return array( $this->_getClassRule('Mage_Adminhtml_Block_Api_Edituser'), $this->_getClassRule('Mage_Adminhtml_Block_Api_Tab_Userroles'), $this->_getClassRule('Mage_Adminhtml_Block_Catalog'), + $this->_getClassRule('Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Super_Config_Grid'), $this->_getClassRule('Mage_Adminhtml_Block_Page_Menu', 'Mage_Backend_Block_Menu'), $this->_getClassRule('Mage_Adminhtml_Block_Permissions_User'), $this->_getClassRule('Mage_Adminhtml_Block_Permissions_User_Grid'), diff --git a/dev/tests/static/testsuite/Legacy/_files/obsolete_methods.php b/dev/tests/static/testsuite/Legacy/_files/obsolete_methods.php index d494ecfc05a9c8a4b0ffd3570ac604ab688ff6e8..70cc13636affdc0a2ab4eeed46e1d57ff0a0ec42 100644 --- a/dev/tests/static/testsuite/Legacy/_files/obsolete_methods.php +++ b/dev/tests/static/testsuite/Legacy/_files/obsolete_methods.php @@ -24,6 +24,8 @@ * @copyright Copyright (c) 2012 X.commerce, Inc. (http://www.magentocommerce.com) * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ + +/** @var $this Legacy_ObsoleteCodeTest */ return array( $this->_getRule('__get', 'Varien_Object'), $this->_getRule('__set', 'Varien_Object'), @@ -167,6 +169,7 @@ return array( $this->_getRule('drawItem', 'Mage_Catalog_Block_Navigation'), $this->_getRule('dropKey', 'Varien_Db_Adapter_Pdo_Mysql'), $this->_getRule('editAction', 'Mage_Tag_CustomerController'), + $this->_getRule('escapeJs', 'Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Super_Config'), $this->_getRule('exportOrderedCsvAction'), $this->_getRule('exportOrderedExcelAction'), $this->_getRule('fetchItemsCount', 'Mage_Wishlist_Model_Resource_Wishlist'), @@ -186,6 +189,7 @@ return array( $this->_getRule('getAllOrderEntityIds', 'Mage_Rss_Model_Resource_Order'), $this->_getRule('getAllOrderEntityTypeIds', 'Mage_Rss_Model_Resource_Order'), $this->_getRule('getAnonSuffix'), + $this->_getRule('getAttributesJson', 'Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Super_Config', 'getAttributes'), $this->_getRule('getBaseTaxAmount', 'Mage_Sales_Model_Quote_Item_Abstract'), $this->_getRule('getCheckoutMehod', 'Mage_Checkout_Model_Type_Onepage'), $this->_getRule('getChild', null, 'Mage_Core_Block_Abstract::getChildBlock()', 'app'), diff --git a/dev/tests/static/testsuite/Php/LiveCodeTest.php b/dev/tests/static/testsuite/Php/LiveCodeTest.php index aa0c2d7550be0bc82dd8a7972df6a46e372dc3d2..a3110889faf0908c9cc1802206b4355362b9cb16 100644 --- a/dev/tests/static/testsuite/Php/LiveCodeTest.php +++ b/dev/tests/static/testsuite/Php/LiveCodeTest.php @@ -57,12 +57,15 @@ class Php_LiveCodeTest extends PHPUnit_Framework_TestCase public function testCodeStyle() { $reportFile = self::$_reportDir . '/phpcs_report.xml'; - $cmd = new Inspection_CodeSniffer_Command(realpath(__DIR__ . '/_files/phpcs'), $reportFile); - if (!$cmd->canRun()) { - $this->markTestSkipped('PHP Code Sniffer command is not available.'); + $wrapper = new CodingStandard_Tool_CodeSniffer_Wrapper(); + $codeSniffer = new CodingStandard_Tool_CodeSniffer(realpath(__DIR__ . '/_files/phpcs'), $reportFile, $wrapper); + if (!$codeSniffer->canRun()) { + $this->markTestSkipped('PHP Code Sniffer is not installed.'); } - $cmd->setExtensions(array('php', 'phtml')); - $this->assertTrue($cmd->run(self::$_whiteList, self::$_blackList), $cmd->getLastRunMessage()); + $result = $codeSniffer->run(self::$_whiteList, self::$_blackList, array('php', 'phtml')); + $this->assertEquals(0, $result, + "PHP Code Sniffer has found $result error(s): See detailed report in $reportFile" + ); } public function testCodeMess() diff --git a/dev/tests/static/testsuite/Php/_files/whitelist/common.txt b/dev/tests/static/testsuite/Php/_files/whitelist/common.txt index a4cd10262c1e4de9b48c1b614943da67ec7bde37..86c7ffcd8091ed9b21435ac6a898eb96abf70aff 100644 --- a/dev/tests/static/testsuite/Php/_files/whitelist/common.txt +++ b/dev/tests/static/testsuite/Php/_files/whitelist/common.txt @@ -3,18 +3,20 @@ # app/bootstrap.php app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/Tab/Options/Popup/Grid.php +app/code/core/Mage/Adminhtml/Block/Catalog/Product/Helper/Form/Weight/Renderer.php app/code/core/Mage/Adminhtml/Block/Catalog/Product/Options/Ajax.php app/code/core/Mage/Adminhtml/Block/Cms/Page/Edit/Tab/Design.php app/code/core/Mage/Adminhtml/Block/Customer/Edit/Tab/Account.php app/code/core/Mage/Adminhtml/Model/Observer.php -app/code/core/Mage/Adminhtml/controllers/UrlrewriteController.php app/code/core/Mage/Adminhtml/Block/Urlrewrite app/code/core/Mage/Adminhtml/Block/Page/System/Config/Robots/Reset.php +app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/NewCategory.php app/code/core/Mage/Adminhtml/Block/Catalog/Product/Helper/Form/Category.php app/code/core/Mage/Adminhtml/Block/System/Store/Edit app/code/core/Mage/Adminhtml/Block/System/Store/Edit.php app/code/core/Mage/Adminhtml/controllers/Report/CustomerController.php app/code/core/Mage/Adminhtml/controllers/Report/ProductController.php +app/code/core/Mage/Adminhtml/controllers/UrlrewriteController.php app/code/core/Mage/Backend/Model/Acl/Config.php app/code/core/Mage/Backend/Block/System/Config/Form/Field/Regexceptions.php app/code/core/Mage/Backend/Block/Widget/Grid/ColumnSet.php @@ -25,6 +27,8 @@ app/code/core/Mage/Backend/Block/System/Config/Form/Field.php app/code/core/Mage/Backend/controllers/Adminhtml/System/ConfigController.php app/code/core/Mage/Backend/controllers/Adminhtml/SystemController.php app/code/core/Mage/Backend/Model/Widget/Grid +app/code/core/Mage/Catalog/Block/Product/Configurable +app/code/core/Mage/Catalog/Model/Resource/Product/Collection app/code/core/Mage/CatalogInventory/Block/Adminhtml/Form/Field/Stock.php app/code/core/Mage/Core/Block/Abstract.php app/code/core/Mage/Core/data diff --git a/dev/tests/unit/testsuite/Mage/Adminhtml/Block/Catalog/Product/Edit/NewCategoryTest.php b/dev/tests/unit/testsuite/Mage/Adminhtml/Block/Catalog/Product/Edit/NewCategoryTest.php new file mode 100644 index 0000000000000000000000000000000000000000..30a3bdd70b5955f75df9010e3fe9f89d770035f6 --- /dev/null +++ b/dev/tests/unit/testsuite/Mage/Adminhtml/Block/Catalog/Product/Edit/NewCategoryTest.php @@ -0,0 +1,79 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @category Magento + * @package Mage_Adminhtml + * @subpackage unit_tests + * @copyright Copyright (c) 2012 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +class Mage_Adminhtml_Block_Catalog_Product_Edit_NewCategoryTest extends PHPUnit_Framework_TestCase +{ + /** @var Mage_Adminhtml_Block_Catalog_Product_Edit_NewCategory */ + protected $_object; + + /** @var Mage_Core_Model_Url|PHPUnit_Framework_MockObject_MockObject */ + protected $_urlModel; + + protected function setUp() + { + $objectManager = new Magento_Test_Helper_ObjectManager($this); + + $this->_urlModel = $this->getMock('Mage_Backend_Model_Url', array('getUrl'), array(), '', false); + $this->_object = $objectManager->getBlock('Mage_Adminhtml_Block_Catalog_Product_Edit_NewCategory', array( + 'urlBuilder' => $this->_urlModel, + )); + } + + /** + * @covers Mage_Adminhtml_Block_Catalog_Product_Edit_NewCategory::getSaveCategoryUrl + * @covers Mage_Adminhtml_Block_Catalog_Product_Edit_NewCategory::getSuggestCategoryUrl + * @dataProvider urlMethodsDataProvider + * @param string $expectedUrl + * @param string $executedMethod + */ + public function testGetUrlMethods($expectedUrl, $executedMethod) + { + $this->_urlModel->expects($this->once()) + ->method('getUrl') + ->with($expectedUrl) + ->will($this->returnCallback( + function ($string) { + return strrev($string); + } + )); + $this->assertEquals( + strrev($expectedUrl), + call_user_func_array(array($this->_object, $executedMethod), array($expectedUrl)) + ); + } + + /** + * @return array + */ + public static function urlMethodsDataProvider() + { + return array( + array('*/catalog_category/save', 'getSaveCategoryUrl'), + array('*/catalog_category/suggestCategories', 'getSuggestCategoryUrl'), + ); + } +} diff --git a/dev/tests/unit/testsuite/Mage/Adminhtml/Block/Catalog/Product/Helper/Form/Weight/RendererTest.php b/dev/tests/unit/testsuite/Mage/Adminhtml/Block/Catalog/Product/Helper/Form/Weight/RendererTest.php new file mode 100644 index 0000000000000000000000000000000000000000..e4d740d5bc4bc1d3495c914a68b114098974ace0 --- /dev/null +++ b/dev/tests/unit/testsuite/Mage/Adminhtml/Block/Catalog/Product/Helper/Form/Weight/RendererTest.php @@ -0,0 +1,70 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @category Magento + * @package Mage_Catalog + * @subpackage unit_tests + * @copyright Copyright (c) 2012 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +class Mage_Adminhtml_Block_Catalog_Product_Helper_Form_Weight_RendererTest extends PHPUnit_Framework_TestCase +{ + const VIRTUAL_FIELD_HTML_ID = 'weight_and_type_switcher'; + + /** + * @var Mage_Adminhtml_Block_Catalog_Product_Helper_Form_Weight_Renderer + */ + protected $_model; + + /** + * @var Varien_Data_Form_Element_Checkbox + */ + protected $_virtual; + + public function testSetForm() + { + $this->_virtual = new Varien_Object(); + + $helper = $this->getMock('Mage_Catalog_Helper_Product', array('getTypeSwitcherControlLabel')); + $helper->expects($this->any())->method('getTypeSwitcherControlLabel') + ->will($this->returnValue('Virtual / Downloadable')); + + $this->assertNull($this->_virtual->getId()); + $this->assertNull($this->_virtual->getName()); + $this->assertNull($this->_virtual->getLabel()); + $this->assertNull($this->_virtual->getForm()); + + $this->_model = new Mage_Adminhtml_Block_Catalog_Product_Helper_Form_Weight_Renderer( + array('element' => $this->_virtual, 'helper' => $helper) + ); + + $form = new Varien_Data_Form(); + $this->_model->setForm($form); + + $this->assertEquals( + Mage_Adminhtml_Block_Catalog_Product_Helper_Form_Weight_Renderer::VIRTUAL_FIELD_HTML_ID, + $this->_virtual->getId() + ); + $this->assertEquals('is_virtual', $this->_virtual->getName()); + $this->assertEquals('Virtual / Downloadable', $this->_virtual->getLabel()); + $this->assertSame($form, $this->_virtual->getForm()); + } +} diff --git a/dev/tests/unit/testsuite/Mage/Adminhtml/controllers/Catalog/ProductControllerTest.php b/dev/tests/unit/testsuite/Mage/Adminhtml/controllers/Catalog/ProductControllerTest.php deleted file mode 100644 index 95355d194f59ca5c86bbe481828e36806d7eff83..0000000000000000000000000000000000000000 --- a/dev/tests/unit/testsuite/Mage/Adminhtml/controllers/Catalog/ProductControllerTest.php +++ /dev/null @@ -1,176 +0,0 @@ -<?php -/** - * Magento - * - * NOTICE OF LICENSE - * - * This source file is subject to the Open Software License (OSL 3.0) - * that is bundled with this package in the file LICENSE.txt. - * It is also available through the world-wide-web at this URL: - * http://opensource.org/licenses/osl-3.0.php - * If you did not receive a copy of the license and are unable to - * obtain it through the world-wide-web, please send an email - * to license@magentocommerce.com so we can send you a copy immediately. - * - * DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade Magento to newer - * versions in the future. If you wish to customize Magento for your - * needs please refer to http://www.magentocommerce.com for more information. - * - * @category Mage - * @package Mage_Adminhtml - * @subpackage unit_tests - * @copyright Copyright (c) 2012 X.commerce, Inc. (http://www.magentocommerce.com) - * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) - */ -/** - * - * Test class for Mage_Adminhtml_Catalog_ProductController - * - * @category Mage - * @package Mage_Adminhtml - * @author Magento Core Team <core@magentocommerce.com> - */ -require_once __DIR__ . '/../../../../../../../../' - . 'app/code/core/Mage/Adminhtml/controllers/Catalog/ProductController.php'; -class Mage_Adminhtml_Catalog_ProductControllerTest extends PHPUnit_Framework_TestCase -{ - /** - * @var PHPUnit_Framework_MockObject_MockObject|Mage_Adminhtml_Catalog_ProductController - */ - protected $_controller; - - /** - * @var PHPUnit_Framework_MockObject_MockObject|Zend_Controller_Request_Abstract - */ - protected $_request; - - /** - * @var PHPUnit_Framework_MockObject_MockObject|Mage_Backend_Model_Session - */ - protected $_sessionMock; - - /** - * @var PHPUnit_Framework_MockObject_MockObject|Magento_ObjectManager - */ - protected $_objectManager; - - /** - * @var Zend_Controller_Response_Abstract|PHPUnit_Framework_MockObject_MockObject - */ - protected $_response; - - protected function setUp() - { - $this->_request = $this->getMockBuilder('Mage_Core_Controller_Request_Http') - ->setMethods(array('getPost', 'getParam'))->getMock(); - $this->_response = $this->getMockBuilder('Mage_Core_Controller_Response_Http')->getMock(); - $this->_objectManager = $this->getMockBuilder('Magento_ObjectManager')->getMock(); - $frontController = $this->getMockBuilder('Mage_Core_Controller_Varien_Front')->getMock(); - - $helperMock = $this->getMockBuilder('Mage_Backend_Helper_Data')->disableOriginalConstructor()->getMock(); - $this->_sessionMock = $this->getMockBuilder('Mage_Backend_Model_Session')->disableOriginalConstructor() - ->setMethods(array('addError', 'setProductData'))->getMock(); - $translatorMock = $this->getMockBuilder('Mage_Core_Model_Translate')->getMock(); - - $this->_controller = $this->getMockBuilder('Mage_Adminhtml_Catalog_ProductController') - ->setMethods(array('loadLayout', '_initProduct', '_initProductSave', '_redirect', '__')) - ->setConstructorArgs(array( - $this->_request, - $this->_response, - $this->_objectManager, - $frontController, - array( - 'helper' => $helperMock, - 'session' => $this->_sessionMock, - 'translator' => $translatorMock, - ) - )) - ->getMock(); - $this->_controller->expects($this->any())->method('__')->will($this->returnArgument(0)); - } - - /** - * Test for Mage_Adminhtml_Catalog_ProductController::saveAction - */ - public function testSaveActionWithDangerRequest() - { - $data = array( - 'product' => array( - 'entity_id' => 234 - ) - ); - - $productMock = $this->getMockBuilder('Mage_Catalog_Model_Product') - ->setMethods(array('getIdFieldName', 'save', 'getSku')) - ->disableOriginalConstructor() - ->getMock(); - $productMock->expects($this->any())->method('getIdFieldName')->will($this->returnValue('entity_id')); - $productMock->expects($this->never())->method('save'); - - $this->_sessionMock->expects($this->once())->method('addError')->with('Unable to save product') - ->will($this->returnValue($this->_sessionMock)); - $this->_sessionMock->expects($this->once())->method('setProductData'); - - $this->_request->expects($this->any())->method('getPost')->will($this->returnValue($data)); - - $this->_controller->expects($this->any())->method('_initProductSave')->will($this->returnValue($productMock)); - - $this->_controller->saveAction(); - } - - /** - * Test for Mage_Adminhtml_Catalog_ProductController::quickCreateAction - */ - public function testQuickCreateActionWithDangerRequest() - { - $data = array( - 'entity_id' => 234 - ); - $this->_request->expects($this->any())->method('getParam')->will($this->returnValue($data)); - - $typeInstance = $this->getMockBuilder('Mage_Catalog_Model_Product_Type') - ->setMethods(array('getConfigurableAttributes', 'getEditableAttributes'))->getMock(); - $typeInstance->expects($this->any())->method('getEditableAttributes')->will($this->returnValue(array())); - $typeInstance->expects($this->any())->method('getConfigurableAttributes')->will($this->returnValue(array())); - - $productMock = $this->getMockBuilder('Mage_Catalog_Model_Product') - ->setMethods(array('getIdFieldName', 'save', 'getSku', 'isConfigurable', 'setStoreId', 'load', 'setTypeId', - 'setAttributeSetId', 'getAttributeSetId', 'getTypeInstance', 'getWebsiteIds')) - ->disableOriginalConstructor() - ->getMock(); - $productMock->expects($this->any())->method('getIdFieldName')->will($this->returnValue('entity_id')); - $productMock->expects($this->any())->method('isConfigurable')->will($this->returnValue(true)); - $productMock->expects($this->any())->method('setStoreId')->will($this->returnSelf()); - $productMock->expects($this->any())->method('load')->will($this->returnSelf()); - $productMock->expects($this->any())->method('setTypeId')->will($this->returnSelf()); - $productMock->expects($this->any())->method('setAttributeSetId')->will($this->returnSelf()); - $productMock->expects($this->any())->method('getTypeInstance')->will($this->returnValue($typeInstance)); - $productMock->expects($this->never())->method('save'); - - $this->_response->expects($this->once())->method('setBody') - ->with('{"attributes":[],"error":{"message":"Unable to create product"}}'); - - $helper = $this->getMockBuilder('Mage_Core_Helper_Data')->setMethods(array('jsonEncode'))->getMock(); - $helper->expects($this->once())->method('jsonEncode') - ->with(array( - 'attributes' => array(), - 'error' => array( - 'message' => 'Unable to create product', - 'fields' => array( - 'sku' => '' - ) - - ) - )) - ->will($this->returnValue('{"attributes":[],"error":{"message":"Unable to create product"}}')); - - $this->_objectManager->expects($this->any())->method('create') - ->with('Mage_Catalog_Model_Product', array(), true)->will($this->returnValue($productMock)); - $this->_objectManager->expects($this->any())->method('get') - ->with('Mage_Core_Helper_Data', array())->will($this->returnValue($helper)); - - $this->_controller->quickCreateAction(); - } -} diff --git a/dev/tests/unit/testsuite/Mage/Bundle/Model/Product/TypeTest.php b/dev/tests/unit/testsuite/Mage/Bundle/Model/Product/TypeTest.php new file mode 100644 index 0000000000000000000000000000000000000000..afe01bba4ed2c350e907fa944eade4ea8d0669ca --- /dev/null +++ b/dev/tests/unit/testsuite/Mage/Bundle/Model/Product/TypeTest.php @@ -0,0 +1,44 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @category Magento + * @package Mage_Bundle + * @subpackage unit_tests + * @copyright Copyright (c) 2012 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +class Mage_Bundle_Model_Product_TypeTest extends PHPUnit_Framework_TestCase +{ + /** + * @var Mage_Bundle_Model_Product_Type + */ + protected $_model; + + protected function setUp() + { + $this->_model = new Mage_Bundle_Model_Product_Type(); + } + + public function testHasWeightTrue() + { + $this->assertTrue($this->_model->hasWeight(), 'This product has not weight, but it should'); + } +} diff --git a/dev/tests/unit/testsuite/Mage/Catalog/Model/ObserverTest.php b/dev/tests/unit/testsuite/Mage/Catalog/Model/ObserverTest.php new file mode 100644 index 0000000000000000000000000000000000000000..2e5a9826f46a333e778f3a86a14f62bd02c84526 --- /dev/null +++ b/dev/tests/unit/testsuite/Mage/Catalog/Model/ObserverTest.php @@ -0,0 +1,80 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @category Magento + * @package Mage_Catalog + * @subpackage unit_tests + * @copyright Copyright (c) 2012 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +class Mage_Catalog_Model_ObserverTest extends PHPUnit_Framework_TestCase +{ + /** + * @var Varien_Event_Observer + */ + protected $_observer; + + /** + * @var Mage_Catalog_Model_Observer + */ + protected $_model; + + protected function setUp() + { + $this->_model = new Mage_Catalog_Model_Observer(); + } + + public function testTransitionProductTypeSimple() + { + $this->markTestIncomplete('MAGETWO-4796'); + $product = new Varien_Object(array('type_id' => 'simple')); + $this->_observer = new Varien_Event_Observer(array('product' => $product)); + $this->_model->transitionProductType($this->_observer); + $this->assertEquals('simple', $product->getTypeId()); + } + + public function testTransitionProductTypeVirtual() + { + $this->markTestIncomplete('MAGETWO-4796'); + $product = new Varien_Object(array('type_id' => 'virtual', 'is_virtual' => '')); + $this->_observer = new Varien_Event_Observer(array('product' => $product)); + $this->_model->transitionProductType($this->_observer); + $this->assertEquals('virtual', $product->getTypeId()); + } + + public function testTransitionProductTypeSimpleToVirtual() + { + $this->markTestIncomplete('MAGETWO-4796'); + $product = new Varien_Object(array('type_id' => 'simple', 'is_virtual' => '')); + $this->_observer = new Varien_Event_Observer(array('product' => $product)); + $this->_model->transitionProductType($this->_observer); + $this->assertEquals('virtual', $product->getTypeId()); + } + + public function testTransitionProductTypeVirtualToSimple() + { + $this->markTestIncomplete('MAGETWO-4796'); + $product = new Varien_Object(array('type_id' => 'virtual')); + $this->_observer = new Varien_Event_Observer(array('product' => $product)); + $this->_model->transitionProductType($this->_observer); + $this->assertEquals('simple', $product->getTypeId()); + } +} diff --git a/dev/tests/unit/testsuite/Mage/Catalog/Model/Product/Attribute/Backend/StockTest.php b/dev/tests/unit/testsuite/Mage/Catalog/Model/Product/Attribute/Backend/StockTest.php index aa9da4264f7edbe82b85966135f4bb75c38c5526..d47fcc3670d04dcc3ed419a286d9bcb02e8ae5a8 100644 --- a/dev/tests/unit/testsuite/Mage/Catalog/Model/Product/Attribute/Backend/StockTest.php +++ b/dev/tests/unit/testsuite/Mage/Catalog/Model/Product/Attribute/Backend/StockTest.php @@ -81,4 +81,30 @@ class Mage_Catalog_Model_Product_Attribute_Backend_StockTest extends PHPUnit_Fra $this->assertEquals(5, $stockData['qty']); $this->assertNull($object->getData(self::ATTRIBUTE_NAME)); } + + public function testBeforeSaveQtyIsEmpty() + { + $object = new Varien_Object(array( + self::ATTRIBUTE_NAME => array('is_in_stock' => 1, 'qty' => ''), + 'stock_data' => array('is_in_stock' => 2, 'qty' => '') + )); + + $this->_model->beforeSave($object); + + $stockData = $object->getStockData(); + $this->assertNull($stockData['qty']); + } + + public function testBeforeSaveQtyIsZero() + { + $object = new Varien_Object(array( + self::ATTRIBUTE_NAME => array('is_in_stock' => 1, 'qty' => 0), + 'stock_data' => array('is_in_stock' => 2, 'qty' => 0) + )); + + $this->_model->beforeSave($object); + + $stockData = $object->getStockData(); + $this->assertEquals(0, $stockData['qty']); + } } diff --git a/dev/tests/unit/testsuite/Mage/Catalog/Model/Product/Type/ConfigurableTest.php b/dev/tests/unit/testsuite/Mage/Catalog/Model/Product/Type/ConfigurableTest.php new file mode 100644 index 0000000000000000000000000000000000000000..f4bbdfd4b793e52687a4dd5381047ae3bee3e734 --- /dev/null +++ b/dev/tests/unit/testsuite/Mage/Catalog/Model/Product/Type/ConfigurableTest.php @@ -0,0 +1,44 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @category Magento + * @package Mage_Catalog + * @subpackage unit_tests + * @copyright Copyright (c) 2012 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +class Mage_Catalog_Model_Product_Type_ConfigurableTest extends PHPUnit_Framework_TestCase +{ + /** + * @var Mage_Catalog_Model_Product_Type_Configurable + */ + protected $_model; + + protected function setUp() + { + $this->_model = new Mage_Catalog_Model_Product_Type_Configurable(); + } + + public function testHasWeightFalse() + { + $this->assertFalse($this->_model->hasWeight(), 'This product has weight, but it should not'); + } +} diff --git a/dev/tests/unit/testsuite/Mage/Catalog/Model/Product/Type/GroupedTest.php b/dev/tests/unit/testsuite/Mage/Catalog/Model/Product/Type/GroupedTest.php new file mode 100644 index 0000000000000000000000000000000000000000..e64ba5339d70aaa9af34f2bcbfea4595311ae1db --- /dev/null +++ b/dev/tests/unit/testsuite/Mage/Catalog/Model/Product/Type/GroupedTest.php @@ -0,0 +1,44 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @category Magento + * @package Mage_Catalog + * @subpackage unit_tests + * @copyright Copyright (c) 2012 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +class Mage_Catalog_Model_Product_Type_GroupedTest extends PHPUnit_Framework_TestCase +{ + /** + * @var Mage_Catalog_Model_Product_Type_Grouped + */ + protected $_model; + + protected function setUp() + { + $this->_model = new Mage_Catalog_Model_Product_Type_Grouped(); + } + + public function testHasWeightFalse() + { + $this->assertFalse($this->_model->hasWeight(), 'This product has weight, but it should not'); + } +} diff --git a/dev/tests/unit/testsuite/Mage/Catalog/Model/Product/Type/SimpleTest.php b/dev/tests/unit/testsuite/Mage/Catalog/Model/Product/Type/SimpleTest.php new file mode 100644 index 0000000000000000000000000000000000000000..a9a3acf259af0c1c8ec744ee9330a5c261595d1a --- /dev/null +++ b/dev/tests/unit/testsuite/Mage/Catalog/Model/Product/Type/SimpleTest.php @@ -0,0 +1,44 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @category Magento + * @package Mage_Catalog + * @subpackage unit_tests + * @copyright Copyright (c) 2012 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +class Mage_Catalog_Model_Product_Type_SimpleTest extends PHPUnit_Framework_TestCase +{ + /** + * @var Mage_Catalog_Model_Product_Type_Simple + */ + protected $_model; + + protected function setUp() + { + $this->_model = new Mage_Catalog_Model_Product_Type_Simple(); + } + + public function testHasWeightTrue() + { + $this->assertTrue($this->_model->hasWeight(), 'This product has not weight, but it should'); + } +} diff --git a/dev/tests/unit/testsuite/Mage/Catalog/Model/Product/Type/VirtualTest.php b/dev/tests/unit/testsuite/Mage/Catalog/Model/Product/Type/VirtualTest.php new file mode 100644 index 0000000000000000000000000000000000000000..757918ef0601c2c40b4c6316897c52988ec181d6 --- /dev/null +++ b/dev/tests/unit/testsuite/Mage/Catalog/Model/Product/Type/VirtualTest.php @@ -0,0 +1,44 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @category Magento + * @package Mage_Catalog + * @subpackage unit_tests + * @copyright Copyright (c) 2012 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +class Mage_Catalog_Model_Product_Type_VirtualTest extends PHPUnit_Framework_TestCase +{ + /** + * @var Mage_Catalog_Model_Product_Type_Virtual + */ + protected $_model; + + protected function setUp() + { + $this->_model = new Mage_Catalog_Model_Product_Type_Virtual(); + } + + public function testHasWeightFalse() + { + $this->assertFalse($this->_model->hasWeight(), 'This product has weight, but it should not'); + } +} diff --git a/dev/tests/unit/testsuite/Mage/Catalog/Model/Resource/Product/Collection/AssociatedProductUpdaterTest.php b/dev/tests/unit/testsuite/Mage/Catalog/Model/Resource/Product/Collection/AssociatedProductUpdaterTest.php new file mode 100644 index 0000000000000000000000000000000000000000..b7048c6f2bf6b9ab1a7e7e7ae072e549ff435f00 --- /dev/null +++ b/dev/tests/unit/testsuite/Mage/Catalog/Model/Resource/Product/Collection/AssociatedProductUpdaterTest.php @@ -0,0 +1,53 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @category Magento + * @package Mage_Catalog + * @subpackage unit_tests + * @copyright Copyright (c) 2012 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +class Mage_Catalog_Model_Resource_Product_Collection_AssociatedProductUpdaterTest extends PHPUnit_Framework_TestCase +{ + /** + * Test adding filtration by qty and stock availability to collection + */ + public function testUpdate() + { + $inventory = array( + 'qty' => 'qty', + 'inventory_in_stock' => 'is_in_stock' + ); + $collection = $this->getMockBuilder('Varien_Data_Collection_Db') + ->disableOriginalConstructor() + ->getMock(); + $stockItem = $this->getMockBuilder('Mage_CatalogInventory_Model_Resource_Stock_Item') + ->disableOriginalConstructor() + ->setMethods(array('addCatalogInventoryToProductCollection')) + ->getMock(); + $stockItem->expects($this->any()) + ->method('addCatalogInventoryToProductCollection') + ->with($collection, $inventory); + + $model = new Mage_Catalog_Model_Resource_Product_Collection_AssociatedProductUpdater($stockItem); + $model->update($collection); + } +} diff --git a/dev/tests/unit/testsuite/Mage/Downloadable/Model/ObserverTest.php b/dev/tests/unit/testsuite/Mage/Downloadable/Model/ObserverTest.php index af9e00636a3f88f31e3bbfac34adcd58ae4da747..9d91e4e3228a4a15638f8146792487f2a89649aa 100644 --- a/dev/tests/unit/testsuite/Mage/Downloadable/Model/ObserverTest.php +++ b/dev/tests/unit/testsuite/Mage/Downloadable/Model/ObserverTest.php @@ -158,6 +158,32 @@ class Mage_Downloadable_Model_ObserverTest extends PHPUnit_Framework_TestCase $this->assertEquals($links['number_of_downloads'], $newDownloadableData['link'][0]['number_of_downloads']); } + /** + * Get downloadable data without is_delete flag + * + * @return array + */ + protected function _getDownloadableData() + { + return array( + 'sample' => array(array('id' => 1, 'is_delete' => '')), + 'link' => array(array('id' => 2, 'is_delete' => '')) + ); + } + + /** + * Get downloadable data with set is_delete flag + * + * @return array + */ + protected function _getDownloadableDataForDelete() + { + return array( + 'sample' => array(array('id' => 1, 'is_delete' => '1')), + 'link' => array(array('id' => 2, 'is_delete' => '1')) + ); + } + /** * Set products to observer * diff --git a/dev/tests/unit/testsuite/Mage/Downloadable/Model/Product/TypeTest.php b/dev/tests/unit/testsuite/Mage/Downloadable/Model/Product/TypeTest.php new file mode 100644 index 0000000000000000000000000000000000000000..875aed90c4584b60a80c17e72964ba0c9ef3b484 --- /dev/null +++ b/dev/tests/unit/testsuite/Mage/Downloadable/Model/Product/TypeTest.php @@ -0,0 +1,44 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @category Magento + * @package Mage_Downloadable + * @subpackage unit_tests + * @copyright Copyright (c) 2012 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +class Mage_Downloadable_Model_Product_TypeTest extends PHPUnit_Framework_TestCase +{ + /** + * @var Mage_Downloadable_Model_Product_Type + */ + protected $_model; + + protected function setUp() + { + $this->_model = new Mage_Downloadable_Model_Product_Type(); + } + + public function testHasWeightFalse() + { + $this->assertFalse($this->_model->hasWeight(), 'This product has weight, but it should not'); + } +} diff --git a/dev/tests/unit/testsuite/Mage/Eav/Model/Entity/Attribute/Backend/ArrayTest.php b/dev/tests/unit/testsuite/Mage/Eav/Model/Entity/Attribute/Backend/ArrayTest.php new file mode 100644 index 0000000000000000000000000000000000000000..b3967b4286d64ce9931e3bd659fecc128f9d1b5f --- /dev/null +++ b/dev/tests/unit/testsuite/Mage/Eav/Model/Entity/Attribute/Backend/ArrayTest.php @@ -0,0 +1,71 @@ +<?php +/** + * Magento + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://opensource.org/licenses/osl-3.0.php + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@magentocommerce.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade Magento to newer + * versions in the future. If you wish to customize Magento for your + * needs please refer to http://www.magentocommerce.com for more information. + * + * @category Magento + * @package Mage_Eav + * @subpackage unit_tests + * @copyright Copyright (c) 2012 X.commerce, Inc. (http://www.magentocommerce.com) + * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) + */ + +class Mage_Eav_Model_Entity_Attribute_Backend_ArrayTest extends PHPUnit_Framework_TestCase +{ + /** + * @var Mage_Eav_Model_Entity_Attribute_Backend_Array + */ + protected $_model; + + /** + * @var Mage_Eav_Model_Entity_Attribute + */ + protected $_attribute; + + protected function setUp() + { + $this->_attribute = $this->getMock( + 'Mage_Eav_Model_Entity_Attribute', array('getAttributeCode'), array(), '', false + ); + $this->_model = new Mage_Eav_Model_Entity_Attribute_Backend_Array(); + $this->_model->setAttribute($this->_attribute); + } + + /** + * @dataProvider attributeValueDataProvider + */ + public function testValidate($data) + { + $this->_attribute->expects($this->atLeastOnce())->method('getAttributeCode')->will($this->returnValue('code')); + $product = new Varien_Object(array('code' => $data)); + $this->_model->validate($product); + $this->assertEquals('1,2,3', $product->getCode()); + } + + public static function attributeValueDataProvider() + { + return array( + array( + array(1, 2, 3) + ), + array( + '1,2,3' + ) + ); + } +} diff --git a/dev/tools/migration/themes_view.php b/dev/tools/migration/themes_view.php index d4cb82b516643bd644670c7b716d4226c69ba82e..7e0cf18f1683f15fb44ba0fc550cea8e45b38043 100644 --- a/dev/tools/migration/themes_view.php +++ b/dev/tools/migration/themes_view.php @@ -24,24 +24,7 @@ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ -/** - * Constants definition - */ -define('DS', DIRECTORY_SEPARATOR); -define('BP', realpath(__DIR__ . '/../../..')); -/** - * Require necessary files - */ -require_once BP . '/lib/Magento/Autoload.php'; -require_once BP . '/app/code/core/Mage/Core/functions.php'; -require_once BP . '/app/Mage.php'; - -$paths[] = BP . DS . 'app' . DS . 'code' . DS . 'local'; -$paths[] = BP . DS . 'app' . DS . 'code' . DS . 'community'; -$paths[] = BP . DS . 'app' . DS . 'code' . DS . 'core'; -$paths[] = BP . DS . 'lib'; -Magento_Autoload::getInstance()->addIncludePath($paths); -Mage::setRoot(); +require_once __DIR__ . '/../../../app/bootstrap.php'; Mage::setIsDeveloperMode(true); try { diff --git a/pub/lib/mage/adminhtml/grid.js b/pub/lib/mage/adminhtml/grid.js index c08f61f16e0e783485c9379c1ed51e2aeb02db8c..3abb9fcc96b583bd2653352d02b52f836b2f22ac 100644 --- a/pub/lib/mage/adminhtml/grid.js +++ b/pub/lib/mage/adminhtml/grid.js @@ -166,7 +166,7 @@ varienGrid.prototype = { if(this.useAjax){ new Ajax.Request(url + (url.match(new RegExp('\\?')) ? '&ajax=true' : '?ajax=true' ), { loaderArea: this.containerId, - parameters: this.reloadParams, + parameters: jQuery.param(this.reloadParams), evalScripts: true, onFailure: this._processFailure.bind(this), onComplete: this.initGridAjax.bind(this), diff --git a/pub/lib/mage/adminhtml/tabs.js b/pub/lib/mage/adminhtml/tabs.js index 4933f9d5e128bfbebfe8729c781797895851bbde..690f066a24f9aae0a1a40e1469fcc9120469626f 100644 --- a/pub/lib/mage/adminhtml/tabs.js +++ b/pub/lib/mage/adminhtml/tabs.js @@ -100,7 +100,7 @@ varienTabs.prototype = { data = data ? jQuery.extend(data, options) : options; }, this)); }, - + setSkipDisplayFirstTab : function(){ this.displayFirst = null; }, @@ -187,7 +187,13 @@ varienTabs.prototype = { if (tabContentElement) { if (this.activeTab != tab) { if (varienGlobalEvents) { - if (varienGlobalEvents.fireEvent('tabChangeBefore', $(this.getTabContentElementId(this.activeTab))).indexOf('cannotchange') != -1) { + var defaultTab = this.tabs[0]; + var eventData = { + from: this.activeTab ? this.activeTab.getAttribute('id') : null, + to: tab ? tab.getAttribute('id') : null, + first: defaultTab && tab && tab.getAttribute('id') == defaultTab.getAttribute('id') + }; + if (varienGlobalEvents.fireEvent('tabChangeBefore', eventData) === false) { return; }; } diff --git a/pub/lib/prototype/validation.js b/pub/lib/prototype/validation.js index 357746bf739c22beb132e25762dd5d785bf0ec1f..22e2f2c88234cf7d6a8f788d86ab2a830792ba10 100644 --- a/pub/lib/prototype/validation.js +++ b/pub/lib/prototype/validation.js @@ -137,6 +137,9 @@ Validation.prototype = { if (elm.hasClassName('local-validation') && !this.isElementInForm(elm, this.form)) { return true; } + if (elm.hasClassName('validation-disabled')) { + return true; + } return Validation.validate(elm,{useTitle : useTitles, onElementValidate : callback}); }, this).all(); }