Permalink
Browse files

2.0.0.0-dev32

* Improved product edit workflow:
  * Introduced Category Assignment control on "General" tab
  * Eliminated attribute preselection screen
  * Base image assignment control moved to "General" tab
  * Base inventory attributes controls displayed on "General" tab. Values of the attributes are synchronized between "General" and "Inventory" tabs
* Improved static code analysis tests to verify existence of paths specified in white/black lists
* Reduced memory usage by integration tests by automatic cleaning properties of test classes
* Added migration tool `dev/tools/migration/themes_view.php` for replacing old `{{skin}}` with new `{{view}}` placeholders
* Changed handling of exceptions, produced by non-existing view files, to not break whole page
* Removed empty locale files
* Bug fixes:
  * Page with tracking information absent, if shipping labels integration is used
  * Category is not displayed on frontend with "Use Flat Catalog Category" option enabled
  * Exception on "Coupons Usage Report" page after upgrade from Magento 1.x
  * Exception on "Most Viewed Products" page after upgrade from Magento 1.x
  * Quick search produces error, if searching for a product with an attribute that has "Use In Search Results Layered Navigation" option set to "Yes"
  * Exception on "Add/Edit Customer" page when Magento profiler with html output is enabled
  * Can't duplicate downloadable product with sample file attached
  * Product Type dropdown on "Add Product" page doesn't work in IE9
  * Various issues related to adding/editing product
  • Loading branch information...
1 parent b516bc3 commit 3916eac0679f6133359261fc1ebf907e4bf01326 @magento-team magento-team committed Nov 22, 2012
Showing with 5,026 additions and 875 deletions.
  1. +23 −0 CHANGELOG.markdown
  2. +1 −1 app/Mage.php
  3. +55 −2 app/code/core/Mage/Adminhtml/Block/Catalog/Category/Tree.php
  4. +4 −7 app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit.php
  5. +2 −1 app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/Action/Attribute/Tab/Attributes.php
  6. +0 −286 app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/Tab/Categories.php
  7. +13 −0 app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/Tab/Super/Config.php
  8. +12 −29 app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/Tab/Super/Settings.php
  9. +0 −6 app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/Tabs.php
  10. +179 −0 app/code/core/Mage/Adminhtml/Block/Catalog/Product/Helper/Form/BaseImage.php
  11. +116 −0 app/code/core/Mage/Adminhtml/Block/Catalog/Product/Helper/Form/Category.php
  12. +5 −15 app/code/core/Mage/Adminhtml/Block/Customer/Edit/Tabs.php
  13. +10 −0 app/code/core/Mage/Adminhtml/controllers/Catalog/CategoryController.php
  14. +14 −27 app/code/core/Mage/Adminhtml/controllers/Catalog/ProductController.php
  15. +17 −11 app/code/core/Mage/Adminhtml/view/adminhtml/catalog.xml
  16. BIN app/code/core/Mage/Adminhtml/view/adminhtml/catalog/images/select2.png
  17. BIN app/code/core/Mage/Adminhtml/view/adminhtml/catalog/images/select2x2.png
  18. BIN app/code/core/Mage/Adminhtml/view/adminhtml/catalog/images/spinner.gif
  19. +28 −0 app/code/core/Mage/Adminhtml/view/adminhtml/catalog/jquery.base-image-uploader.css
  20. +57 −0 app/code/core/Mage/Adminhtml/view/adminhtml/catalog/jquery.base-image-uploader.js
  21. +585 −0 app/code/core/Mage/Adminhtml/view/adminhtml/catalog/jquery.category-selector.css
  22. +142 −0 app/code/core/Mage/Adminhtml/view/adminhtml/catalog/jquery.category-selector.js
  23. +10 −12 app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product/edit.phtml
  24. +0 −148 app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product/edit/categories.phtml
  25. +6 −0 app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product/edit/super/config.phtml
  26. BIN app/code/core/Mage/Adminhtml/view/adminhtml/images/image-placeholder.png
  27. +1 −1 app/code/core/Mage/Backend/Block/Widget/Form.php
  28. +19 −18 app/code/core/Mage/Backend/Block/Widget/Grid/Column/Filter/Date.php
  29. +25 −24 app/code/core/Mage/Backend/Block/Widget/Grid/Column/Filter/Datetime.php
  30. +1 −1 app/code/core/Mage/Backend/view/adminhtml/widget/button/split.phtml
  31. +2 −25 app/code/core/Mage/Catalog/Model/Product.php
  32. +47 −0 app/code/core/Mage/Catalog/Model/Product/Attribute/Backend/Category.php
  33. +84 −0 app/code/core/Mage/Catalog/Model/Product/Attribute/Backend/Stock.php
  34. +1 −2 app/code/core/Mage/Catalog/Model/Resource/Product.php
  35. +55 −0 app/code/core/Mage/Catalog/data/catalog_setup/data-upgrade-1.6.0.0.17-1.6.0.0.18.php
  36. +54 −0 app/code/core/Mage/Catalog/data/catalog_setup/data-upgrade-1.6.0.0.18-1.6.0.0.19.php
  37. +4 −1 app/code/core/Mage/Catalog/etc/config.xml
  38. +48 −0 app/code/core/Mage/Catalog/sql/catalog_setup/upgrade-1.6.0.0.17-1.6.0.0.18.php
  39. +213 −0 app/code/core/Mage/CatalogInventory/Block/Adminhtml/Form/Field/Stock.php
  40. +19 −0 app/code/core/Mage/CatalogInventory/Model/Stock/Status.php
  41. +3 −3 app/code/core/Mage/CatalogSearch/Block/Layer/Filter/Attribute.php
  42. +11 −9 app/code/core/Mage/Cms/Helper/Page.php
  43. +23 −8 app/code/core/Mage/Core/Block/Abstract.php
  44. +45 −49 app/code/core/Mage/Core/Controller/Varien/Action.php
  45. +0 −2 app/code/core/Mage/Core/Model/Layout.php
  46. +6 −4 app/code/core/Mage/Core/Model/Resource/Session.php
  47. +11 −1 app/code/core/Mage/Core/controllers/IndexController.php
  48. +52 −16 app/code/core/Mage/Downloadable/Model/Observer.php
  49. +1 −1 app/code/core/Mage/Eav/Model/Resource/Entity/Attribute.php
  50. +81 −0 app/code/core/Mage/Index/Model/Lock/Storage.php
  51. +47 −45 app/code/core/Mage/Index/Model/Process.php
  52. +101 −0 app/code/core/Mage/Index/Model/Process/File.php
  53. +58 −0 app/code/core/Mage/Index/Model/Process/FileFactory.php
  54. +54 −9 app/code/core/Mage/Page/Block/Html/Head.php
  55. +3 −3 app/code/core/Mage/Reports/Model/Resource/Report/Product/Viewed.php
  56. +2 −2 app/code/core/Mage/Reports/etc/config.xml
  57. +46 −0 app/code/core/Mage/Reports/sql/reports_setup/upgrade-1.6.0.0.1-1.6.0.0.2.php
  58. +38 −8 app/code/core/Mage/Sales/Block/Adminhtml/Report/Filter/Form/Coupon.php
  59. +10 −0 app/code/core/Mage/Sales/Model/Order/Shipment/Track.php
  60. +1 −1 app/code/core/Mage/SalesRule/Model/Resource/Report/Rule.php
  61. +0 −9 app/code/core/Mage/Theme/etc/config.xml
  62. 0 app/code/core/Mage/Theme/locale/de_DE/Mage_Theme.csv
  63. 0 app/code/core/Mage/Theme/locale/en_US/Mage_Theme.csv
  64. 0 app/code/core/Mage/Theme/locale/es_ES/Mage_Theme.csv
  65. 0 app/code/core/Mage/Theme/locale/fr_FR/Mage_Theme.csv
  66. 0 app/code/core/Mage/Theme/locale/nl_NL/Mage_Theme.csv
  67. 0 app/code/core/Mage/Theme/locale/pt_BR/Mage_Theme.csv
  68. 0 app/code/core/Mage/Theme/locale/zh_CN/Mage_Theme.csv
  69. +2 −0 dev/build/publication/extruder/ce.txt
  70. +55 −0 dev/tests/integration/framework/Magento/Test/ClearProperties.php
  71. +1 −1 dev/tests/integration/framework/Magento/Test/Event/PhpUnit.php
  72. +1 −0 dev/tests/integration/framework/bootstrap.php
  73. +118 −0 dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/ClearPropertiesTest.php
  74. +89 −0 dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/_files/DummyTestCase.php
  75. +39 −0 dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/_files/Stub.php
  76. +18 −0 dev/tests/integration/testsuite/Mage/Adminhtml/Block/Catalog/Product/Edit/Tab/Super/ConfigTest.php
  77. +72 −0 dev/tests/integration/testsuite/Mage/Adminhtml/Block/Catalog/Product/Edit/Tab/Super/SettingsTest.php
  78. +1 −0 dev/tests/integration/testsuite/Mage/Bundle/Model/ProductTest.php
  79. +133 −2 dev/tests/integration/testsuite/Mage/Catalog/Model/CategoryTest.php
  80. +0 −14 dev/tests/integration/testsuite/Mage/Catalog/Model/ProductExternalTest.php
  81. +1 −0 dev/tests/integration/testsuite/Mage/Catalog/Model/ProductTest.php
  82. +23 −2 dev/tests/integration/testsuite/Mage/Catalog/_files/product_special_price.php
  83. +2 −4 dev/tests/integration/testsuite/Mage/Cms/_files/pages.php
  84. +33 −2 dev/tests/integration/testsuite/Mage/Core/Block/AbstractTest.php
  85. +0 −1 dev/tests/integration/testsuite/Mage/Core/Model/LayoutTest.php
  86. +19 −3 dev/tests/integration/testsuite/Mage/Core/Model/Resource/SessionTest.php
  87. +2 −2 dev/tests/integration/testsuite/Mage/Core/_files/design_change.php
  88. +36 −0 dev/tests/integration/testsuite/Mage/Core/controllers/IndexControllerTest.php
  89. +51 −0 dev/tests/integration/testsuite/Mage/Downloadable/Model/ObserverTest.php
  90. +82 −0 dev/tests/integration/testsuite/Mage/Downloadable/_files/product_with_files.php
  91. +236 −0 dev/tests/integration/testsuite/Mage/ImportExport/Model/Import/Entity/CustomerCompositeTest.php
  92. +2 −0 .../integration/testsuite/Mage/ImportExport/Model/Import/Entity/_files/customer_composite_delete.csv
  93. +7 −0 .../integration/testsuite/Mage/ImportExport/Model/Import/Entity/_files/customer_composite_update.csv
  94. +193 −0 dev/tests/integration/testsuite/Mage/Index/Model/Process/FileTest.php
  95. +18 −0 dev/tests/integration/testsuite/Mage/Page/Block/Html/HeadTest.php
  96. +69 −0 dev/tests/integration/testsuite/Mage/Sales/Block/Adminhtml/Report/Filter/Form/CouponTest.php
  97. +7 −0 dev/tests/static/testsuite/Php/_files/whitelist/common.txt
  98. +166 −0 dev/tests/unit/testsuite/Mage/Adminhtml/Block/Catalog/Product/Helper/Form/BaseImageTest.php
  99. +4 −0 dev/tests/unit/testsuite/Mage/Adminhtml/Block/Catalog/Product/Helper/Form/_files/BaseImageHtml.txt
  100. +0 −1 dev/tests/unit/testsuite/Mage/Backend/Block/System/Config/EditTest.php
  101. +53 −0 dev/tests/unit/testsuite/Mage/Catalog/Model/Product/Attribute/Backend/CategoryTest.php
  102. +84 −0 dev/tests/unit/testsuite/Mage/Catalog/Model/Product/Attribute/Backend/StockTest.php
  103. +78 −0 dev/tests/unit/testsuite/Mage/CatalogInventory/Block/Adminhtml/Form/Field/StockTest.php
  104. +234 −0 dev/tests/unit/testsuite/Mage/Downloadable/Model/ObserverTest.php
  105. +4 −4 dev/tests/unit/testsuite/Mage/Eav/Model/Resource/Entity/AttributeTest.php
  106. +115 −0 dev/tests/unit/testsuite/Mage/Index/Model/Lock/StorageTest.php
  107. +61 −0 dev/tests/unit/testsuite/Mage/Index/Model/Process/FileFactoryTest.php
  108. +163 −0 dev/tests/unit/testsuite/Mage/Index/Model/ProcessTest.php
  109. +18 −1 dev/tests/unit/testsuite/Mage/Sales/Model/Order/Shipment/TrackTest.php
  110. +103 −0 dev/tests/unit/testsuite/Mage/SalesRule/Model/Resource/Report/RuleTest.php
  111. +33 −51 dev/tests/unit/testsuite/Varien/Io/FileTest.php
  112. +33 −0 dev/tools/migration/aliases_map/cms_content_tables_ce.php
  113. +122 −0 dev/tools/migration/themes_view.php
View
23 CHANGELOG.markdown
@@ -1,3 +1,26 @@
+2.0.0.0-dev32
+=============
+* Improved product edit workflow:
+ * Introduced Category Assignment control on "General" tab
+ * Eliminated attribute preselection screen
+ * Base image assignment control moved to "General" tab
+ * Base inventory attributes controls displayed on "General" tab. Values of the attributes are synchronized between "General" and "Inventory" tabs
+* Improved static code analysis tests to verify existence of paths specified in white/black lists
+* Reduced memory usage by integration tests by automatic cleaning properties of test classes
+* Added migration tool `dev/tools/migration/themes_view.php` for replacing old `{{skin}}` with new `{{view}}` placeholders
+* Changed handling of exceptions, produced by non-existing view files, to not break whole page
+* Removed empty locale files
+* Bug fixes:
+ * Page with tracking information absent, if shipping labels integration is used
+ * Category is not displayed on frontend with "Use Flat Catalog Category" option enabled
+ * Exception on "Coupons Usage Report" page after upgrade from Magento 1.x
+ * Exception on "Most Viewed Products" page after upgrade from Magento 1.x
+ * Quick search produces error, if searching for a product with an attribute that has "Use In Search Results Layered Navigation" option set to "Yes"
+ * Exception on "Add/Edit Customer" page when Magento profiler with html output is enabled
+ * Can't duplicate downloadable product with sample file attached
+ * Product Type dropdown on "Add Product" page doesn't work in IE9
+ * Various issues related to adding/editing product
+
2.0.0.0-dev31
=============
* Themes:
View
2 app/Mage.php
@@ -170,7 +170,7 @@ public static function getVersionInfo()
'revision' => '0',
'patch' => '0',
'stability' => 'dev',
- 'number' => '31',
+ 'number' => '32',
);
}
View
57 app/code/core/Mage/Adminhtml/Block/Catalog/Category/Tree.php
@@ -30,7 +30,7 @@
*
* @category Mage
* @package Mage_Adminhtml
- * @author Magento Core Team <core@magentocommerce.com>
+ * @author Magento Core Team <core@magentocommerce.com>
*/
class Mage_Adminhtml_Block_Catalog_Category_Tree extends Mage_Adminhtml_Block_Catalog_Category_Abstract
{
@@ -104,6 +104,57 @@ public function getCategoryCollection()
return $collection;
}
+ /**
+ * Retrieve list of categories with name containing $namePart and their parents
+ *
+ * @param string $namePart
+ * @return string
+ */
+ public function getSuggestedCategoriesJson($namePart)
+ {
+ $storeId = $this->getRequest()->getParam('store', $this->_getDefaultStoreId());
+
+ /* @var $collection Mage_Catalog_Model_Resource_Category_Collection */
+ $collection = Mage::getModel('Mage_Catalog_Model_Category')->getCollection();
+
+ $matchingNamesCollection = clone $collection;
+ $matchingNamesCollection->addAttributeToFilter('name', array('like' => "%{$namePart}%"))
+ ->addAttributeToSelect('path')
+ ->setStoreId($storeId);
+
+ $shownCategoriesIds = array();
+ foreach ($matchingNamesCollection as $category) {
+ foreach (explode('/', $category->getPath()) as $parentId) {
+ $shownCategoriesIds[$parentId] = 1;
+ }
+ }
+
+ $collection->addAttributeToFilter('entity_id', array('in' => array_keys($shownCategoriesIds)))
+ ->addAttributeToSelect(array('name', 'is_active', 'parent_id'))
+ ->setStoreId($storeId);
+
+ $categoryById = array(
+ Mage_Catalog_Model_Category::TREE_ROOT_ID => array(
+ 'id' => Mage_Catalog_Model_Category::TREE_ROOT_ID,
+ 'children' => array()
+ )
+ );
+ foreach ($collection as $category) {
+ foreach (array($category->getId(), $category->getParentId()) as $categoryId) {
+ if (!isset($categoryById[$categoryId])) {
+ $categoryById[$categoryId] = array('id' => $categoryId, 'children' => array());
+ }
+ }
+ $categoryById[$category->getId()]['is_active'] = $category->getIsActive();
+ $categoryById[$category->getId()]['name'] = $category->getName();
+ $categoryById[$category->getParentId()]['children'][] = &$categoryById[$category->getId()];
+ }
+
+ return Mage::helper('Mage_Core_Helper_Data')->jsonEncode(
+ $categoryById[Mage_Catalog_Model_Category::TREE_ROOT_ID]['children']
+ );
+ }
+
public function getAddRootButtonHtml()
{
return $this->getChildHtml('add_root_button');
@@ -173,7 +224,9 @@ public function getTree($parenNodeCategory=null)
public function getTreeJson($parenNodeCategory=null)
{
$rootArray = $this->_getNodeJson($this->getRoot($parenNodeCategory));
- $json = Mage::helper('Mage_Core_Helper_Data')->jsonEncode(isset($rootArray['children']) ? $rootArray['children'] : array());
+ $json = Mage::helper('Mage_Core_Helper_Data')->jsonEncode(
+ isset($rootArray['children']) ? $rootArray['children'] : array()
+ );
return $json;
}
View
11 app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit.php
@@ -74,15 +74,12 @@ protected function _prepareLayout()
}
if (!$this->getProduct()->isReadonly()) {
- $this->setChild('change_attribute_set_button',
- $this->getLayout()->createBlock(
- 'Mage_Adminhtml_Block_Widget_Button',
- $this->getNameInLayout() . '-change-attribute-set'
- )->setData(array(
+ if (!$this->getProduct()->isConfigurable() || !$this->getIsConfigured()) {
+ $this->addChild('change_attribute_set_button', 'Mage_Adminhtml_Block_Widget_Button', array(
'label' => Mage::helper('Mage_Catalog_Helper_Data')->__('Change Attribute Set'),
'onclick' => "jQuery('#attribute-set-info').dialog('open');"
- ))
- );
+ ));
+ }
$this->addChild('reset_button', 'Mage_Adminhtml_Block_Widget_Button', array(
'label' => Mage::helper('Mage_Catalog_Helper_Data')->__('Reset'),
View
3 app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/Action/Attribute/Tab/Attributes.php
@@ -45,7 +45,8 @@ protected function _construct()
protected function _prepareForm()
{
$this->setFormExcludedFieldList(array(
- 'tier_price','gallery', 'media_gallery', 'recurring_profile', 'group_price'
+ 'tier_price', 'gallery', 'media_gallery', 'recurring_profile', 'group_price',
+ 'quantity_and_stock_status'
));
Mage::dispatchEvent('adminhtml_catalog_product_form_prepare_excluded_field_list', array('object'=>$this));
View
286 app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/Tab/Categories.php
@@ -1,286 +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 Magento Inc. (http://www.magentocommerce.com)
- * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
- */
-
-/**
- * Product categories tab
- *
- * @category Mage
- * @package Mage_Adminhtml
- * @author Magento Core Team <core@magentocommerce.com>
- */
-class Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Categories extends Mage_Adminhtml_Block_Catalog_Category_Tree
-{
- protected $_categoryIds;
- protected $_selectedNodes = null;
-
- protected $_template = 'catalog/product/edit/categories.phtml';
-
- /**
- * Retrieve currently edited product
- *
- * @return Mage_Catalog_Model_Product
- */
- public function getProduct()
- {
- return Mage::registry('current_product');
- }
-
- /**
- * Checks when this block is readonly
- *
- * @return boolean
- */
- public function isReadonly()
- {
- return $this->getProduct()->getCategoriesReadonly();
- }
-
- /**
- * Return array with category IDs which the product is assigned to
- *
- * @return array
- */
- protected function getCategoryIds()
- {
- return $this->getProduct()->getCategoryIds();
- }
-
- /**
- * Forms string out of getCategoryIds()
- *
- * @return string
- */
- public function getIdsString()
- {
- return implode(',', $this->getCategoryIds());
- }
-
- /**
- * Returns root node and sets 'checked' flag (if necessary)
- *
- * @return Varien_Data_Tree_Node
- */
- public function getRootNode()
- {
- $root = $this->getRoot();
- if ($root && in_array($root->getId(), $this->getCategoryIds())) {
- $root->setChecked(true);
- }
- return $root;
- }
-
- /**
- * Returns root node
- *
- * @param Mage_Catalog_Model_Category|null $parentNodeCategory
- * @param int $recursionLevel
- * @return Varien_Data_Tree_Node
- */
- public function getRoot($parentNodeCategory = null, $recursionLevel = 3)
- {
- if (!is_null($parentNodeCategory) && $parentNodeCategory->getId()) {
- return $this->getNode($parentNodeCategory, $recursionLevel);
- }
- $root = Mage::registry('root');
- if (is_null($root)) {
- $storeId = (int) $this->getRequest()->getParam('store');
-
- if ($storeId) {
- $store = Mage::app()->getStore($storeId);
- $rootId = $store->getRootCategoryId();
- }
- else {
- $rootId = Mage_Catalog_Model_Category::TREE_ROOT_ID;
- }
-
- $ids = $this->getSelectedCategoriesPathIds($rootId);
- $tree = Mage::getResourceSingleton('Mage_Catalog_Model_Resource_Category_Tree')
- ->loadByIds($ids, false, false);
-
- if ($this->getCategory()) {
- $tree->loadEnsuredNodes($this->getCategory(), $tree->getNodeById($rootId));
- }
-
- $tree->addCollectionData($this->getCategoryCollection());
-
- $root = $tree->getNodeById($rootId);
-
- if ($root && $rootId != Mage_Catalog_Model_Category::TREE_ROOT_ID) {
- $root->setIsVisible(true);
- if ($this->isReadonly()) {
- $root->setDisabled(true);
- }
- }
- elseif($root && $root->getId() == Mage_Catalog_Model_Category::TREE_ROOT_ID) {
- $root->setName(Mage::helper('Mage_Catalog_Helper_Data')->__('Root'));
- }
-
- Mage::register('root', $root);
- }
-
- return $root;
- }
-
- /**
- * Returns array with configuration of current node
- *
- * @param Varien_Data_Tree_Node $node
- * @param int $level How deep is the node in the tree
- * @return array
- */
- protected function _getNodeJson($node, $level = 1)
- {
- $item = parent::_getNodeJson($node, $level);
-
- if ($this->_isParentSelectedCategory($node)) {
- $item['expanded'] = true;
- }
-
- if (in_array($node->getId(), $this->getCategoryIds())) {
- $item['checked'] = true;
- }
-
- if ($this->isReadonly()) {
- $item['disabled'] = true;
- }
-
- return $item;
- }
-
- /**
- * Returns whether $node is a parent (not exactly direct) of a selected node
- *
- * @param Varien_Data_Tree_Node $node
- * @return bool
- */
- protected function _isParentSelectedCategory($node)
- {
- $result = false;
- // Contains string with all category IDs of children (not exactly direct) of the node
- $allChildren = $node->getAllChildren();
- if ($allChildren) {
- $selectedCategoryIds = $this->getCategoryIds();
- $allChildrenArr = explode(',', $allChildren);
- for ($i = 0, $cnt = count($selectedCategoryIds); $i < $cnt; $i++) {
- $isSelf = $node->getId() == $selectedCategoryIds[$i];
- if (!$isSelf && in_array($selectedCategoryIds[$i], $allChildrenArr)) {
- $result = true;
- break;
- }
- }
- }
-
- return $result;
- }
-
- /**
- * Returns array with nodes those are selected (contain current product)
- *
- * @return array
- */
- protected function _getSelectedNodes()
- {
- if ($this->_selectedNodes === null) {
- $this->_selectedNodes = array();
- $root = $this->getRoot();
- foreach ($this->getCategoryIds() as $categoryId) {
- if ($root) {
- $this->_selectedNodes[] = $root->getTree()->getNodeById($categoryId);
- }
- }
- }
-
- return $this->_selectedNodes;
- }
-
- /**
- * Returns JSON-encoded array of category children
- *
- * @param int $categoryId
- * @return string
- */
- public function getCategoryChildrenJson($categoryId)
- {
- $category = Mage::getModel('Mage_Catalog_Model_Category')->load($categoryId);
- $node = $this->getRoot($category, 1)->getTree()->getNodeById($categoryId);
-
- if (!$node || !$node->hasChildren()) {
- return '[]';
- }
-
- $children = array();
- foreach ($node->getChildren() as $child) {
- $children[] = $this->_getNodeJson($child);
- }
-
- return Mage::helper('Mage_Core_Helper_Data')->jsonEncode($children);
- }
-
- /**
- * Returns URL for loading tree
- *
- * @param null $expanded
- * @return string
- */
- public function getLoadTreeUrl($expanded = null)
- {
- return $this->getUrl('*/*/categoriesJson', array('_current' => true));
- }
-
- /**
- * Return distinct path ids of selected categories
- *
- * @param mixed $rootId Root category Id for context
- * @return array
- */
- public function getSelectedCategoriesPathIds($rootId = false)
- {
- $ids = array();
- $categoryIds = $this->getCategoryIds();
- if (empty($categoryIds)) {
- return array();
- }
- $collection = Mage::getResourceModel('Mage_Catalog_Model_Resource_Category_Collection');
-
- if ($rootId) {
- $collection->addFieldToFilter('parent_id', $rootId);
- } else {
- $collection->addFieldToFilter('entity_id', array('in'=>$categoryIds));
- }
-
- foreach ($collection as $item) {
- if ($rootId && !in_array($rootId, $item->getPathIds())) {
- continue;
- }
- foreach ($item->getPathIds() as $id) {
- if (!in_array($id, $ids)) {
- $ids[] = $id;
- }
- }
- }
- return $ids;
- }
-}
View
13 app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/Tab/Super/Config.php
@@ -110,6 +110,7 @@ protected function _prepareLayout()
'class' => 'add',
'onclick' => 'superProduct.createEmptyProduct()'
));
+ $this->addChild('super_settings', 'Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Super_Settings');
if ($this->_getProduct()->getId()) {
$this->setChild('simple',
@@ -356,4 +357,16 @@ public function getShowUseDefaultPrice()
return !Mage::helper('Mage_Catalog_Helper_Data')->isPriceGlobal()
&& $this->_getProduct()->getStoreId();
}
+
+ /**
+ * Get list of used attributes
+ *
+ * @return array
+ */
+ public function getSelectedAttributes()
+ {
+ return array_filter(
+ $this->_getProduct()->getTypeInstance()->getUsedProductAttributes($this->_getProduct())
+ );
+ }
}
View
41 app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/Tab/Super/Settings.php
@@ -41,30 +41,17 @@ class Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Super_Settings extends Mage_
protected function _prepareLayout()
{
$onclick = "setSuperSettings('" . $this->getContinueUrl() . "','attribute-checkbox', 'attributes')";
- $this->addChild('continue_button', 'Mage_Adminhtml_Block_Widget_Button', array(
- 'label' => Mage::helper('Mage_Catalog_Helper_Data')->__('Continue'),
- 'onclick' => $onclick,
- 'class' => 'save'
+ $this->addChild('continue_button', 'Mage_Backend_Block_Widget_Button', array(
+ 'label' => Mage::helper('Mage_Catalog_Helper_Data')->__('Continue'),
+ 'onclick' => $onclick,
+ 'class' => 'save',
));
- $backButton = $this->getLayout()->createBlock('Mage_Adminhtml_Block_Widget_Button')
- ->setData(array(
- 'label' => Mage::helper('Mage_Catalog_Helper_Data')->__('Back'),
- 'onclick' => "setLocation('".$this->getBackUrl()."')",
- 'class' => 'back'
- ));
-
- $this->setChild('back_button', $backButton);
-
- $this->setChild('change_attribute_set_button',
- $this->getLayout()->createBlock(
- 'Mage_Adminhtml_Block_Widget_Button',
- $this->getNameInLayout() . '-change-attribute-set'
- )->setData(array(
- 'label' => Mage::helper('Mage_Catalog_Helper_Data')->__('Change Attribute Set'),
- 'onclick' => "jQuery('#attribute-set-info').dialog('open');"
- ))
- );
+ $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();
}
@@ -97,12 +84,8 @@ protected function _prepareForm()
$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>'
- ));
-
- $fieldset->addField('change_attribute_set_button', 'note', array(
- 'text' => $this->getChildHtml('change_attribute_set_button'),
+ . $this->__('Only attributes with scope "Global", input type "Dropdown" and Use To Create Configurable Product "Yes" are available.')
+ . '</li></ul></li></ul>'
));
$hasAttributes = false;
@@ -153,7 +136,7 @@ protected function _prepareForm()
*/
public function getContinueUrl()
{
- return $this->getUrl('*/*/new', array(
+ return $this->getUrl($this->_getProduct()->getId() ? '*/*/edit' : '*/*/new', array(
'_current' => true,
'attributes' => '{{attributes}}'
));
View
6 app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/Tabs.php
@@ -102,12 +102,6 @@ protected function _prepareLayout()
));
}
- $this->addTab('categories', array(
- 'label' => Mage::helper('Mage_Catalog_Helper_Data')->__('Categories'),
- 'url' => $this->getUrl('*/*/categories', array('_current' => true)),
- 'class' => 'ajax',
- ));
-
$this->addTab('related', array(
'label' => Mage::helper('Mage_Catalog_Helper_Data')->__('Related Products'),
'url' => $this->getUrl('*/*/related', array('_current' => true)),
View
179 app/code/core/Mage/Adminhtml/Block/Catalog/Product/Helper/Form/BaseImage.php
@@ -0,0 +1,179 @@
+<?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 Magento Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
+ */
+
+/**
+ * Product form image field helper
+ *
+ * @category Mage
+ * @package Mage_Adminhtml
+ * @author Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Adminhtml_Block_Catalog_Product_Helper_Form_BaseImage extends Varien_Data_Form_Element_Hidden
+{
+ /**
+ * Maximum file size to upload in bytes.
+ *
+ * @var int
+ */
+ protected $_maxFileSize;
+
+ /**
+ * Media Uploader instance
+ *
+ * @var Mage_Adminhtml_Block_Media_Uploader
+ */
+ protected $_mediaUploader;
+
+ /**
+ * Model Url instance
+ *
+ * @var Mage_Backend_Model_Url
+ */
+ protected $_url;
+
+ /**
+ * Media Config instance
+ *
+ * @var Mage_Catalog_Model_Product_Media_Config
+ */
+ protected $_mediaConfig;
+
+ /**
+ * Design Package instance
+ *
+ * @var Mage_Core_Model_Design_Package
+ */
+ protected $_design;
+
+ /**
+ * Data instance
+ *
+ * @var Mage_Core_Helper_Data
+ */
+ protected $_helperData;
+
+ /**
+ * Constructor
+ *
+ * @param array $attributes
+ */
+ public function __construct(array $attributes = array())
+ {
+ parent::__construct($attributes);
+
+ $this->_mediaUploader = isset($attributes['mediaUploader']) ? $attributes['mediaUploader']
+ : Mage::getSingleton('Mage_Adminhtml_Block_Media_Uploader');
+ $this->_url = isset($attributes['url']) ? $attributes['url']
+ : Mage::getModel('Mage_Backend_Model_Url');
+ $this->_mediaConfig = isset($attributes['mediaConfig']) ? $attributes['mediaConfig']
+ : Mage::getSingleton('Mage_Catalog_Model_Product_Media_Config');
+ $this->_design = isset($attributes['design']) ? $attributes['design']
+ : Mage::getSingleton('Mage_Core_Model_Design_Package');
+ $this->_helperData = isset($attributes['helperData']) ? $attributes['helperData']
+ : Mage::helper('Mage_Core_Helper_Data');
+
+ $this->_maxFileSize = $this->_getFileMaxSize();
+ }
+
+ /**
+ * Return element html code
+ *
+ * @return string
+ */
+ public function getElementHtml()
+ {
+ $imageUrl = $this->_helperData->escapeHtml($this->_getImageUrl($this->getValue()));
+ $htmlId = $this->_helperData->escapeHtml($this->getHtmlId());
+ $uploadUrl = $this->_helperData->escapeHtml($this->_getUploadUrl());
+
+ $html = '<input id="' . $htmlId .'_upload" type="file" name="image" '
+ . 'data-url="' . $uploadUrl . '" style="display: none;" />'
+ . parent::getElementHtml()
+ . '<img align="left" src="' . $imageUrl . '" id="' . $htmlId . '_image"'
+ . ' title="' . $imageUrl . '" alt="' . $imageUrl . '" class="base-image-uploader"'
+ . ' onclick="jQuery(\'#' . $htmlId . '_upload\').trigger(\'click\')"/>';
+ $html .= $this->_getJs();
+
+ return $html;
+ }
+
+ /**
+ * Get js for image uploader
+ *
+ * @return string
+ */
+ protected function _getJs()
+ {
+ return "<script>/* <![CDATA[ */"
+ . "jQuery(function(){"
+ . "BaseImageUploader({$this->_helperData->jsonEncode($this->getHtmlId())}, "
+ . "{$this->_helperData->jsonEncode($this->_maxFileSize)});"
+ . " });"
+ . "/*]]>*/</script>";
+ }
+
+ /**
+ * Get full url for image
+ *
+ * @param string $imagePath
+ *
+ * @return string
+ */
+ protected function _getImageUrl($imagePath)
+ {
+ if (!in_array($imagePath, array(null, 'no_selection', '/'))) {
+ if (pathinfo($imagePath, PATHINFO_EXTENSION) == 'tmp') {
+ $imageUrl = $this->_mediaConfig->getTmpMediaUrl(substr($imagePath, 0, -4));
+ } else {
+ $imageUrl = $this->_mediaConfig->getMediaUrl($imagePath);
+ }
+ } else {
+ $imageUrl = $this->_design->getViewFileUrl('Mage_Adminhtml::images/image-placeholder.png');
+ }
+
+ return $imageUrl;
+ }
+
+ /**
+ * Get url to upload files
+ *
+ * @return string
+ */
+ protected function _getUploadUrl()
+ {
+ return $this->_url->getUrl('*/catalog_product_gallery/upload');
+ }
+
+ /**
+ * Get maximum file size to upload in bytes
+ *
+ * @return int
+ */
+ protected function _getFileMaxSize()
+ {
+ return $this->_mediaUploader->getDataMaxSizeInBytes();
+ }
+}
View
116 app/code/core/Mage/Adminhtml/Block/Catalog/Product/Helper/Form/Category.php
@@ -0,0 +1,116 @@
+<?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 Magento Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
+ */
+
+/**
+ * Product form category field helper
+ *
+ * @category Mage
+ * @package Mage_Adminhtml
+ * @author Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Adminhtml_Block_Catalog_Product_Helper_Form_Category extends Varien_Data_Form_Element_Multiselect
+{
+ /**
+ * Get values for select
+ * @return array
+ */
+ public function getValues()
+ {
+ $collection = $this->_getCategoriesCollection();
+ $values = $this->getValue();
+ if (!is_array($values)) {
+ $values = explode(',', $values);
+ }
+ $collection->addAttributeToSelect('name');
+ $collection->addIdFilter($values);
+
+ $options = array();
+
+ foreach ($collection as $category) {
+ $options[] = array(
+ 'label' => $category->getName(),
+ 'value' => $category->getId()
+ );
+ }
+ return $options;
+ }
+
+ /**
+ * Get categories collection
+ * @return Mage_Catalog_Model_Resource_Category_Collection
+ */
+ protected function _getCategoriesCollection()
+ {
+ return Mage::getResourceModel('Mage_Catalog_Model_Resource_Category_Collection');
+ }
+
+ /**
+ * Get html for 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>";
+ }
+
+ /**
+ * Get selector options
+ *
+ * @return array
+ */
+ protected function _getSelectorOptions()
+ {
+ return array(
+ 'url' => $this->_getBackendHelper()->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");
+ }
+
+}
View
20 app/code/core/Mage/Adminhtml/Block/Customer/Edit/Tabs.php
@@ -50,7 +50,8 @@ protected function _beforeToHtml()
if (Mage::registry('current_customer')->getId()) {
$this->addTab('view', array(
'label' => Mage::helper('Mage_Customer_Helper_Data')->__('Customer View'),
- 'content' => $this->getLayout()->createBlock('Mage_Adminhtml_Block_Customer_Edit_Tab_View')->toHtml(),
+ 'content' => $this->getLayout()
+ ->createBlock('Mage_Adminhtml_Block_Customer_Edit_Tab_View')->toHtml(),
'active' => true
));
}
@@ -111,29 +112,18 @@ protected function _beforeToHtml()
}
$this->_updateActiveTab();
+ Magento_Profiler::stop('customer/tabs');
return parent::_beforeToHtml();
}
protected function _updateActiveTab()
{
$tabId = $this->getRequest()->getParam('tab');
- if( $tabId ) {
+ if ($tabId) {
$tabId = preg_replace("#{$this->getId()}_#", '', $tabId);
- if($tabId) {
+ if ($tabId) {
$this->setActiveTab($tabId);
}
}
}
-
- /**
- * Processing block html after rendering
- *
- * @param string $html
- * @return string
- */
- protected function _afterToHtml($html)
- {
- Magento_Profiler::stop('customer/tabs');
- return parent::_afterToHtml($html);
- }
}
View
10 app/code/core/Mage/Adminhtml/controllers/Catalog/CategoryController.php
@@ -503,6 +503,16 @@ public function refreshPathAction()
}
/**
+ * Category list suggestion based on already entered symbols
+ */
+ public function suggestCategoriesAction()
+ {
+ $this->getResponse()->setBody($this->getLayout()->createBlock('Mage_Adminhtml_Block_Catalog_Category_Tree')
+ ->getSuggestedCategoriesJson($this->getRequest()->getParam('name_part'))
+ );
+ }
+
+ /**
* Check if admin has permissions to visit related pages
*
* @return boolean
View
41 app/code/core/Mage/Adminhtml/controllers/Catalog/ProductController.php
@@ -133,8 +133,10 @@ protected function _initProduct()
$product->addData($data)
->setWebsiteIds($configProduct->getWebsiteIds());
}
- if ($product->dataHasChangedFor('attribute_set_id')) {
+
+ if ($setId != $this->_getSession()->getAttributeSetId()) {
$this->_initProductSave($product);
+ $this->_getSession()->setAttributeSetId($setId);
}
Mage::register('product', $product);
@@ -223,7 +225,7 @@ public function newAction()
$this->_setActiveMenu('Mage_Catalog::catalog_products');
}
- $this->getLayout()->getBlock('head')->setCanLoadExtJs(true);
+ $this->getLayout()->getBlock('head')->setCanLoadExtJs(false);
$block = $this->getLayout()->getBlock('catalog.wysiwyg.js');
if ($block) {
@@ -274,7 +276,7 @@ public function editAction()
);
}
- $this->getLayout()->getBlock('head')->setCanLoadExtJs(true);
+ $this->getLayout()->getBlock('head')->setCanLoadExtJs(false);
$block = $this->getLayout()->getBlock('catalog.wysiwyg.js');
if ($block) {
@@ -620,28 +622,23 @@ protected function _initProductSave($product)
*/
$links = $this->getRequest()->getPost('links');
if (isset($links['related']) && !$product->getRelatedReadonly()) {
- $product->setRelatedLinkData(Mage::helper('Mage_Adminhtml_Helper_Js')->decodeGridSerializedInput($links['related']));
+ $product->setRelatedLinkData(
+ Mage::helper('Mage_Adminhtml_Helper_Js')->decodeGridSerializedInput($links['related'])
+ );
}
if (isset($links['upsell']) && !$product->getUpsellReadonly()) {
- $product->setUpSellLinkData(Mage::helper('Mage_Adminhtml_Helper_Js')->decodeGridSerializedInput($links['upsell']));
+ $product->setUpSellLinkData(
+ Mage::helper('Mage_Adminhtml_Helper_Js')->decodeGridSerializedInput($links['upsell'])
+ );
}
if (isset($links['crosssell']) && !$product->getCrosssellReadonly()) {
$product->setCrossSellLinkData(Mage::helper('Mage_Adminhtml_Helper_Js')
->decodeGridSerializedInput($links['crosssell']));
}
if (isset($links['grouped']) && !$product->getGroupedReadonly()) {
- $product->setGroupedLinkData(Mage::helper('Mage_Adminhtml_Helper_Js')->decodeGridSerializedInput($links['grouped']));
- }
-
- /**
- * Initialize product categories
- */
- $categoryIds = $this->getRequest()->getPost('category_ids');
- if (null !== $categoryIds) {
- if (empty($categoryIds)) {
- $categoryIds = array();
- }
- $product->setCategoryIds($categoryIds);
+ $product->setGroupedLinkData(
+ Mage::helper('Mage_Adminhtml_Helper_Js')->decodeGridSerializedInput($links['grouped'])
+ );
}
/**
@@ -703,16 +700,6 @@ protected function _filterStockData(&$stockData) {
}
}
- public function categoriesJsonAction()
- {
- $product = $this->_initProduct();
-
- $this->getResponse()->setBody(
- $this->getLayout()->createBlock('Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Categories')
- ->getCategoryChildrenJson($this->getRequest()->getParam('category'))
- );
- }
-
/**
* Save product action
*/
View
28 app/code/core/Mage/Adminhtml/view/adminhtml/catalog.xml
@@ -51,14 +51,17 @@
<action method="addJs"><file>mage/jquery-no-conflict.js</file></action>
<action method="addJs"><file>jquery/jquery-ui-1.8.18.custom.min.js</file></action>
<action method="addCss"><file>Mage_Adminhtml::css/ui-lightness/jquery-ui-1.8.21.custom.css</file></action>
-
<action method="addCss"><file>Mage_Adminhtml::jquery/fileUploader/css/jquery.fileupload-ui.css</file></action>
<action method="addJs"><file>Mage_Adminhtml::jquery/fileUploader/vendor/jquery.ui.widget.js</file></action>
<action method="addJs"><file>Mage_Adminhtml::jquery/fileUploader/jquery.iframe-transport.js</file></action>
<action method="addJs"><file>Mage_Adminhtml::jquery/fileUploader/jquery.fileupload.js</file></action>
<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>
</reference>
<reference name="content">
<block type="Mage_Adminhtml_Block_Catalog_Product_Edit" name="product_edit"></block>
@@ -81,14 +84,17 @@
<action method="addJs"><file>mage/jquery-no-conflict.js</file></action>
<action method="addJs"><file>jquery/jquery-ui-1.8.18.custom.min.js</file></action>
<action method="addCss"><file>Mage_Adminhtml::css/ui-lightness/jquery-ui-1.8.21.custom.css</file></action>
-
<action method="addCss"><file>Mage_Adminhtml::jquery/fileUploader/css/jquery.fileupload-ui.css</file></action>
<action method="addJs"><file>Mage_Adminhtml::jquery/fileUploader/vendor/jquery.ui.widget.js</file></action>
<action method="addJs"><file>Mage_Adminhtml::jquery/fileUploader/jquery.iframe-transport.js</file></action>
<action method="addJs"><file>Mage_Adminhtml::jquery/fileUploader/jquery.fileupload.js</file></action>
<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>
</reference>
<reference name="content">
<block type="Mage_Adminhtml_Block_Catalog_Product_Edit" name="product_edit"></block>
@@ -105,12 +111,6 @@
</reference>
</adminhtml_catalog_product_edit>
- <adminhtml_catalog_product_categories>
- <container name="root" label="Root" output="1">
- <block type="Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Categories" name="catalog.product.edit.tab.categories"/>
- </container>
- </adminhtml_catalog_product_categories>
-
<adminhtml_catalog_product_reviews>
<container name="root" label="Root" output="1">
<block type="Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Reviews" name="admin.product.reviews"/>
@@ -261,9 +261,15 @@ Layout handle for configurable products
-->
<adminhtml_catalog_product_configurable_new>
- <remove name="product_tabs"/>
- <reference name="left">
- <block type="Mage_Adminhtml_Block_Catalog_Product_Edit_Tabs_Configurable" name="configurable_product_tabs"/>
+ <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>
</reference>
</adminhtml_catalog_product_configurable_new>
View
BIN app/code/core/Mage/Adminhtml/view/adminhtml/catalog/images/select2.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN app/code/core/Mage/Adminhtml/view/adminhtml/catalog/images/select2x2.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN app/code/core/Mage/Adminhtml/view/adminhtml/catalog/images/spinner.gif
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
28 app/code/core/Mage/Adminhtml/view/adminhtml/catalog/jquery.base-image-uploader.css
@@ -0,0 +1,28 @@
+/**
+ * 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_Catalog
+ * @package
+ * @copyright Copyright (c) 2012 Magento 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;
+}
View
57 app/code/core/Mage/Adminhtml/view/adminhtml/catalog/jquery.base-image-uploader.js
@@ -0,0 +1,57 @@
+/**
+ * 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 js
+ * @copyright Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
+ */
+function BaseImageUploader(id, maxFileSize) {
+ (function ($) {
+ $('#' + id + '_upload').fileupload({
+ dataType: 'json',
+ dropZone: '#' + id + '_image',
+ acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i,
+ maxFileSize: maxFileSize,
+ done: function (e, data) {
+ if (!data.result) {
+ return;
+ }
+ if (!data.result.error) {
+ $('#' + id + '_image').attr({src: data.result.url,
+ title: data.result.url,
+ alt: data.result.url});
+ $('#' + id).val(data.result.file);
+ if (typeof media_gallery_contentJsObject != 'undefined') {
+ media_gallery_contentJsObject.handleUploadComplete(data.result);
+ media_gallery_contentJsObject.imagesValues.image = data.result.file;
+ media_gallery_contentJsObject.updateImages();
+ }
+ } else {
+ alert(jQuery.mage.__('File extension not known or unsupported type.'));
+ }
+ },
+ add: function(e, data) {
+ $(this).fileupload('process', data).done(function () {
+ data.submit();
+ });
+ }
+ });
+ })(jQuery);
+}
View
585 app/code/core/Mage/Adminhtml/view/adminhtml/catalog/jquery.category-selector.css
@@ -0,0 +1,585 @@
+/**
+ * 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_Cat
+ * @package
+ * @copyright Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
+ */
+.category-selector-container {
+ position:relative;
+ display:inline-block;
+ vertical-align:top;
+ width:99%;
+}
+
+.category-selector-container,
+.category-selector-drop,
+.category-selector-search,
+.category-selector-search input {
+ -moz-box-sizing:border-box;
+ -ms-box-sizing:border-box;
+ -webkit-box-sizing:border-box;
+ -khtml-box-sizing:border-box;
+ box-sizing:border-box;
+}
+
+.category-selector-container .category-selector-choice {
+ background-color:#fff;
+ background-image:-webkit-gradient(linear, left bottom, left top, color-stop(0, #eeeeee), color-stop(0.5, white));
+ background-image:-webkit-linear-gradient(center bottom, #eeeeee 0%, white 50%);
+ background-image:-moz-linear-gradient(center bottom, #eeeeee 0%, white 50%);
+ background-image:-o-linear-gradient(bottom, #eeeeee 0%, #ffffff 50%);
+ background-image:-ms-linear-gradient(top, #eeeeee 0%, #ffffff 50%);
+ background-image:linear-gradient(top, #eeeeee 0%, #ffffff 50%);
+ border-radius:4px;
+ background-clip:padding-box;
+ border:1px solid #aaa;
+ display:block;
+ overflow:hidden;
+ white-space:nowrap;
+ position:relative;
+ height:26px;
+ line-height:26px;
+ padding:0 0 0 8px;
+ color:#444;
+ text-decoration:none;
+}
+
+.category-selector-container.category-selector-drop-above .category-selector-choice {
+ border-bottom-color:#aaa;
+ border-radius:0px 0px 4px 4px;
+ background-image:-webkit-gradient(linear, left bottom, left top, color-stop(0, #eeeeee), color-stop(0.9, white));
+ background-image:-webkit-linear-gradient(center bottom, #eeeeee 0%, white 90%);
+ background-image:-moz-linear-gradient(center bottom, #eeeeee 0%, white 90%);
+ background-image:-o-linear-gradient(bottom, #eeeeee 0%, white 90%);
+ background-image:-ms-linear-gradient(top, #eeeeee 0%, #ffffff 90%);
+ background-image:linear-gradient(top, #eeeeee 0%, #ffffff 90%);
+}
+
+.category-selector-container .category-selector-choice span {
+ margin-right:26px;
+ display:block;
+ overflow:hidden;
+ white-space:nowrap;
+ -o-text-overflow:ellipsis;
+ -ms-text-overflow:ellipsis;
+ text-overflow:ellipsis;
+}
+
+.category-selector-container .category-selector-choice abbr {
+ display:block;
+ position:absolute;
+ right:26px;
+ top:8px;
+ width:12px;
+ height:12px;
+ font-size:1px;
+ background:url('images/select2.png') right top no-repeat;
+ cursor:pointer;
+ text-decoration:none;
+ border:0;
+ outline:0;
+}
+.category-selector-container .category-selector-choice abbr:hover {
+ background-position:right -11px;
+ cursor:pointer;
+}
+
+.category-selector-drop {
+ background:#fff;
+ color:#000;
+ border:1px solid #ccc;
+ border-top:0;
+ position:absolute;
+ top:100%;
+ box-shadow: 0 3px 6px rgba(0, 0, 0, 0.2);
+ z-index:9999;
+ width:100%;
+ margin-top:-3px;
+ border-radius:0 0 3px 3px;
+}
+
+.category-selector-drop.category-selector-drop-above {
+ border-radius:3px 3px 0 0;
+ margin-top:3px;
+ border-top:1px solid #ccc;
+ border-bottom:0;
+ box-shadow: 0 -3px 6px rgba(0, 0, 0, 0.2);
+}
+
+.category-selector-container .category-selector-choice div {
+ border-radius:0 4px 4px 0;
+ background-clip:padding-box;
+ background:#ccc;
+ background-image:-webkit-gradient(linear, left bottom, left top, color-stop(0, #ccc), color-stop(0.6, #eee));
+ background-image:-webkit-linear-gradient(center bottom, #ccc 0%, #eee 60%);
+ background-image:-moz-linear-gradient(center bottom, #ccc 0%, #eee 60%);
+ background-image:-o-linear-gradient(bottom, #ccc 0%, #eee 60%);
+ background-image:-ms-linear-gradient(top, #cccccc 0%, #eeeeee 60%);
+ background-image:linear-gradient(top, #cccccc 0%, #eeeeee 60%);
+ border-left:1px solid #aaa;
+ position:absolute;
+ right:0;
+ top:0;
+ display:block;
+ height:100%;
+ width:18px;
+}
+
+.category-selector-container .category-selector-choice div b {
+ background:url('images/select2.png') no-repeat 0 1px;
+ display:block;
+ width:100%;
+ height:100%;
+}
+
+.category-selector-search {
+ display:inline-block;
+ white-space:nowrap;
+ z-index:10000;
+ min-height:26px;
+ width:100%;
+ margin:0;
+ padding-left:4px;
+ padding-right:4px;
+}
+
+.category-selector-search-hidden {
+ display:block;
+ position:absolute;
+ left:-10000px;
+}
+
+.category-selector-search input {
+ background:#fff url('images/select2.png') no-repeat 100% -22px;
+ background:url('images/select2.png') no-repeat 100% -22px, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, white), color-stop(0.99, #eeeeee));
+ background:url('images/select2.png') no-repeat 100% -22px, -webkit-linear-gradient(center bottom, white 85%, #eeeeee 99%);
+ background:url('images/select2.png') no-repeat 100% -22px, -moz-linear-gradient(center bottom, white 85%, #eeeeee 99%);
+ background:url('images/select2.png') no-repeat 100% -22px, -o-linear-gradient(bottom, white 85%, #eeeeee 99%);
+ background:url('images/select2.png') no-repeat 100% -22px, -ms-linear-gradient(top, #ffffff 85%, #eeeeee 99%);
+ background:url('images/select2.png') no-repeat 100% -22px, linear-gradient(top, #ffffff 85%, #eeeeee 99%);
+ padding:4px 20px 4px 5px;
+ outline:0;
+ border:1px solid #aaa;
+ font-family:sans-serif;
+ font-size:1em;
+ width:100%;
+ margin:0;
+ height:auto !important;
+ min-height:26px;
+ box-shadow:none;
+ border-radius:0;
+}
+
+.category-selector-drop.category-selector-drop-above .category-selector-search input {
+ margin-top:4px;
+}
+
+.category-selector-search input.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%);
+ background:url('images/spinner.gif') no-repeat 100%, -moz-linear-gradient(center bottom, white 85%, #eeeeee 99%);
+ background:url('images/spinner.gif') no-repeat 100%, -o-linear-gradient(bottom, white 85%, #eeeeee 99%);
+ background:url('images/spinner.gif') no-repeat 100%, -ms-linear-gradient(top, #ffffff 85%, #eeeeee 99%);
+ background:url('images/spinner.gif') no-repeat 100%, linear-gradient(top, #ffffff 85%, #eeeeee 99%);
+}
+
+.category-selector-container-active .category-selector-choice,
+.category-selector-container-active .category-selector-choices {
+ box-shadow:0 0 5px rgba(0, 0, 0, .3);
+ border:1px solid #74B9EF;
+ outline:none;
+}
+
+.category-selector-dropdown-open .category-selector-choice {
+ border:1px solid #aaa;
+ border-bottom-color:transparent;
+ box-shadow:0 1px 0 #fff inset;
+ background-color:#eee;
+ background-image:-webkit-gradient(linear, left bottom, left top, color-stop(0, white), color-stop(0.5, #eeeeee));
+ background-image:-webkit-linear-gradient(center bottom, white 0%, #eeeeee 50%);
+ background-image:-moz-linear-gradient(center bottom, white 0%, #eeeeee 50%);
+ background-image:-o-linear-gradient(bottom, white 0%, #eeeeee 50%);
+ background-image:-ms-linear-gradient(top, #ffffff 0%, #eeeeee 50%);
+ background-image:linear-gradient(top, #ffffff 0%, #eeeeee 50%);
+ -webkit-border-bottom-left-radius:0;
+ -webkit-border-bottom-right-radius:0;
+ -moz-border-radius-bottomleft:0;
+ -moz-border-radius-bottomright:0;
+ border-bottom-left-radius:0;
+ border-bottom-right-radius:0;
+}
+
+.category-selector-dropdown-open .category-selector-choice div {
+ background:transparent;
+ border-left:none;
+}
+.category-selector-dropdown-open .category-selector-choice div b {
+ background-position:-18px 1px;
+}
+
+/* results */
+.category-selector-results {
+ margin:4px 4px 4px 0;
+ padding:0 0 0 4px;
+ position:relative;
+ overflow-x:hidden;
+ overflow-y:auto;
+ max-height:200px;
+}
+
+.category-selector-results ul.category-selector-result-sub {
+ margin:0;
+ padding:0;
+}
+
+.category-selector-results ul.category-selector-result-sub > li .category-selector-result-label { padding-left:20px }
+.category-selector-results ul.category-selector-result-sub ul.category-selector-result-sub > li .category-selector-result-label { padding-left:40px }
+.category-selector-results ul.category-selector-result-sub ul.category-selector-result-sub ul.category-selector-result-sub > li .category-selector-result-label { padding-left:60px }
+.category-selector-results ul.category-selector-result-sub ul.category-selector-result-sub ul.category-selector-result-sub ul.category-selector-result-sub > li .category-selector-result-label { padding-left:80px }
+.category-selector-results ul.category-selector-result-sub ul.category-selector-result-sub ul.category-selector-result-sub ul.category-selector-result-sub ul.category-selector-result-sub > li .category-selector-result-label { padding-left:100px }
+.category-selector-results ul.category-selector-result-sub ul.category-selector-result-sub ul.category-selector-result-sub ul.category-selector-result-sub ul.category-selector-result-sub ul.category-selector-result-sub > li .category-selector-result-label { padding-left:110px }
+.category-selector-results ul.category-selector-result-sub ul.category-selector-result-sub ul.category-selector-result-sub ul.category-selector-result-sub ul.category-selector-result-sub ul.category-selector-result-sub ul.category-selector-result-sub > li .category-selector-result-label { padding-left:120px }
+
+.category-selector-results li {
+ list-style:none;
+ display:list-item;
+}
+
+.category-selector-results li.category-selector-result-with-children > .category-selector-result-label {
+ font-weight:bold;
+}
+
+.category-selector-results .category-selector-result-label {
+ padding:3px 7px 4px;
+ margin:0;
+ cursor:pointer;
+}
+
+.category-selector-results .category-selector-highlighted {
+ background:#3875d7;
+ color:#fff;
+}
+.category-selector-results li em {
+ background:#feffde;
+ font-style:normal;
+}
+.category-selector-results .category-selector-highlighted em {
+ background:transparent;
+}
+.category-selector-results .category-selector-no-results {
+ padding:3px;
+}
+.category-selector-results .category-selector-no-results,
+.category-selector-results .category-selector-searching,
+.category-selector-results .category-selector-selection-limit {
+ background:#f4f4f4;
+ display:list-item;
+}
+.category-selector-results .category-selector-disabled {
+ display:none;
+}
+.category-selector-more-results.category-selector-active {
+ background:#f4f4f4 url('images/spinner.gif') no-repeat 100%;
+}
+
+.category-selector-more-results {
+ background:#f4f4f4;
+ display:list-item;
+}
+
+/* disabled styles */
+.category-selector-container.category-selector-container-disabled .category-selector-choice {
+ background-color:#f4f4f4;
+ background-image:none;
+ border:1px solid #ddd;
+ cursor:default;
+}
+
+.category-selector-container.category-selector-container-disabled .category-selector-choice div {
+ background-color:#f4f4f4;
+ background-image:none;
+ border-left:0;
+}
+
+/* multiselect */
+
+.category-selector-container-multi .category-selector-choices {
+ background-color:#fff;
+ border:1px solid #ccc;
+ margin:0;
+ padding:0;
+ cursor:text;
+ overflow:hidden;
+ min-height:28px;
+ position:relative;
+ box-sizing:border-box;
+ border-radius:3px;
+ box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ -webkit-transition:border linear 0.2s, box-shadow linear 0.2s;
+ -moz-transition:border linear 0.2s, box-shadow linear 0.2s;
+ -ms-transition:border linear 0.2s, box-shadow linear 0.2s;
+ -o-transition:border linear 0.2s, box-shadow linear 0.2s;
+ transition:border linear 0.2s, box-shadow linear 0.2s;
+}
+
+.category-selector-container-multi.category-selector-container-active .category-selector-choices {
+ box-shadow:0 0 5px rgba(0, 0, 0, .3);
+ border:1px solid #74B9EF;
+ outline:none;
+}
+.category-selector-container-multi .category-selector-choices li {
+ float:left;
+ list-style:none;
+}
+.category-selector-container-multi .category-selector-choices .category-selector-search-field {
+ white-space:nowrap;
+ margin:0;
+ padding:0;
+}
+
+.category-selector-container-multi .category-selector-choices .category-selector-search-field input {
+ color:#666;
+ background:transparent !important;
+ font-family:sans-serif;
+ font-size:100%;
+ height:22px;
+ padding:5px;
+ margin:1px 0;
+ outline:0;
+ border:0;
+ box-shadow:none;
+}
+
+.category-selector-container-multi .category-selector-choices .category-selector-search-field input.category-selector-active {
+ background:#fff url('images/spinner.gif') no-repeat 100% !important;
+}
+
+.category-selector-default {
+ color:#999 !important;
+}
+
+.category-selector-container-multi .category-selector-choices .category-selector-search-choice {
+ margin:3px 0 3px 5px;
+ padding-left:15px;
+ position:relative;
+ cursor:default;
+}
+.category-selector-container-multi .category-selector-choices .category-selector-search-choice span {
+ cursor:default;
+}
+.category-selector-container-multi .category-selector-choices .category-selector-search-choice-focus {
+ background:#d4d4d4;
+}
+
+.category-selector-search-choice-close {
+ display:block;
+ position:absolute;
+ right:3px;
+ top:4px;
+ width:12px;
+ height:13px;
+ font-size:1px;
+ background:url('images/select2.png') right top no-repeat;
+ outline:none;
+}
+
+.category-selector-container-multi .category-selector-search-choice-close {
+ left:3px;
+ top:7px;
+}
+
+.category-selector-container-multi .category-selector-choices .category-selector-search-choice .category-selector-search-choice-close:hover {
+ background-position:right -11px;
+}
+.category-selector-container-multi .category-selector-choices .category-selector-search-choice-focus .category-selector-search-choice-close {
+ background-position:right -11px;
+}
+
+/* disabled styles */
+
+.category-selector-container-multi.category-selector-container-disabled .category-selector-choices {
+ background-color:#f4f4f4;
+ background-image:none;
+ border:1px solid #ddd;
+ cursor:default;
+}
+
+.category-selector-container-multi.category-selector-container-disabled .category-selector-choices .category-selector-search-choice {
+ background-image:none;
+ background-color:#f4f4f4;
+ border:1px solid #ddd;
+ padding:3px 5px 3px 5px;
+}
+
+.category-disabled a{
+ color: #808080;
+}
+
+.category-selected a{
+ background-color: #0000ff;
+ color: #FFF;
+}
+.category-selector-container-multi.category-selector-container-disabled .category-selector-choices .category-selector-search-choice .category-selector-search-choice-close {
+ display:none;
+}
+/* end multiselect */
+
+.category-selector-result-selectable .category-selector-match,
+.category-selector-result-unselectable .category-selector-result-selectable .category-selector-match {
+ text-decoration:underline;
+}
+.category-selector-result-unselectable .category-selector-match {
+ text-decoration:none;
+}
+
+.category-selector-offscreen {
+ position:absolute; left:-10000px;
+}
+
+.category-selector-results li {
+ margin-bottom:1px;
+}
+
+.parent {
+ font-weight:bold;
+}
+.parent.level-1 {
+ margin-left:0;
+}
+.level-1,
+.parent.level-2 {
+ margin-left:15px;
+}
+.level-2,
+.parent.level-3 {
+ margin-left:25px;
+}
+.level-3,
+.parent.level-4 {
+ margin-left:35px;
+}
+.level-4,
+.parent.level-5{
+ margin-left:45px;
+}
+.level-5 {
+ margin-left:55px;
+}
+
+/* Retina-ize icons */
+@media only screen and (-webkit-min-device-pixel-ratio: 1.5) {
+ .category-selector-search input,
+ .category-selector-search-choice-close,
+ .category-selector-container .category-selector-choice abbr,
+ .category-selector-container .category-selector-choice div b {
+ background-image:url(images/select2x2.png) !important;
+ background-repeat:no-repeat !important;
+ background-size:60px 40px !important;
+ }
+ .category-selector-search input {
+ background-position:100% -21px !important;
+ }
+}
+
+/* TODO: remove after Magento User Interface framework integration */
+/* =============================================================================
+ Buttons
+ ========================================================================== */
+.button {
+ position:relative;
+ display: inline-block;
+ padding: 4px 10px;
+ margin-bottom: 0;
+ font-size: 13px;
+ line-height: 18px;
+ color: #333;
+ text-align: center;
+ text-decoration:none;
+ text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75);
+ vertical-align: middle;
+ cursor: pointer;
+ background: #ffffff;
+ background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNlNmU2ZTYiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+);
+ background: -moz-linear-gradient(top, #ffffff 0%, #e6e6e6 100%);
+ background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#ffffff), color-stop(100%,#e6e6e6));
+ background: -webkit-linear-gradient(top, #ffffff 0%,#e6e6e6 100%);
+ background: -o-linear-gradient(top, #ffffff 0%,#e6e6e6 100%);
+ background: -ms-linear-gradient(top, #ffffff 0%,#e6e6e6 100%);
+ background: linear-gradient(to bottom, #ffffff 0%,#e6e6e6 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#e6e6e6',GradientType=0 );
+ border: 1px solid #ccc;
+ border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
+ border-radius: 4px;
+ -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
+ -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
+ -webkit-touch-callout: none;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+}
+.ie9 .button {
+ padding-top:5px;
+ padding-bottom:3px;
+ filter:none;
+}
+
+.button:hover {
+ color: #333;
+ text-decoration: none;
+ background: #f9f9f9;
+ background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2Y5ZjlmOSIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNlNmU2ZTYiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+);
+ background: -moz-linear-gradient(top, #f9f9f9 0%, #e6e6e6 100%);
+ background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f9f9f9), color-stop(100%,#e6e6e6));
+ background: -webkit-linear-gradient(top, #f9f9f9 0%,#e6e6e6 100%);
+ background: -o-linear-gradient(top, #f9f9f9 0%,#e6e6e6 100%);
+ background: -ms-linear-gradient(top, #f9f9f9 0%,#e6e6e6 100%);
+ background: linear-gradient(to bottom, #f9f9f9 0%,#e6e6e6 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f9f9f9', endColorstr='#e6e6e6',GradientType=0 );
+}
+.button:focus {
+ outline: thin dotted #333;
+ outline: 5px auto -webkit-focus-ring-color;
+ outline-offset: -2px;
+}
+.button:active
+.button.active {
+ background-color: #e6e6e6;
+ background-image: none;
+ outline: 0;
+ -webkit-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
+ -moz-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
+ box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
+}
+.button[disabled] {
+ cursor: not-allowed;
+ background-color: #e6e6e6;
+ background-image: none;
+ opacity: 0.65;
+ -webkit-box-shadow: none;
+ -moz-box-shadow: none;
+ box-shadow: none;
+}
+.button:visited {
+ color:#333;
+}
View
142 app/code/core/Mage/Adminhtml/view/adminhtml/catalog/jquery.category-selector.js
@@ -0,0 +1,142 @@
+/**
+ * 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 js
+ * @copyright Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
+ */
+(function ($, undefined) {
+ "use strict";
+ 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;
+ };
+ $.fn.categorySelector = function (options) {
+ this.each(function () {
+ var $element = $(
+ '<div class="category-selector-container category-selector-container-multi">' +
+ '<ul class="category-selector-choices">' +
+ '<li class="category-selector-search-field">' +
+ '<input type="text" autocomplete="off" ' +
+ 'data-ui-id="category-selector-input" class="category-selector-input">' +
+ '</li></ul></div>'
+ ),
+ $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) + ']';
+