├── README.md ├── app ├── code │ └── community │ │ └── TheExtensionLab │ │ └── MegaMenu │ │ ├── Block │ │ ├── Adminhtml │ │ │ ├── Attribute │ │ │ │ ├── Chooser.php │ │ │ │ └── Option │ │ │ │ │ └── Chooser.php │ │ │ ├── Catalog │ │ │ │ ├── Category │ │ │ │ │ └── Widget │ │ │ │ │ │ ├── Chooser.php │ │ │ │ │ │ └── Draggable │ │ │ │ │ │ └── Chooser.php │ │ │ │ └── Product │ │ │ │ │ └── Widget │ │ │ │ │ └── Chooser.php │ │ │ └── System │ │ │ │ └── Config │ │ │ │ └── Extension.php │ │ ├── Page │ │ │ └── Html │ │ │ │ └── Topmenu │ │ │ │ └── Renderer.php │ │ └── Widget │ │ │ ├── Attribute │ │ │ └── List.php │ │ │ ├── Category │ │ │ ├── Featured.php │ │ │ └── List.php │ │ │ ├── Cms │ │ │ ├── Block.php │ │ │ └── Page │ │ │ │ └── Featured.php │ │ │ ├── Product │ │ │ └── Featured.php │ │ │ └── Template.php │ │ ├── Helper │ │ ├── Attribute │ │ │ └── Url.php │ │ ├── Category.php │ │ ├── Category │ │ │ └── Url.php │ │ ├── Column │ │ │ └── Types.php │ │ ├── Data.php │ │ └── Display │ │ │ └── Styles.php │ │ ├── Model │ │ ├── Config │ │ │ ├── Dependancy.php │ │ │ └── Source │ │ │ │ ├── Abstract.php │ │ │ │ ├── Columns.php │ │ │ │ ├── Display.php │ │ │ │ ├── Dropdown │ │ │ │ └── Type.php │ │ │ │ ├── Interface.php │ │ │ │ ├── Link │ │ │ │ └── Type.php │ │ │ │ └── List │ │ │ │ └── Columns.php │ │ ├── Menu │ │ │ ├── Attributes.php │ │ │ └── Populator.php │ │ ├── Observer.php │ │ ├── Parser.php │ │ ├── Parser │ │ │ ├── Attribute │ │ │ │ └── Option.php │ │ │ ├── Cms │ │ │ │ ├── Block.php │ │ │ │ └── Page │ │ │ │ │ └── Featured.php │ │ │ ├── Interface.php │ │ │ ├── Product │ │ │ │ └── Featured.php │ │ │ └── Url │ │ │ │ └── Rewrite.php │ │ ├── Prefetcher.php │ │ ├── Prefetcher │ │ │ ├── Attribute.php │ │ │ ├── Attribute │ │ │ │ └── Option.php │ │ │ ├── Cms │ │ │ │ ├── Block.php │ │ │ │ └── Page.php │ │ │ ├── Interface.php │ │ │ ├── Product.php │ │ │ └── Url │ │ │ │ └── Rewrite.php │ │ ├── Resource │ │ │ ├── Category │ │ │ │ └── Flat.php │ │ │ └── Setup.php │ │ └── Template │ │ │ └── Filter.php │ │ ├── Test │ │ ├── Block │ │ │ └── Widget │ │ │ │ └── Cms │ │ │ │ └── Page │ │ │ │ └── Featured.php │ │ ├── Config │ │ │ └── Main.php │ │ ├── Model │ │ │ ├── Menu │ │ │ │ ├── Attributes.php │ │ │ │ ├── CategoryCollectionMock.php │ │ │ │ ├── DbAdapterMock.php │ │ │ │ └── fixtures │ │ │ │ │ └── testAttributesConfigGetter.yaml │ │ │ ├── Parser.php │ │ │ ├── Parser │ │ │ │ └── Cms │ │ │ │ │ └── Page │ │ │ │ │ └── Featured.php │ │ │ ├── Prefetcher.php │ │ │ ├── Prefetcher │ │ │ │ └── Cms │ │ │ │ │ └── Page.php │ │ │ └── Resource │ │ │ │ └── Setup.php │ │ └── controller │ │ │ └── Adminhtml │ │ │ └── Cms │ │ │ └── PageController.php │ │ ├── controllers │ │ └── Adminhtml │ │ │ └── Menu │ │ │ ├── Attribute │ │ │ ├── Option │ │ │ │ └── WidgetController.php │ │ │ └── WidgetController.php │ │ │ └── Catalog │ │ │ ├── Category │ │ │ ├── Draggable │ │ │ │ └── WidgetController.php │ │ │ └── WidgetController.php │ │ │ └── Product │ │ │ └── WidgetController.php │ │ ├── data │ │ └── theextensionlab_megamenu_setup │ │ │ └── data-install-1.0.0.php │ │ ├── etc │ │ ├── config.xml │ │ ├── system.xml │ │ └── widget.xml │ │ └── sql │ │ └── theextensionlab_megamenu_setup │ │ ├── install-1.0.0.php │ │ └── upgrade-1.0.0-1.5.3.php ├── design │ ├── adminhtml │ │ └── default │ │ │ └── default │ │ │ ├── layout │ │ │ └── theextensionlab │ │ │ │ └── megamenu.xml │ │ │ └── template │ │ │ └── theextensionlab │ │ │ └── megamenu │ │ │ ├── system │ │ │ └── config │ │ │ │ └── extension-info.phtml │ │ │ └── widget │ │ │ ├── catalog │ │ │ └── category │ │ │ │ └── tree.phtml │ │ │ └── grid │ │ │ └── json │ │ │ └── serializer.phtml │ └── frontend │ │ └── base │ │ └── default │ │ ├── layout │ │ └── theextensionlab │ │ │ └── megamenu.xml │ │ └── template │ │ └── theextensionlab │ │ └── megamenu │ │ ├── attributes │ │ ├── li-only-list.phtml │ │ └── list.phtml │ │ ├── categories │ │ ├── featured.phtml │ │ ├── li-only-list.phtml │ │ └── list.phtml │ │ ├── cms │ │ ├── block.phtml │ │ └── page │ │ │ └── featured.phtml │ │ ├── page │ │ └── html │ │ │ ├── topmenu.phtml │ │ │ └── topmenu │ │ │ └── renderer.phtml │ │ └── products │ │ ├── featured-secondary.phtml │ │ └── featured.phtml ├── etc │ └── modules │ │ └── TheExtensionLab_MegaMenu.xml └── locale │ ├── de_DE │ └── TheExtensionLab_MegaMenu.csv │ └── en_US │ └── TheExtensionLab_MegaMenu.csv ├── composer.json ├── js └── theextensionlab │ └── megamenu │ ├── adminhtml │ └── grid │ │ └── json │ │ └── serializer.js │ └── wysiwyg │ └── widget.js ├── modman └── skin ├── adminhtml └── default │ └── default │ └── theextensionlab │ └── megamenu │ └── css │ └── widget │ └── draggable.css └── frontend ├── base └── default │ ├── css │ └── theextensionlab │ │ └── megamenu │ │ ├── grid.css │ │ ├── main.css │ │ ├── responsive.css │ │ └── theme-specific.css │ ├── js │ └── theextensionlab │ │ └── megamenu │ │ ├── menu-bp.js │ │ └── menu.js │ └── scss │ └── theextensionlab │ └── megamenu │ ├── _settings.scss │ ├── grid.scss │ ├── main.scss │ ├── mixins │ ├── _grid.scss │ └── _main.scss │ └── responsive.scss └── default └── default └── css └── theextensionlab └── megamenu └── theme-specific.css /README.md: -------------------------------------------------------------------------------- 1 | TheExtensionLab MegaMenu 2 | ------------------------ 3 | 4 | [![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://paypal.me/JamesAnelay) 5 | 6 | This is a free extension - if it saves you time feel free to buy me a beer :) 7 | 8 | Adds a easy to manage, fast mega menu dropdown to Magento. 9 | 10 | License 11 | ------- 12 | @license Open Software License (OSL 3.0 13 | 14 | Installation & Configuration 15 | ------------------ 16 | For up to date installation & configuration instructions please check out the documentation at 17 | [http://docs.theextensionlab.com/mega-menu/installation.html](http://docs.theextensionlab.com/mega-menu/installation.html) 18 | 19 | Extension Overview 20 | ------------------ 21 | Modman: Yes (However this extension has other Magento Extension dependencies composer is therefore the recommend installation option) 22 | 23 | Composer: Yes 24 | 25 | GitHub: Public :) 26 | 27 | Core Hacks: 0 28 | 29 | Class Rewrites: 0 30 | 31 | Avaliable Add-Ons 32 | ----------------- 33 | - https://github.com/TheExtensionLab/MegaMenuBubbleLayerCompat (Makes MegaMenu shop by attribute use the bubbleshop layered nav url structure in links) 34 | - https://github.com/TheExtensionLab/MegaMenuCatalinSeoCompatability (Makes MegaMenu shop by attribute use the catalin seo url structure in links) 35 | - https://github.com/TheExtensionLab/MegaMenuWordpressPostsWidget (Adds widget to add Wordpress/Fishpig post to MegaMenu by ID) 36 | 37 | Developer 38 | -------------- 39 | James Anelay - TheExtensionLab 40 | 41 | [http://www.theextensionlab.com](http://www.theextensionlab.com) 42 | 43 | [@JamesAnelay](https://twitter.com/jamesanelay) - [@TheExtensionLab](https://twitter.com/TheExtensionLab) 44 | 45 | 46 | Copyright 47 | --------- 48 | (c) TheExtensionLab 49 | -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/Block/Adminhtml/Attribute/Chooser.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | 11 | class TheExtensionLab_MegaMenu_Block_Adminhtml_Attribute_Chooser extends 12 | Mage_Adminhtml_Block_Widget_Grid 13 | { 14 | public function __construct($arguments = array()) 15 | { 16 | parent::__construct($arguments); 17 | $this->setUseAjax(true); 18 | 19 | } 20 | 21 | public function prepareElementHtml(Varien_Data_Form_Element_Abstract $element) 22 | { 23 | $uniqId = Mage::helper('core')->uniqHash($element->getId()); 24 | $sourceUrl = $this->getUrl('*/menu_attribute_widget/chooser', array('uniq_id' => $uniqId)); 25 | 26 | $chooser = $this->getLayout()->createBlock('widget/adminhtml_widget_chooser') 27 | ->setElement($element) 28 | ->setTranslationHelper($this->getTranslationHelper()) 29 | ->setConfig($this->getConfig()) 30 | ->setFieldsetId($this->getFieldsetId()) 31 | ->setSourceUrl($sourceUrl) 32 | ->setUniqId($uniqId); 33 | 34 | if($element->hasValue()) 35 | { 36 | $label = 'Multiple Options'; 37 | $chooser->setLabel($label); 38 | 39 | $elementValue = $element->getValue(); 40 | 41 | $sourceUrl = $this->getUrl('*/menu_attribute_option_widget/chooser', array('uniq_id' => $uniqId,'prev_value' => $elementValue)); 42 | $chooser->setSourceUrl($sourceUrl); 43 | } 44 | 45 | $element->setData('after_element_html', $chooser->toHtml()); 46 | return $element; 47 | } 48 | 49 | /** 50 | * Grid Row JS Callback 51 | * 52 | * @return string 53 | */ 54 | public function getRowClickCallback() 55 | { 56 | $chooserJsObject = $this->getId(); 57 | $newUrl = $this->getUrl('*/menu_attribute_option_widget/chooser', array('uniq_id' => $this->getId())); 58 | 59 | $js = ' 60 | function (grid, event) { 61 | var trElement = Event.findElement(event, "tr"); 62 | var attributeId = trElement.down("td").innerHTML.replace(/^\s+|\s+$/g,""); 63 | '.$chooserJsObject.'.close(); 64 | '.$chooserJsObject.'.chooseNew("'.$newUrl.'?attribute_id=" + attributeId); 65 | } 66 | '; 67 | return $js; 68 | } 69 | 70 | protected function _prepareCollection() 71 | { 72 | $collection = Mage::getResourceModel('catalog/product_attribute_collection') 73 | ->addVisibleFilter(); 74 | $this->setCollection($collection); 75 | 76 | return parent::_prepareCollection(); 77 | } 78 | 79 | protected function _prepareColumns() 80 | { 81 | $this->addColumn('attribute_id', array( 82 | 'header'=>Mage::helper('eav')->__('Attribute Id'), 83 | 'sortable'=>true, 84 | 'index'=>'attribute_id' 85 | )); 86 | 87 | $this->addColumn('attribute_code', array( 88 | 'header'=>Mage::helper('eav')->__('Attribute Code'), 89 | 'sortable'=>true, 90 | 'index'=>'attribute_code' 91 | )); 92 | 93 | $this->addColumn('frontend_label', array( 94 | 'header'=>Mage::helper('eav')->__('Attribute Label'), 95 | 'sortable'=>true, 96 | 'index'=>'frontend_label' 97 | )); 98 | 99 | return parent::_prepareColumns(); 100 | } 101 | 102 | public function getGridUrl() 103 | { 104 | return $this->getUrl('*/menu_attribute_widget/chooser', array('_current' => true)); 105 | } 106 | } -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/Block/Adminhtml/Attribute/Option/Chooser.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | 11 | class TheExtensionLab_MegaMenu_Block_Adminhtml_Attribute_Option_Chooser extends 12 | Mage_Adminhtml_Block_Widget_Grid 13 | { 14 | public function __construct($arguments = array()) 15 | { 16 | parent::__construct($arguments); 17 | $this->setUseAjax(true); 18 | $this->setSkipGenerateContent(true); 19 | if($this->getCallback()) { 20 | $this->setDefaultFilter(array('use_options' => 1)); 21 | } 22 | } 23 | 24 | protected function _prepareLayout() 25 | { 26 | $this->setChild('submit_button', 27 | $this->getLayout()->createBlock('adminhtml/widget_button') 28 | ->setData(array( 29 | 'label' => Mage::helper('adminhtml')->__('Submit Options'), 30 | 'onclick' => $this->getSubmitCallback(), 31 | 'class' => 'task' 32 | )) 33 | ); 34 | 35 | $this->setChild('back_button', 36 | $this->getLayout()->createBlock('adminhtml/widget_button') 37 | ->setData(array( 38 | 'label' => Mage::helper('adminhtml')->__('Back'), 39 | 'onclick' => $this->getBackCallback(), 40 | 'class' => 'back' 41 | )) 42 | ); 43 | 44 | parent::_prepareLayout(); 45 | 46 | $this->setChild('reset_filter_button', 47 | $this->getLayout()->createBlock('adminhtml/widget_button') 48 | ->setData(array( 49 | 'label' => Mage::helper('adminhtml')->__('Reset Filter'), 50 | 'onclick' => $this->getJsObjectName().'.addVarToUrl(\'attribute_id\',\''.$this->getAttributeId().'\');'.$this->getJsObjectName().'.resetFilter()', 51 | )) 52 | ); 53 | 54 | return $this; 55 | } 56 | 57 | 58 | protected function _addColumnFilterToCollection($column) 59 | { 60 | if ($column->getId() == 'use_options') { 61 | $this->_setCustomFilterForInProductFlag($column); 62 | } else { 63 | parent::_addColumnFilterToCollection($column); 64 | } 65 | return $this; 66 | } 67 | 68 | private function _setCustomFilterForInProductFlag($column) 69 | { 70 | $optionIds = $this->_getSelectedOptions(); 71 | if (empty($optionIds)) { 72 | $optionIds = 0; 73 | } 74 | if ($column->getFilter()->getValue()) { 75 | $this->getCollection()->addFieldToFilter('tsv.option_id', array('in' => $optionIds)); 76 | } else { 77 | if($optionIds) { 78 | $this->getCollection()->addFieldToFilter('tsv.option_id', array('nin' => $optionIds)); 79 | } 80 | } 81 | } 82 | 83 | 84 | private function getBackCallback() 85 | { 86 | $chooserJsObject = $this->getId(); 87 | $newUrl = $this->getUrl('*/menu_attribute_widget/chooser', array('uniq_id' => $this->getId())); 88 | 89 | $js = ' 90 | '.$chooserJsObject.'.close(); 91 | '.$chooserJsObject.'.chooseNew(\''.$newUrl.'\'); 92 | '; 93 | 94 | return $js; 95 | } 96 | 97 | public function getSubmitCallback() 98 | { 99 | $chooserJsObject = $this->getId(); 100 | 101 | $js = ' 102 | '.$chooserJsObject.'.setElementValue(document.getElementsByName(\'megamenu_attribute_options\')[0].value); 103 | '.$chooserJsObject.'.setElementLabel(\'Multiple Options\'); 104 | '.$chooserJsObject.'.close(); 105 | '; 106 | 107 | return $js; 108 | } 109 | 110 | public function getBackButtonHtml() 111 | { 112 | return $this->getChildHtml('back_button'); 113 | } 114 | 115 | public function getSubmitButtonHtml() 116 | { 117 | return $this->getChildHtml('submit_button'); 118 | } 119 | 120 | 121 | public function getMainButtonsHtml() 122 | { 123 | $html = ''; 124 | 125 | $html.= $this->getBackButtonHtml(); 126 | 127 | if($this->getFilterVisibility()){ 128 | $html.= $this->getResetFilterButtonHtml(); 129 | $html.= $this->getSearchButtonHtml(); 130 | } 131 | 132 | $html.= $this->getSubmitButtonHtml(); 133 | 134 | return $html; 135 | } 136 | 137 | public function prepareElementHtml(Varien_Data_Form_Element_Abstract $element) 138 | { 139 | $uniqId = Mage::helper('core')->uniqHash($element->getId()); 140 | $sourceUrl = $this->getUrl('*/menu_attribute_option_widget/chooser', array('uniq_id' => $uniqId)); 141 | 142 | $chooser = $this->getLayout()->createBlock('widget/adminhtml_widget_chooser') 143 | ->setElement($element) 144 | ->setTranslationHelper($this->getTranslationHelper()) 145 | ->setConfig($this->getConfig()) 146 | ->setFieldsetId($this->getFieldsetId()) 147 | ->setSourceUrl($sourceUrl) 148 | ->setUniqId($uniqId); 149 | 150 | $element->setData('after_element_html', $chooser->toHtml()); 151 | return $element; 152 | } 153 | 154 | protected function _prepareCollection() 155 | { 156 | $attributeId = $this->getAttributeId(); 157 | 158 | $storeId = Mage::app()->getStore()->getStoreId(); 159 | $collection = Mage::getResourceModel('eav/entity_attribute_option_collection') 160 | ->setAttributeFilter($attributeId) 161 | ->setStoreFilter($storeId, false); 162 | 163 | // $this->_setCollectionPositionValues($collection); 164 | 165 | $this->setCollection($collection); 166 | 167 | return parent::_prepareCollection(); 168 | } 169 | 170 | protected function _afterLoadCollection() 171 | { 172 | $prevValue = $this->getCallback(); 173 | foreach($this->getCollection() as $item) { 174 | if (isset($prevValue[$item->getOptionId()][0]['position'])) { 175 | $item->setPosition((int) $prevValue[$item->getOptionId()][0]['position']); 176 | }else{ 177 | $item->setPosition(0); 178 | } 179 | } 180 | return $this; 181 | } 182 | 183 | 184 | protected function _prepareColumns() 185 | { 186 | $this->addColumn( 187 | 'use_options', array( 188 | 'header_css_class' => 'a-center', 189 | 'type' => 'checkbox', 190 | 'name' => 'use_options', 191 | 'values' => $this->_getSelectedOptions(), 192 | 'align' => 'center', 193 | 'index' => 'option_id' 194 | ) 195 | ); 196 | 197 | $this->addColumn('option_id', array( 198 | 'header'=>Mage::helper('eav')->__('Option Id'), 199 | 'index'=>'option_id', 200 | 'width' => '80px' 201 | )); 202 | 203 | $this->addColumn('value', array( 204 | 'header'=>Mage::helper('eav')->__('Option Value'), 205 | 'index'=>'value' 206 | )); 207 | 208 | $this->addColumn( 209 | 'position', array( 210 | 'header' => Mage::helper('eav')->__('Position'), 211 | 'name' => 'position', 212 | 'type' => 'number', 213 | 'validate_class' => 'validate-number', 214 | 'width' => '1', 215 | 'editable' => true, 216 | 'index' => 'position', 217 | 'value' => '0' 218 | ) 219 | ); 220 | 221 | 222 | return parent::_prepareColumns(); 223 | } 224 | 225 | private function _getSelectedOptions() 226 | { 227 | $optionIds = array(); 228 | if($this->getCallback()) { 229 | $prevValueArray = $this->getCallback(); 230 | $optionIds = array_keys($prevValueArray); 231 | } 232 | return $optionIds; 233 | } 234 | 235 | 236 | public function getCallback() 237 | { 238 | return json_decode($this->getPrevValue(),1); 239 | } 240 | 241 | public function getGridUrl() 242 | { 243 | return $this->getUrl('*/menu_attribute_option_widget/chooserGridOnly', array('_current' => true)); 244 | } 245 | 246 | 247 | } -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/Block/Adminhtml/Catalog/Category/Widget/Chooser.php: -------------------------------------------------------------------------------- 1 | 15 | * 16 | */ 17 | 18 | class TheExtensionLab_MegaMenu_Block_Adminhtml_Catalog_Category_Widget_Chooser 19 | extends Mage_Adminhtml_Block_Catalog_Category_Widget_Chooser 20 | { 21 | public function prepareElementHtml(Varien_Data_Form_Element_Abstract $element) 22 | { 23 | $chooser = $this->getChooserWithCustomSourceUrl($element); 24 | 25 | if ($element->getValue()) { 26 | $categoryId = false; 27 | if ($element->hasValue()) { 28 | $categoryId = $element->getValue(); 29 | } 30 | if ($categoryId) { 31 | $label = $this->_getModelAttributeByEntityId('catalog/category', 'name', $categoryId); 32 | $chooser->setLabel($label); 33 | } 34 | } 35 | 36 | $element->setData('after_element_html', $chooser->toHtml()); 37 | return $element; 38 | } 39 | 40 | public function getNodeClickListener() 41 | { 42 | $js = parent::getNodeClickListener(); 43 | 44 | if(!$this->getData('node_click_listener') && !$this->getUseMassaction()) 45 | { 46 | $chooserJsObject = $this->getId(); 47 | $js = $this->_getJsWithoutCategoryPrefix($chooserJsObject); 48 | } 49 | 50 | return $js; 51 | } 52 | 53 | private function _getJsWithoutCategoryPrefix($chooserJsObject) 54 | { 55 | $js = ' 56 | function (node, e) { 57 | '.$chooserJsObject.'.setElementValue(node.attributes.id); 58 | '.$chooserJsObject.'.setElementLabel(node.text); 59 | '.$chooserJsObject.'.close(); 60 | } 61 | '; 62 | 63 | return $js; 64 | } 65 | 66 | private function getChooserWithCustomSourceUrl(Varien_Data_Form_Element_Abstract $element) 67 | { 68 | $uniqId = Mage::helper('core')->uniqHash($element->getId()); 69 | 70 | $sourceUrl = $this->getUrl('*/menu_catalog_category_widget/chooser', 71 | array('uniq_id' => $uniqId, 'use_massaction' => false)); 72 | 73 | $chooser = $this->getLayout()->createBlock('widget/adminhtml_widget_chooser') 74 | ->setElement($element) 75 | ->setTranslationHelper($this->getTranslationHelper()) 76 | ->setConfig($this->getConfig()) 77 | ->setFieldsetId($this->getFieldsetId()) 78 | ->setSourceUrl($sourceUrl) 79 | ->setUniqId($uniqId); 80 | 81 | return $chooser; 82 | } 83 | } -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/Block/Adminhtml/Catalog/Category/Widget/Draggable/Chooser.php: -------------------------------------------------------------------------------- 1 | 15 | * 16 | */ 17 | 18 | class TheExtensionLab_MegaMenu_Block_Adminhtml_Catalog_Category_Widget_Draggable_Chooser 19 | extends Mage_Adminhtml_Block_Catalog_Category_Widget_Chooser 20 | { 21 | public function __construct() 22 | { 23 | parent::__construct(); 24 | $this->setTemplate('theextensionlab/megamenu/widget/catalog/category/tree.phtml'); 25 | } 26 | 27 | public function prepareElementHtml(Varien_Data_Form_Element_Abstract $element) { 28 | $uniqId = Mage::helper('core')->uniqHash($element->getId()); 29 | $sourceUrl = $this->getUrl( 30 | '*/menu_catalog_category_draggable_widget/chooser', 31 | array('uniq_id' => $uniqId, 'use_massaction' => false) 32 | ); 33 | 34 | $chooser = $this->getLayout() 35 | ->createBlock('widget/adminhtml_widget_chooser') 36 | ->setElement($element) 37 | ->setTranslationHelper($this->getTranslationHelper()) 38 | ->setConfig($this->getConfig()) 39 | ->setFieldsetId($this->getFieldsetId()) 40 | ->setSourceUrl($sourceUrl) 41 | ->setUniqId($uniqId); 42 | 43 | if($element->hasValue()) 44 | { 45 | $label = 'Selected'; 46 | $chooser->setLabel($label); 47 | 48 | $elementValue = $element->getValue(); 49 | 50 | $sourceUrl = $this->getUrl( 51 | '*/menu_catalog_category_draggable_widget/chooser', 52 | array( 53 | 'uniq_id' => $uniqId, 54 | 'prev_value' => $elementValue, 55 | 'use_massaction' => false 56 | ) 57 | ); 58 | $chooser->setSourceUrl($sourceUrl); 59 | } 60 | 61 | $element->setData('after_element_html', $chooser->toHtml()); 62 | return $element; 63 | } 64 | 65 | public function getEmptyTreeJson($parenNodeCategory = null) 66 | { 67 | $prevValueJson = $this->getPrevValue(); 68 | $prevValue = json_decode($prevValueJson); 69 | 70 | $rootArray = $this->_getNodeJson($this->getRoot($parenNodeCategory), 0); 71 | 72 | $oldChild = $rootArray['children']['0']; 73 | $rootArray['children'] = null; 74 | $rootArray['children']['0'] = $oldChild; 75 | $rootArray['children']['0']['children'] = null; 76 | 77 | if(!empty($prevValue->categories)): 78 | $prevValue->categories = $this->_addCategoryNameToPrevValueCategories($prevValue->categories); 79 | $rootArray['children']['0']['children'] = $prevValue->categories; 80 | endif; 81 | 82 | $rootArray['use_ajax'] = false; 83 | 84 | $rootArray['children']['0']['text'] = $this->__("Drag your categories here"); 85 | $rootArray['children']['0']['id'] = 2; 86 | $json = Mage::helper('core')->jsonEncode( 87 | isset($rootArray['children']) 88 | ? $rootArray['children'] : array() 89 | ); 90 | return $json; 91 | } 92 | 93 | private function _addCategoryNameToPrevValueCategories($categories) 94 | { 95 | $categoryCollection = $this->getCategoryCollection(); 96 | foreach($categories as $categoryNode) 97 | { 98 | $category = $categoryCollection->getItemById($categoryNode->id); 99 | $categoryNode->text = $category->getName(); 100 | 101 | if(!empty($categoryNode->children)){ 102 | $this->_addCategoryNameToPrevValueCategories($categoryNode->children); 103 | } 104 | } 105 | 106 | return $categories; 107 | } 108 | 109 | public function getNodeClickListener() 110 | { 111 | $chooserJsObject = $this->getId(); 112 | 113 | $js 114 | = ' 115 | function (event) { 116 | ' . $chooserJsObject . '.setElementValue( 117 | 118 | JSON.stringify(getNodeData( 119 | tree2' . $this->getId() . '.getNodeById(2), 120 | ["id","text"] 121 | )).addSlashes() 122 | 123 | ); 124 | ' . $chooserJsObject . '.setElementLabel("Selected"); 125 | ' . $chooserJsObject . '.close(); 126 | } 127 | 128 | 129 | '; 130 | 131 | return $js; 132 | } 133 | 134 | } -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/Block/Adminhtml/System/Config/Extension.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | class TheExtensionLab_MegaMenu_Block_Adminhtml_System_Config_Extension 11 | extends Mage_Adminhtml_Block_Abstract 12 | implements Varien_Data_Form_Element_Renderer_Interface 13 | { 14 | protected function _construct() 15 | { 16 | parent::_construct(); 17 | $this->setTemplate( 18 | 'theextensionlab/megamenu/system/config/extension-info.phtml' 19 | ); 20 | } 21 | 22 | public function render(Varien_Data_Form_Element_Abstract $element) 23 | { 24 | $html = $this->renderView(); 25 | return $html; 26 | } 27 | } -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/Block/Page/Html/Topmenu/Renderer.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | 11 | class TheExtensionLab_MegaMenu_Block_Page_Html_Topmenu_Renderer 12 | extends Mage_Page_Block_Html_Topmenu_Renderer 13 | { 14 | 15 | protected function _toHtml() 16 | { 17 | $html = parent::_toHtml(); 18 | $prefetcher = $this->_getMegaMenuHelper()->getMenuWidgetPrefetcher(); 19 | $prefetcher->prefetch($html); 20 | $processor = $this->_getMegaMenuHelper()->getMenuTemplateProcessor(); 21 | $html = $processor->filter($html); 22 | return $html; 23 | } 24 | 25 | protected function _getMenuItemClasses(Varien_Data_Tree_Node $item) 26 | { 27 | $classes = array(); 28 | 29 | $classes[] = 'level' . $item->getLevel(); 30 | $classes[] = $item->getPositionClass(); 31 | 32 | if ($item->getIsActive()) { 33 | $classes[] = 'active'; 34 | } 35 | 36 | if ($item->getClass()) { 37 | $classes[] = $item->getClass(); 38 | } 39 | 40 | if($item->getId()){ 41 | $classes[] = $item->getId(); 42 | } 43 | 44 | if ($this->getHasDropdownContent($item)) { 45 | $classes[] = 'parent'; 46 | } 47 | 48 | return $classes; 49 | } 50 | 51 | protected function getHasDropdownContent(Varien_Data_Tree_Node $item) 52 | { 53 | $hasContent = false; 54 | 55 | if(!$item->hasColumns()): 56 | return false; 57 | endif; 58 | 59 | $columns = $item->getColumns(); 60 | 61 | foreach($columns as $column){ 62 | if(!empty($column['content'])): 63 | if($column['col_width'] != 0) { 64 | $hasContent = true; 65 | } 66 | endif; 67 | } 68 | return $hasContent; 69 | } 70 | 71 | protected function getCategoryLiClass($category){ 72 | $hasChildren = ($category->hasChildren()) ? ' has-children' : ''; 73 | 74 | $class = 'level'.$category->getLevel(); 75 | $class .= $hasChildren; 76 | 77 | return $class; 78 | } 79 | 80 | protected function setCategoryData($category,$parentLevel) 81 | { 82 | $childLevel = is_null($parentLevel) ? 0 : $parentLevel + 1; 83 | 84 | $category->setLevel($childLevel); 85 | $category->setHasDropDownContent($this->getHasDropdownContent($category)); 86 | } 87 | 88 | protected function getMenuDropDownTypeClass($category) 89 | { 90 | $dropdownTypeId = $category->getMenuDropdownType(); 91 | 92 | switch ($dropdownTypeId) { 93 | case 1: 94 | $dropdownClass = 'megamenu absolute-center'; 95 | break; 96 | case 2: 97 | $dropdownClass = 'megamenu absolute-left'; 98 | break; 99 | case 3: 100 | $dropdownClass = 'megamenu absolute-right'; 101 | break; 102 | case 4: 103 | $dropdownClass = 'megamenu relative-center'; 104 | break; 105 | case 5: 106 | $dropdownClass = 'megamenu hang-right'; 107 | break; 108 | case 6: 109 | $dropdownClass = 'megamenu hang-left'; 110 | break; 111 | default: 112 | $dropdownClass = 'megamenu absolute-center'; 113 | break; 114 | } 115 | 116 | $dropdownClass .= ' level'.$category->getLevel(); 117 | $dropdownClass .= ' xlab_grid_container'; 118 | 119 | return $dropdownClass; 120 | } 121 | 122 | protected function getDropDownInlineStyle($child){ 123 | 124 | $style = ''; 125 | 126 | if($child->getMenuDropdownWidth() != null) 127 | { 128 | $style .= ' width:'.$child->getMenuDropdownWidth().';'; 129 | } 130 | 131 | return $style; 132 | } 133 | 134 | protected function _isCategoryPlaceholder($category){ 135 | return $category->getMenuLinkType() == TheExtensionLab_MegaMenu_Model_Config_Source_Link_Type::NO_LINK; 136 | } 137 | 138 | private function _getMegaMenuHelper() 139 | { 140 | return Mage::helper('theextensionlab_megamenu'); 141 | } 142 | } -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/Block/Widget/Attribute/List.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | 11 | class TheExtensionLab_MegaMenu_Block_Widget_Attribute_List 12 | extends TheExtensionLab_MegaMenu_Block_Widget_Template 13 | implements Mage_Widget_Block_Interface 14 | { 15 | protected function getClass() 16 | { 17 | $class = ''; 18 | $columns = $this->getListColumns(); 19 | 20 | if ($columns > 1) { 21 | $class = "content-columns-{$columns}"; 22 | } 23 | 24 | return $class; 25 | } 26 | 27 | protected function getDisplayClass() 28 | { 29 | $displayClass = parent::getDisplayClass(); 30 | if ($this->hasContentColumns()) { 31 | $displayClass .= ' content-columns-section'; 32 | } 33 | 34 | return $displayClass; 35 | } 36 | 37 | public function getOptionIds(){ 38 | $optionsIds = json_decode($this->getData('option_ids'),true); 39 | uasort($optionsIds, array($this, '_sortOptionsByPosition')); 40 | return $optionsIds; 41 | } 42 | 43 | private static function _sortOptionsByPosition($a,$b) 44 | { 45 | return $a[0]['position'] - $b[0]['position']; 46 | } 47 | 48 | private function hasContentColumns() 49 | { 50 | $columns = $this->getListColumns(); 51 | 52 | if($columns > 1) { 53 | return true; 54 | } 55 | 56 | return false; 57 | } 58 | } -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/Block/Widget/Category/Featured.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | 11 | class TheExtensionLab_MegaMenu_Block_Widget_Category_Featured 12 | extends TheExtensionLab_MegaMenu_Block_Widget_Template 13 | implements Mage_Widget_Block_Interface 14 | { 15 | protected function getFeaturedCategoryNode() 16 | { 17 | 18 | $currentMenu = Mage::registry('current_menu'); 19 | $childNodes = $currentMenu->getAllChildNodes(); 20 | 21 | $categoryNodeId = 'category-node-'.$this->getMenuFeaturedCategoryId(); 22 | 23 | if(!isset($childNodes[$categoryNodeId])){ 24 | return false; 25 | } 26 | 27 | $categoryNode = $childNodes[$categoryNodeId]; 28 | 29 | return $categoryNode; 30 | 31 | } 32 | } -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/Block/Widget/Category/List.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | 11 | class TheExtensionLab_MegaMenu_Block_Widget_Category_List 12 | extends TheExtensionLab_MegaMenu_Block_Widget_Template 13 | implements Mage_Widget_Block_Interface 14 | { 15 | protected function getCategoryTree() 16 | { 17 | $json = $this->getCategoryJson(); 18 | $categoryData = json_decode($json); 19 | 20 | return $categoryData->categories; 21 | } 22 | 23 | protected function getLoadedMenuNodes() 24 | { 25 | $currentMenu = Mage::registry('current_menu'); 26 | $childNodes = $currentMenu->getAllChildNodes(); 27 | 28 | return $childNodes; 29 | } 30 | 31 | protected function _getCategoryNodeById($childNodes, $categoryId) 32 | { 33 | $categoryNodeId = 'category-node-'.$categoryId; 34 | 35 | if(!isset($childNodes[$categoryNodeId])): 36 | return false; 37 | endif; 38 | 39 | return $childNodes[$categoryNodeId]; 40 | } 41 | 42 | protected function _getCustomCategoryMenuName($categoryNode, $categoryJson) 43 | { 44 | if(isset($categoryJson->custom_name)){ 45 | return $categoryJson->custom_name; 46 | } 47 | 48 | return $categoryNode->getName(); 49 | } 50 | } -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/Block/Widget/Cms/Block.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | 11 | class TheExtensionLab_MegaMenu_Block_Widget_Cms_Block extends TheExtensionLab_MegaMenu_Block_Widget_Template 12 | implements Mage_Widget_Block_Interface 13 | { 14 | public function getBlock() 15 | { 16 | $blockId = $this->getMenuStaticBlockId(); 17 | 18 | if (!$blockId) { 19 | return false; 20 | } 21 | 22 | $collection = Mage::registry('megamenu_cms_blocks'); 23 | $block = $collection->getItemById($blockId); 24 | return $block; 25 | } 26 | } -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/Block/Widget/Cms/Page/Featured.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | 11 | class TheExtensionLab_MegaMenu_Block_Widget_Cms_Page_Featured 12 | extends TheExtensionLab_MegaMenu_Block_Widget_Template implements Mage_Widget_Block_Interface 13 | { 14 | public function getCmsPage() 15 | { 16 | $collection = Mage::registry('megamenu_cms_pages'); 17 | $cmsPage = $collection->getItemById($this->getMenuFeaturedCmsId()); 18 | return $cmsPage; 19 | } 20 | 21 | public function getCmsPageUrl(Mage_Cms_Model_Page $cmsPage) 22 | { 23 | return $this->getUrl($cmsPage->getIdentifier()); 24 | } 25 | } -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/Block/Widget/Product/Featured.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | 11 | class TheExtensionLab_MegaMenu_Block_Widget_Product_Featured 12 | extends TheExtensionLab_MegaMenu_Block_Widget_Template 13 | implements Mage_Widget_Block_Interface 14 | { 15 | protected function getFeaturedProductsCollection() 16 | { 17 | $featuredProducts = json_decode($this->getMegamenuFeaturedProductIds(), true); 18 | 19 | uasort($featuredProducts, array($this, '_featuredProductsSortByPosition')); 20 | 21 | $featuredProductCollection = $this->_createFeaturedProductsCollectionFromPrefetchedData($featuredProducts); 22 | 23 | return $featuredProductCollection; 24 | } 25 | 26 | private function _createFeaturedProductsCollectionFromPrefetchedData(array $featuredProducts) 27 | { 28 | $featuredProductCollection = new Varien_Data_Collection(); 29 | $prefetchedCollection = $this->_getPrefetchedProductCollection(); 30 | 31 | foreach ($featuredProducts as $featuredProductId => $featuredProduct) { 32 | $item = $prefetchedCollection->getItemById($featuredProductId); 33 | if($item) { 34 | $featuredProductCollection->addItem($item); 35 | } 36 | } 37 | 38 | return $featuredProductCollection; 39 | } 40 | private function _getPrefetchedProductCollection() 41 | { 42 | return Mage::registry('megamenu_products_collection'); 43 | } 44 | 45 | private static function _featuredProductsSortByPosition($a,$b) 46 | { 47 | return $a[0]['position'] - $b[0]['position']; 48 | } 49 | } -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/Block/Widget/Template.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | 11 | class TheExtensionLab_MegaMenu_Block_Widget_Template 12 | extends Mage_Core_Block_Template 13 | { 14 | protected function getDisplayClass() 15 | { 16 | $screensToDisplayOn = $this->getDisplayOn(); 17 | 18 | if (empty($screensToDisplayOn)) { 19 | return ''; 20 | } 21 | 22 | $screensToDisplayOnArray = explode(',', $screensToDisplayOn); 23 | 24 | return $this->_getStylesHelper()->getDisplayClass($screensToDisplayOnArray); 25 | } 26 | 27 | private function _getStylesHelper() 28 | { 29 | return Mage::helper('theextensionlab_megamenu/display_styles'); 30 | } 31 | } -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/Helper/Attribute/Url.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | 11 | class TheExtensionLab_MegaMenu_Helper_Attribute_Url 12 | { 13 | public function getFilterUrl($categoryId, $code, $value) 14 | { 15 | $requestPath = ''; 16 | $query = array( 17 | $code => $value, 18 | Mage::getBlockSingleton('page/html_pager')->getPageVarName() => null, 19 | ); 20 | 21 | $urlRewritesCollection = Mage::registry('megamenu_url_rewrites'); 22 | 23 | if (isset($urlRewritesCollection['category/' . $categoryId])) { 24 | $requestPath = $urlRewritesCollection['category/' . $categoryId]->getRequestPath(); 25 | } 26 | 27 | $url = Mage::getUrl($requestPath, array('_query' => $query)); 28 | $url = Mage::getModel('core/url')->sessionUrlVar($url); 29 | $url = str_replace('/?', '?', $url); 30 | 31 | $urlData = new Varien_Object( 32 | array('category_id' => $categoryId, 33 | 'attribute_code' => $code, 34 | 'value' => $value, 35 | 'query' => $query, 36 | 'url' => $url 37 | ) 38 | ); 39 | 40 | $this->_dispatchEventToAllowUrlCustomisation($urlData); 41 | 42 | return $urlData->getUrl(); 43 | } 44 | 45 | private function _dispatchEventToAllowUrlCustomisation($urlData) 46 | { 47 | Mage::dispatchEvent( 48 | 'megamenu_getfilterurl_after', array('url_data' => $urlData) 49 | ); 50 | } 51 | } -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/Helper/Category.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | 11 | class TheExtensionLab_MegaMenu_Helper_Category extends Mage_Core_Model_Abstract 12 | { 13 | protected $_storeCategories = array(); 14 | 15 | public function getMenuName($category) 16 | { 17 | if($category->getMenuName()){ 18 | return $category->getMenuName(); 19 | } 20 | 21 | return $category->getName(); 22 | } 23 | 24 | public function getFullImageUrl($image) 25 | { 26 | $url = false; 27 | if ($image) { 28 | $url = Mage::getBaseUrl('media').'catalog' . DS . 'category' . DS .$image; 29 | } 30 | return $url; 31 | } 32 | 33 | public function getStoreCategories($sorted = false, $asCollection = false, $toLoad = true) 34 | { 35 | $parent = Mage::app()->getStore()->getRootCategoryId(); 36 | 37 | $cacheKey = $this->_makeCacheKey( 38 | $parent, $sorted, $asCollection, $toLoad 39 | ); 40 | 41 | if (isset($this->_storeCategories[$cacheKey])) { 42 | return $this->_storeCategories[$cacheKey]; 43 | } 44 | 45 | $recursionLevel = $this->_getRecursionLevel(); 46 | $storeCategories = $this->_getCategories($parent, $recursionLevel, $sorted, $asCollection, $toLoad); 47 | 48 | 49 | 50 | $this->_storeCategories[$cacheKey] = $storeCategories; 51 | return $storeCategories; 52 | } 53 | 54 | private function _makeCacheKey($parent, $sorted, $asCollection, $toLoad) 55 | { 56 | return sprintf('%d-%d-%d-%d', $parent, $sorted, $asCollection, $toLoad); 57 | } 58 | 59 | private function _checkIfParentNodeStillExists($parent) 60 | { 61 | /* @var Mage_Catalog_Model_Category */ 62 | $category = Mage::getModel('catalog/category'); 63 | return $category->checkId($parent); 64 | } 65 | 66 | private function _getRecursionLevel() 67 | { 68 | $recursionLevel = (int)Mage::app()->getStore()->getConfig( 69 | 'catalog/navigation/max_depth' 70 | ); 71 | 72 | if ($recursionLevel < 0) { 73 | $recursionLevel = 0; 74 | } 75 | 76 | return $recursionLevel; 77 | 78 | } 79 | 80 | private function _getCategories( 81 | $parent, $recursionLevel = 0, $sorted = false, $asCollection = false, $toLoad = true, $onlyActive = false 82 | ) { 83 | if(Mage::helper('catalog/category_flat')->isEnabled() && Mage::helper('catalog/category_flat')->isBuilt()) { 84 | return $this->_getCategoriesFromFlatTables($parent, $recursionLevel, $sorted, $asCollection, $toLoad); 85 | } 86 | /* @var $tree Mage_Catalog_Model_Resource_Category_Tree */ 87 | $tree = Mage::getResourceModel('catalog/category_tree'); 88 | 89 | $collection = $tree->getCollection($sorted); 90 | $collection->addAttributeToFilter('include_in_menu', 1); 91 | 92 | $nodes = $tree->loadNode($parent) 93 | ->loadChildren($recursionLevel) 94 | ->getChildren(); 95 | 96 | $tree->addCollectionData($collection, $sorted, $parent, $toLoad, $onlyActive); 97 | 98 | if ($asCollection) { 99 | return $tree->getCollection(); 100 | } 101 | 102 | return $nodes; 103 | } 104 | 105 | private function _getCategoriesFromFlatTables($parent, $recursionLevel = 0, $sorted = false, $asCollection = false, $toLoad = true){ 106 | return Mage::getResourceModel('theextensionlab_megamenu/category_flat')->getCategories($parent, $recursionLevel, $sorted, $asCollection, $toLoad); 107 | } 108 | } -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/Helper/Category/Url.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | 11 | class TheExtensionLab_MegaMenu_Helper_Category_Url extends Mage_Core_Model_Abstract 12 | { 13 | public function getCategoryUrl($category) 14 | { 15 | if ($this->_checkIsCategoryInternalLink($category)) { 16 | $url = Mage::getUrl($category->getMenuLink()); 17 | $url = Mage::getModel('core/url')->sessionUrlVar($url); 18 | return $url; 19 | } 20 | 21 | if ($this->_checkIsCategoryExternalLink($category)) { 22 | return $category->getMenuLink(); 23 | } 24 | 25 | return $this->_getCategoryHelper()->getCategoryUrl($category); 26 | } 27 | 28 | private function _checkIsCategoryInternalLink($category) 29 | { 30 | $internalLinkType = TheExtensionLab_MegaMenu_Model_Config_Source_Link_Type::INTERNAL_LINK_TYPE; 31 | $isCategoryInternalLink = ($category->getMenuLinkType() == $internalLinkType); 32 | return $isCategoryInternalLink; 33 | } 34 | 35 | private function _checkIsCategoryExternalLink($category) 36 | { 37 | $externalLinkType = TheExtensionLab_MegaMenu_Model_Config_Source_Link_Type::EXTERNAL_LINK_TYPE; 38 | $isCategoryExternalLink = ($category->getMenuLinkType() == $externalLinkType); 39 | return $isCategoryExternalLink; 40 | } 41 | 42 | private function _getCategoryHelper() 43 | { 44 | return Mage::helper('catalog/category'); 45 | } 46 | } -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/Helper/Column/Types.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | 11 | class TheExtensionLab_MegaMenu_Helper_Column_Types 12 | { 13 | public function getTypes() 14 | { 15 | return array(5,24); 16 | } 17 | 18 | public function getMaxColumns() 19 | { 20 | return (int) 24; 21 | } 22 | } -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/Helper/Data.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | 11 | class TheExtensionLab_MegaMenu_Helper_Data extends Mage_Core_Helper_Abstract 12 | { 13 | const XML_NODE_MENU_TEMPLATE_FILTER = 'global/theextensionlab_megamenu/menu/tempate_filter'; 14 | const XML_NODE_MENU_WIDGET_PREFETCHER = 'global/theextensionlab_megamenu/menu/widget_prefetcher'; 15 | 16 | public function getMenuTemplateProcessor() 17 | { 18 | $model = (string)Mage::getConfig()->getNode(self::XML_NODE_MENU_TEMPLATE_FILTER); 19 | return Mage::getModel($model); 20 | } 21 | 22 | public function getMenuWidgetPrefetcher() 23 | { 24 | $model = (string)Mage::getConfig()->getNode(self::XML_NODE_MENU_WIDGET_PREFETCHER); 25 | return Mage::getModel($model); 26 | } 27 | } -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/Helper/Display/Styles.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | 11 | class TheExtensionLab_MegaMenu_Helper_Display_Styles 12 | { 13 | public function getDisplayClass(array $screensToDisplayOn) 14 | { 15 | $displayClasses = array(); 16 | 17 | $screenTypes = array( 18 | 'small', 19 | 'medium', 20 | 'large' 21 | ); 22 | 23 | foreach($screenTypes as $screenType){ 24 | if(!in_array($screenType,$screensToDisplayOn)){ 25 | $displayClasses[] = 'hide-on-'.$screenType; 26 | } 27 | } 28 | 29 | $displayCssClasses = implode(' ',$displayClasses); 30 | 31 | return $displayCssClasses; 32 | } 33 | } -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/Model/Config/Dependancy.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | 11 | class TheExtensionLab_MegaMenu_Model_Config_Dependancy 12 | { 13 | public function addCategoryFieldDependancys(Mage_Adminhtml_Block_Catalog_Category_Tab_Attributes $block) 14 | { 15 | $group = $block->getGroup(); 16 | $groupId = $group->getAttributeGroupId(); 17 | $groupName = $group->getAttributeGroupName(); 18 | 19 | $dependanceBlock = $block->getLayout()->createBlock('adminhtml/widget_form_element_dependence'); 20 | 21 | if($groupName == "MegaMenu Settings") { 22 | $this->_defineSettingsFieldDependancies($dependanceBlock, $groupId); 23 | } 24 | 25 | if($groupName == "MegaMenu Contents") { 26 | $this->_defineContentsFieldDependancies($dependanceBlock, $groupId); 27 | } 28 | 29 | Mage::dispatchEvent('define_megamenu_dependancies_after',array('dependaceBlock' => $dependanceBlock, 'block' => $block)); 30 | 31 | $block->setChild('form_after', $dependanceBlock); 32 | } 33 | 34 | private function _defineSettingsFieldDependancies(Mage_Adminhtml_Block_Widget_Form_Element_Dependence $dependanceBlock, $groupId) 35 | { 36 | $dependanceBlock->addFieldMap("group_{$groupId}menu_dropdown_type", 'menu_dropdown_type') 37 | ->addFieldMap("group_{$groupId}menu_dropdown_width", 'menu_dropdown_width') 38 | ->addFieldMap("group_{$groupId}menu_link_type","menu_link_type") 39 | ->addFieldMap("group_{$groupId}menu_link","menu_link") 40 | ->addFieldDependence('menu_dropdown_width', 'menu_dropdown_type', array("2","3","4","5","6")) 41 | ->addFieldDependence('menu_link','menu_link_type', array("1","2")); 42 | } 43 | 44 | private function _defineContentsFieldDependancies(Mage_Adminhtml_Block_Widget_Form_Element_Dependence $dependanceBlock, $groupId) 45 | { 46 | $this->_addColumnsDependace($dependanceBlock, $groupId); 47 | } 48 | 49 | private function _addColumnsDependace($dependanceBlock, $groupId) 50 | { 51 | $columsType = Mage::helper('theextensionlab_megamenu/column_types')->getTypes(); 52 | 53 | $valuesForActive = array(); 54 | 55 | foreach($columsType as $columnType){ 56 | for($i = 1;$i <= $columnType;$i++){ 57 | $valuesForActive[] = "{$i}_{$columnType}"; 58 | } 59 | } 60 | 61 | $totalColumnFeilds = (int) 7; 62 | 63 | for($i = 1;$i <= $totalColumnFeilds;$i++){ 64 | $dependanceBlock->addFieldMap("group_{$groupId}menu_section_{$i}_column_width","menu_section_{$i}_column_width") 65 | ->addFieldMap("group_{$groupId}menu_section_{$i}_content","menu_section_{$i}_content") 66 | ->addFieldDependence("menu_section_{$i}_content","menu_section_{$i}_column_width", $valuesForActive); 67 | } 68 | } 69 | } -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/Model/Config/Source/Abstract.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | 11 | abstract class TheExtensionLab_MegaMenu_Model_Config_Source_Abstract 12 | extends Mage_Eav_Model_Entity_Attribute_Source_Abstract 13 | implements TheExtensionLab_MegaMenu_Model_Config_Source_Interface 14 | { 15 | 16 | protected $_eventPrefix; 17 | 18 | public function getAllOptions() 19 | { 20 | $optionsContainer = new Varien_Object(); 21 | $optionsContainer->setOptions($this->getAllOptionsArray()); 22 | 23 | Mage::dispatchEvent( 24 | $this->_eventPrefix . '_get_all_options_array_after', 25 | array('options_container' => $optionsContainer) 26 | ); 27 | 28 | return $optionsContainer->getOptions(); 29 | } 30 | 31 | public function getOptions() 32 | { 33 | return $this->_options; 34 | } 35 | 36 | public function setOptions($options){ 37 | return $this->_options = $options; 38 | } 39 | } -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/Model/Config/Source/Columns.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | 11 | class TheExtensionLab_MegaMenu_Model_Config_Source_Columns 12 | extends TheExtensionLab_MegaMenu_Model_Config_Source_Abstract 13 | { 14 | protected $_eventPrefix = 'columns'; 15 | protected $_columnTypes = array(); 16 | 17 | public function __construct() 18 | { 19 | $this->_columnTypes = Mage::helper('theextensionlab_megamenu/column_types')->getTypes(); 20 | } 21 | 22 | public function getAllOptionsArray() 23 | { 24 | if (is_null($this->_options)) { 25 | 26 | $this->_options[] = array( 27 | 'label' => Mage::helper('theextensionlab_megamenu')->__('Not Active'), 28 | 'value' => '0' 29 | ); 30 | 31 | foreach($this->_columnTypes as $columnType) { 32 | for ($i = 1; $i <= $columnType; $i++) { 33 | $width = $this->_calculatePercentage($i,$columnType); 34 | $this->_options[] = array( 35 | 'label' => Mage::helper('theextensionlab_megamenu')->__( 36 | '%s of %s columns (%s)', $i, $columnType, $width 37 | ), 38 | 'value' => $i . '_' . $columnType 39 | ); 40 | } 41 | } 42 | } 43 | 44 | return $this->_options; 45 | } 46 | 47 | private function _calculatePercentage($numerator,$denominator){ 48 | return round(($numerator / $denominator) * 100,2) . '%'; 49 | } 50 | } -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/Model/Config/Source/Display.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | 11 | class TheExtensionLab_MegaMenu_Model_Config_Source_Display 12 | { 13 | public function toOptionArray() 14 | { 15 | return array( 16 | array('value' => 'small', 'label'=>Mage::helper('adminhtml')->__('Small (Mobile)')), 17 | array('value' => 'medium', 'label'=>Mage::helper('adminhtml')->__('Medium (Tablet)')), 18 | array('value' => 'large', 'label'=>Mage::helper('adminhtml')->__('Large (Desktop)')) 19 | ); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/Model/Config/Source/Dropdown/Type.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | 11 | class TheExtensionLab_MegaMenu_Model_Config_Source_Dropdown_Type 12 | extends TheExtensionLab_MegaMenu_Model_Config_Source_Abstract 13 | { 14 | 15 | protected $_eventPrefix = 'dropdown_type'; 16 | 17 | const ABSOLUTE_CENTER = 1; 18 | const ABSOLUTE_LEFT = 2; 19 | const ABSOLUTE_RIGHT = 3; 20 | const RELATIVE_CENTER = 4; 21 | const HANG_RIGHT = 5; 22 | const HANG_LEFT = 6; 23 | 24 | public function getAllOptionsArray() 25 | { 26 | if (is_null($this->_options)) { 27 | $this->_options = array( 28 | array( 29 | 'label' => $this->_getHelper()->__('Absolute Center (Fullwidth)'), 30 | 'value' => self::ABSOLUTE_CENTER 31 | ), 32 | array( 33 | 'label' => $this->_getHelper()->__('Absolute Left'), 34 | 'value' => self::ABSOLUTE_LEFT 35 | ), 36 | array( 37 | 'label' => $this->_getHelper()->__('Absolute Right'), 38 | 'value' => self::ABSOLUTE_RIGHT 39 | ), 40 | array( 41 | 'label' => $this->_getHelper()->__('Relative Center'), 42 | 'value' => self::RELATIVE_CENTER 43 | ), 44 | array( 45 | 'label' => $this->_getHelper()->__('Hang Right'), 46 | 'value' => self::HANG_RIGHT 47 | ), 48 | array( 49 | 'label' => $this->_getHelper()->__('Hang Left'), 50 | 'value' => self::HANG_LEFT 51 | ) 52 | ); 53 | } 54 | return $this->_options; 55 | } 56 | 57 | private function _getHelper() 58 | { 59 | return Mage::helper('theextensionlab_megamenu'); 60 | } 61 | } -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/Model/Config/Source/Interface.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | 11 | interface TheExtensionLab_MegaMenu_Model_Config_Source_Interface 12 | { 13 | /** 14 | * Retrieve All options as an array 15 | * Because we use a Varien_Object for events 16 | * 17 | * @return array 18 | */ 19 | public function getAllOptionsArray(); 20 | } 21 | -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/Model/Config/Source/Link/Type.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | 11 | class TheExtensionLab_MegaMenu_Model_Config_Source_Link_Type 12 | extends TheExtensionLab_MegaMenu_Model_Config_Source_Abstract 13 | { 14 | 15 | protected $_eventPrefix = 'link_type'; 16 | 17 | const DEFAULT_LINK_TYPE = 0; 18 | const INTERNAL_LINK_TYPE = 1; 19 | const EXTERNAL_LINK_TYPE = 2; 20 | const NO_LINK = 3; 21 | 22 | public function getAllOptionsArray() 23 | { 24 | if (is_null($this->_options)) { 25 | $this->_options = array( 26 | array( 27 | 'label' => $this->_getHelper()->__('Default'), 28 | 'value' => self::DEFAULT_LINK_TYPE 29 | ), 30 | array( 31 | 'label' => $this->_getHelper()->__('Internal Link'), 32 | 'value' => self::INTERNAL_LINK_TYPE 33 | ), 34 | array( 35 | 'label' => $this->_getHelper()->__('External Link'), 36 | 'value' => self::EXTERNAL_LINK_TYPE 37 | ), 38 | array( 39 | 'label' => $this->_getHelper()->__('No Link'), 40 | 'value' => self::NO_LINK 41 | ) 42 | ); 43 | } 44 | return $this->_options; 45 | } 46 | 47 | private function _getHelper() 48 | { 49 | return Mage::helper('theextensionlab_megamenu'); 50 | } 51 | } -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/Model/Config/Source/List/Columns.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | 11 | class TheExtensionLab_MegaMenu_Model_Config_Source_List_Columns 12 | { 13 | public function toOptionArray() 14 | { 15 | $maxColumns = 5; 16 | $options = array(); 17 | for($i = 1;$i <= $maxColumns;$i++) 18 | { 19 | $options[] = array( 20 | 'value' => $i, 21 | 'label' => $i 22 | ); 23 | } 24 | 25 | return $options; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/Model/Menu/Attributes.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | 11 | class TheExtensionLab_MegaMenu_Model_Menu_Attributes 12 | { 13 | private $_extraAttributes = array(); 14 | 15 | public function __construct() 16 | { 17 | $this->_getExtraAttributesFromConfig(); 18 | } 19 | 20 | public function addExtraAttributesToSelect($categoryCollection) 21 | { 22 | foreach ($this->_extraAttributes as $extraAttribute) { 23 | $categoryCollection->addAttributeToSelect($extraAttribute); 24 | } 25 | } 26 | 27 | public function addExtraFlatAttributesToSelect($select) 28 | { 29 | $select->columns($this->_extraAttributes); 30 | } 31 | 32 | private function _getExtraAttributesFromConfig() 33 | { 34 | $extraAttributes = Mage::getConfig()->getNode('theextensionlab_megamenu/extra_attributes')->asArray(); 35 | foreach ($extraAttributes as $attributeCode => $value) { 36 | if (!$this->_isAttributeDisabled($value)) { 37 | $this->_extraAttributes[] = $attributeCode; 38 | } 39 | } 40 | } 41 | 42 | private function _isAttributeDisabled($value) 43 | { 44 | if (isset($value['disabled'])) { 45 | if ($value['disabled'] == true) { 46 | return true; 47 | } 48 | } 49 | 50 | return false; 51 | } 52 | } -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/Model/Menu/Populator.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | 11 | class TheExtensionLab_MegaMenu_Model_Menu_Populator 12 | extends Mage_Catalog_Model_Observer 13 | { 14 | 15 | public function addCategoriesToMenu($menu, $block) 16 | { 17 | $storeCategories = $this->_getCategoryHelper()->getStoreCategories(); 18 | $this->_addCategoriesToMenuParentNode($storeCategories, $menu, $block, true); 19 | } 20 | 21 | private function _addCategoriesToMenuParentNode($categories, $parentCategoryNode, $menuBlock, $addTags = false) 22 | { 23 | foreach ($categories as $category) { 24 | if (!$this->_canAddToMenu($category)) { 25 | continue; 26 | } 27 | 28 | $this->_addCacheTagsToModel($category, $menuBlock, $addTags); //Why? 29 | 30 | $categoryData = $this->_getCategoryMenuData($category); 31 | 32 | $categoryNode = $this->_createTreeNode($categoryData, $parentCategoryNode); 33 | $parentCategoryNode->addChild($categoryNode); 34 | 35 | $subcategories = $this->_getSubCategories($category); 36 | 37 | if($subcategories !== null) { 38 | $this->_addCategoriesToMenuParentNode( 39 | $subcategories, $categoryNode, $menuBlock, $addTags 40 | ); 41 | } 42 | } 43 | } 44 | 45 | private function _getCategoryMenuData($category) 46 | { 47 | Mage::dispatchEvent('menu_get_category_menu_data_before', array('category' => $category)); 48 | 49 | $categoryMenuData = new Varien_Object( 50 | array( 51 | 'name' => $this->_getCategoryHelper()->getMenuName($category), 52 | 'id' => $this->_getNodeId($category->getId()), 53 | 'url' => $this->_getCategoryUrlHelper()->getCategoryUrl($category), 54 | 'is_active' => $this->_isActiveMenuCategory($category), 55 | 'columns' => $this->_getCategoryColumns($category), 56 | 'image' => $category->getImage(), 57 | 'menu_dropdown_width' => $category->getMenuDropdownWidth(), 58 | 'menu_dropdown_type' => $category->getMenuDropdownType(), 59 | 'include_in_menu' => $category->getIncludeInMenu(), 60 | 'menu_link_type' => $category->getMenuLinkType() 61 | ) 62 | ); 63 | 64 | Mage::dispatchEvent( 65 | 'menu_get_category_menu_data_after', 66 | array('category' => $category, 'category_menu_data' => $categoryMenuData) 67 | ); 68 | 69 | return $categoryMenuData->getData(); 70 | } 71 | 72 | private function _getNodeId($categoryId) 73 | { 74 | $prefix = 'category-node'; 75 | return $prefix . '-' . $categoryId; 76 | } 77 | 78 | private function _getSubCategories($category) 79 | { 80 | if(Mage::helper('catalog/category_flat')->isEnabled() && Mage::helper('catalog/category_flat')->isBuilt()) { 81 | $subcategories = $category->getChildrenNodes(); 82 | } else { 83 | $subcategories = $category->getChildren(); 84 | } 85 | 86 | return $subcategories; 87 | } 88 | 89 | private function _getCategoryColumns($category) 90 | { 91 | $columns = array(); 92 | $maxColumns = Mage::getStoreConfig('catalog/navigation/sections_count'); 93 | 94 | for ($i = 1; $i <= $maxColumns; $i++) { 95 | $colWidth = $category->getData('menu_section_' . $i . '_column_width'); 96 | $colContent = $category->getData('menu_section_' . $i . '_content'); 97 | $columns['column_' . $i] = array( 98 | 'col_width' => $colWidth, 99 | 'content' => $colContent, 100 | 'column_number' => $i 101 | ); 102 | } 103 | 104 | return $columns; 105 | } 106 | 107 | private function _createTreeNode($categoryData, $parentCategoryNode) 108 | { 109 | $tree = $parentCategoryNode->getTree(); 110 | $categoryNode = new Varien_Data_Tree_Node($categoryData, 'id', $tree, $parentCategoryNode); 111 | 112 | return $categoryNode; 113 | } 114 | 115 | private function _addCacheTagsToModel($category, $menuBlock, $addTags) 116 | { 117 | $categoryModel = Mage::getModel('catalog/category'); 118 | $categoryModel->setId($category->getId()); 119 | if ($addTags) { 120 | $menuBlock->addModelTags($categoryModel); 121 | } 122 | } 123 | 124 | private function _canAddToMenu($category) 125 | { 126 | return ($category->getIsActive() || $category->getMenuLinkType() == 1 || $category->getMenuLinkType() == 2 127 | || $category->getMenuLinkType() == 3); 128 | } 129 | 130 | /** 131 | * @return TheExtensionLab_MegaMenu_Helper_Category 132 | */ 133 | private function _getCategoryHelper() 134 | { 135 | return Mage::helper('theextensionlab_megamenu/category'); 136 | } 137 | 138 | /** 139 | * @return TheExtensionLab_MegaMenu_Helper_Category_Url 140 | */ 141 | private function _getCategoryUrlHelper() 142 | { 143 | return Mage::helper('theextensionlab_megamenu/category_url'); 144 | } 145 | } -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/Model/Observer.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | 11 | class TheExtensionLab_MegaMenu_Model_Observer 12 | { 13 | private $_menuKey = 'current_menu'; 14 | 15 | public function pageBlockHtmlTopmenuGetHtmlBefore(Varien_Event_Observer $observer) 16 | { 17 | $block = $observer->getBlock(); 18 | $block->addCacheTag(Mage_Catalog_Model_Category::CACHE_TAG); 19 | 20 | $menu = $observer->getMenu(); 21 | 22 | if(!$this->_isMenuTreeAlreadyStored()){ 23 | $this->_getMenuPopulator()->addCategoriesToMenu($menu, $block); 24 | Mage::register($this->_menuKey, $menu); 25 | } 26 | } 27 | 28 | public function enableWysiwygInWysiwygConfig(Varien_Event_Observer $observer) 29 | { 30 | $wysiwygConfig = $observer->getEvent()->getConfig(); 31 | $wysiwygConfig->setAddWidgets('true'); 32 | } 33 | 34 | public function catalogCategoryFlatLoadnodesBefore(Varien_Event_Observer $observer) { 35 | $select = $observer->getSelect(); 36 | $this->_getMenuAttributesModel()->addExtraFlatAttributesToSelect($select); 37 | } 38 | 39 | public function catalogCategoryCollectionLoadBefore(Varien_Event_Observer $observer){ 40 | $categoryCollection = $observer->getEvent()->getCategoryCollection(); 41 | $this->_getMenuAttributesModel()->addExtraAttributesToSelect($categoryCollection); 42 | } 43 | 44 | public function cmsPagePrepareSave(Varien_Event_Observer $observer) 45 | { 46 | $pageModel = $observer->getPage(); 47 | 48 | try { 49 | $path = Mage::getBaseDir('media') . DS . 'cms' . DS . 'menu' . DS; 50 | if (isset($_FILES['menu_image'])) { 51 | $uploader = new Mage_Core_Model_File_Uploader('menu_image'); 52 | $uploader->setAllowedExtensions(array('jpg', 'jpeg', 'gif', 'png')); 53 | $uploader->setAllowRenameFiles(true); 54 | $result = $uploader->save($path); 55 | 56 | $pageModel->setMenuImage($result['file']); 57 | } 58 | } catch (Exception $e) { 59 | Mage::logException($e); 60 | } 61 | } 62 | 63 | public function adminhtmlBlockHtmlBefore(Varien_Event_Observer $observer) 64 | { 65 | $block = $observer->getBlock(); 66 | if($block instanceof Mage_Adminhtml_Block_Catalog_Category_Tab_Attributes) { 67 | $this->_getConfigDependancyModel()->addCategoryFieldDependancys($block); 68 | } 69 | 70 | if($block instanceof Mage_Adminhtml_Block_Cms_Page_Edit_Form) 71 | { 72 | $form = $block->getForm(); 73 | $form->setEnctype('multipart/form-data'); 74 | } 75 | } 76 | 77 | private function _isMenuTreeAlreadyStored(){ 78 | if(Mage::registry($this->_menuKey) == null){ 79 | return false; 80 | } 81 | 82 | return true; 83 | } 84 | 85 | private function _getConfigDependancyModel() 86 | { 87 | return Mage::getModel('theextensionlab_megamenu/config_dependancy'); 88 | } 89 | 90 | private function _getMenuPopulator() 91 | { 92 | return Mage::getModel('theextensionlab_megamenu/menu_populator'); 93 | } 94 | 95 | private function _getMenuAttributesModel() 96 | { 97 | return Mage::getModel('theextensionlab_megamenu/menu_attributes'); 98 | } 99 | 100 | private function _getConfigUpdater() 101 | { 102 | return Mage::getModel('theextensionlab_megamenu/config_updater'); 103 | } 104 | 105 | private function _getProtectorHelper() 106 | { 107 | return Mage::helper('theextensionlab_megamenu/protector'); 108 | } 109 | } -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/Model/Parser.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | 11 | class TheExtensionLab_MegaMenu_Model_Parser extends Mage_Widget_Model_Template_Filter 12 | { 13 | private $_directiveValues = array(); 14 | private $_parsers = array(); 15 | 16 | public function __construct($defaultParsers) 17 | { 18 | $this->_parsers = $defaultParsers; 19 | } 20 | 21 | public function getDirectiveValues($value) 22 | { 23 | if ($constructions = $this->_matchConstructionPattern($value)) { 24 | foreach ($constructions as $index => $construction) { 25 | $this->_callPrefetchDirective($construction); 26 | } 27 | } 28 | 29 | return $this->_directiveValues; 30 | } 31 | 32 | public function _matchConstructionPattern($value) 33 | { 34 | preg_match_all(self::CONSTRUCTION_PATTERN, $value, $constructions, PREG_SET_ORDER); 35 | return $constructions; 36 | } 37 | 38 | public function setChildParser($key,$modelAlias){ 39 | $this->_parsers[$key] = $modelAlias; 40 | } 41 | 42 | private function _callPrefetchDirective($construction) 43 | { 44 | $callback = array($this, $construction[1] . 'PrefetchDirective'); 45 | if ($this->isDirectiveIsCallable($callback)) { 46 | call_user_func($callback, $construction); 47 | } 48 | } 49 | 50 | private function isDirectiveIsCallable($callback) 51 | { 52 | return is_callable($callback); 53 | } 54 | 55 | private function widgetPrefetchDirective($construction) 56 | { 57 | $params = $this->_getIncludeParameters($construction[2]); 58 | 59 | foreach ($this->_parsers as $modelAlias) { 60 | $this->getConfigDataToPrefetchFromConstruction($modelAlias, $params); 61 | } 62 | } 63 | 64 | private function getConfigDataToPrefetchFromConstruction($modelAlias, $params) 65 | { 66 | $parser = Mage::getModel($modelAlias); 67 | if ($this->isMegaMenuParserInstance($parser)) { 68 | $directiveValues = $parser->parse($params); 69 | $this->_directiveValues = array_merge_recursive($this->_directiveValues, $directiveValues); 70 | } 71 | } 72 | 73 | private function isMegaMenuParserInstance($parser) 74 | { 75 | return $parser instanceof TheExtensionLab_MegaMenu_Model_Parser_Interface; 76 | } 77 | } -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/Model/Parser/Attribute/Option.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | 11 | class TheExtensionLab_MegaMenu_Model_Parser_Attribute_Option 12 | implements TheExtensionLab_MegaMenu_Model_Parser_Interface 13 | { 14 | public function parse($params) 15 | { 16 | $prefetchConfig = array(); 17 | if($this->_hasValuesRequiredForAttributeOptions($params)) { 18 | 19 | $optionIds = json_decode($params['option_ids'],1); 20 | $prefetchConfig['option_ids'] = array_keys($optionIds); 21 | 22 | if($this->_hasCategoryIdRequiredForRewritePath($params)) { 23 | $prefetchConfig['rewrite_ids'][] = 'category/' . $params['category_id']; 24 | } 25 | } 26 | 27 | return $prefetchConfig; 28 | } 29 | 30 | private function _hasCategoryIdRequiredForRewritePath($params) 31 | { 32 | return isset($params['category_id']); 33 | } 34 | 35 | private function _hasValuesRequiredForAttributeOptions($params) 36 | { 37 | return isset($params['option_ids']); 38 | } 39 | } -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/Model/Parser/Cms/Block.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | 11 | class TheExtensionLab_MegaMenu_Model_Parser_Cms_Block 12 | implements TheExtensionLab_MegaMenu_Model_Parser_Interface 13 | { 14 | public function parse($params) 15 | { 16 | $prefetchConfig = array(); 17 | if ($this->_hasValidBlockId($params)){ 18 | $prefetchConfig['static_block_ids'][] = $params['menu_static_block_id']; 19 | } 20 | return $prefetchConfig; 21 | } 22 | 23 | private function _hasValidBlockId($params) 24 | { 25 | if (!isset($params['menu_static_block_id'])) { 26 | return false; 27 | } 28 | 29 | return is_numeric($params['menu_static_block_id']); 30 | } 31 | } -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/Model/Parser/Cms/Page/Featured.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | 11 | class TheExtensionLab_MegaMenu_Model_Parser_Cms_Page_Featured 12 | implements TheExtensionLab_MegaMenu_Model_Parser_Interface 13 | { 14 | public function parse($params) 15 | { 16 | $prefetchConfig = array(); 17 | if ($this->_hasValidCmsId($params)) { 18 | $prefetchConfig['cms_page_ids'][] = $params['menu_featured_cms_id']; 19 | } 20 | 21 | return $prefetchConfig; 22 | } 23 | 24 | private function _hasValidCmsId($params) 25 | { 26 | if (!isset($params['menu_featured_cms_id'])) { 27 | return false; 28 | } 29 | 30 | return is_numeric($params['menu_featured_cms_id']); 31 | } 32 | } -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/Model/Parser/Interface.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | 11 | interface TheExtensionLab_MegaMenu_Model_Parser_Interface 12 | { 13 | public function parse($params); 14 | } -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/Model/Parser/Product/Featured.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | 11 | class TheExtensionLab_MegaMenu_Model_Parser_Product_Featured 12 | implements TheExtensionLab_MegaMenu_Model_Parser_Interface 13 | { 14 | public function parse($params) 15 | { 16 | $prefetchConfig = array(); 17 | if ($this->_hasValuesRequiredForFeaturedProducts($params)) { 18 | $prefetchConfig['product_ids'] = array_keys($this->_getFeaturedProductIdsAsArray($params)); 19 | } 20 | 21 | return $prefetchConfig; 22 | } 23 | 24 | private function _getFeaturedProductIdsAsArray($params) 25 | { 26 | $featuredProductIdsJsonString = $params['megamenu_featured_product_ids']; 27 | $featuredProductData = json_decode($featuredProductIdsJsonString, 1); 28 | return $featuredProductData; 29 | } 30 | 31 | private function _hasValuesRequiredForFeaturedProducts($params) 32 | { 33 | return isset($params['megamenu_featured_product_ids']); 34 | } 35 | } -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/Model/Parser/Url/Rewrite.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | 11 | class TheExtensionLab_MegaMenu_Model_Parser_Url_Rewrite 12 | implements TheExtensionLab_MegaMenu_Model_Parser_Interface 13 | { 14 | public function parse($params) 15 | { 16 | $prefetchConfig = array(); 17 | if ($this->_hasValuesRequiredForRewrite()) { 18 | $this->_getRewriteIdPathsForOptions($params); 19 | } 20 | 21 | return $prefetchConfig; 22 | } 23 | 24 | private function _getRewriteIdPathsForOptions($params) 25 | { 26 | $optionIds = json_decode($params['option_ids']); 27 | $categoryId = $params['category_id']; 28 | foreach ($optionIds as $key => $value) { 29 | $prefetchConfig['rewrite_ids'][] = 'category/' . $categoryId; 30 | } 31 | 32 | return $optionIds; 33 | } 34 | 35 | private function _hasValuesRequiredForRewrite() 36 | { 37 | return isset($params['option_ids']) && isset($params['category_id']); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/Model/Prefetcher.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | class TheExtensionLab_MegaMenu_Model_Prefetcher 11 | { 12 | private $_prefetchModels = array(); 13 | private $_parser = array(); 14 | private $_directiveValues = array(); 15 | 16 | public function __construct() 17 | { 18 | $this->_prepareChildModels(); 19 | } 20 | 21 | public function prefetch($value) 22 | { 23 | $this->_getDirectiveValues($value); 24 | $this->_prefetchWaitingData(); 25 | } 26 | 27 | public function setChildPrefetcher($key,$modelAlias){ 28 | $this->_prefetchModels[$key] = $modelAlias; 29 | } 30 | 31 | private function _prepareChildModels() 32 | { 33 | $this->_prefetchModels = $this->_getDefaultPrefetchers(); 34 | $this->_parser = Mage::getModel('theextensionlab_megamenu/parser', $this->_getDefaultParsers()); 35 | $this->_dispatchEventToAllowPrefetchAndParserModelUpdates(); 36 | } 37 | 38 | private function _dispatchEventToAllowPrefetchAndParserModelUpdates() 39 | { 40 | Mage::dispatchEvent( 41 | 'megamenu_prepare_prefetch_models_after', array('prefetcher' => $this, 'parser' => $this->_parser) 42 | ); 43 | } 44 | 45 | private function _getDefaultPrefetchers() 46 | { 47 | return array( 48 | 'product' => 'theextensionlab_megamenu/prefetcher_product', 49 | 'attribute_option' => 'theextensionlab_megamenu/prefetcher_attribute_option', 50 | 'attribute' => 'theextensionlab_megamenu/prefetcher_attribute', 51 | 'url_rewrite' => 'theextensionlab_megamenu/prefetcher_url_rewrite', 52 | 'cms_page' => 'theextensionlab_megamenu/prefetcher_cms_page', 53 | 'cms_block' => 'theextensionlab_megamenu/prefetcher_cms_block' 54 | ); 55 | } 56 | 57 | private function _getDefaultParsers() 58 | { 59 | return array( 60 | 'featured_product' => 'theextensionlab_megamenu/parser_product_featured', 61 | 'attribute_option' => 'theextensionlab_megamenu/parser_attribute_option', 62 | 'url_rewrite' => 'theextensionlab_megamenu/parser_url_rewrite', 63 | 'featured_cms_page' => 'theextensionlab_megamenu/parser_cms_page_featured', 64 | 'cms_block' => 'theextensionlab_megamenu/parser_cms_block' 65 | ); 66 | } 67 | 68 | private function _getDirectiveValues($value) 69 | { 70 | $this->_directiveValues = $this->_parser->getDirectiveValues($value); 71 | } 72 | 73 | 74 | private function _prefetchWaitingData() 75 | { 76 | Varien_Profiler::start('megamenu_prefetch_and_store_data'); 77 | 78 | foreach ($this->_prefetchModels as $modelAlias) { 79 | $model = Mage::getModel($modelAlias); 80 | if (is_callable(array($model, 'prefetchData'))) { 81 | $model->prefetchData($this->_directiveValues); 82 | } 83 | } 84 | 85 | Varien_Profiler::stop('megamenu_prefetch_and_store_data'); 86 | } 87 | 88 | } -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/Model/Prefetcher/Attribute.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | 11 | class TheExtensionLab_MegaMenu_Model_Prefetcher_Attribute 12 | implements TheExtensionLab_MegaMenu_Model_Prefetcher_Interface 13 | { 14 | public function prefetchData(&$directiveValues) 15 | { 16 | if(isset($directiveValues['attribute_ids'])) { 17 | $collection = $this->getAttributeCollection($directiveValues['attribute_ids']); 18 | $attributeIdArray = $this->getAttributeIdsArrayFromCollection($collection); 19 | 20 | Mage::register('megamenu_attributes', $attributeIdArray); 21 | } 22 | } 23 | 24 | private function getAttributeIdsArrayFromCollection($collection) 25 | { 26 | $attributeIdArray = array(); 27 | 28 | foreach ($collection as $attribute) { 29 | $attributeIdArray[$attribute->getAttributeId()] = $attribute; 30 | } 31 | 32 | return $attributeIdArray; 33 | } 34 | 35 | private function getAttributeCollection(array $attributeIds) 36 | { 37 | return Mage::getResourceModel('catalog/product_attribute_collection') 38 | ->addFieldToFilter('main_table.attribute_id', array('in' => $attributeIds)) 39 | ->addVisibleFilter(); 40 | } 41 | } -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/Model/Prefetcher/Attribute/Option.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | 11 | class TheExtensionLab_MegaMenu_Model_Prefetcher_Attribute_Option 12 | implements TheExtensionLab_MegaMenu_Model_Prefetcher_Interface 13 | { 14 | public function prefetchData(&$directiveValues) 15 | { 16 | if(isset($directiveValues['option_ids'])){ 17 | $collection = $this->getAttributeOptionCollection($directiveValues['option_ids']); 18 | 19 | if(!isset($directiveValues['attribute_ids'])) 20 | { 21 | $directiveValues['attribute_ids'] = array(); 22 | } 23 | 24 | $optionIdArray = $this->getOptionIds($collection); 25 | $directiveValues = $this->storeOptionParentAttributeIds($collection, $directiveValues); 26 | 27 | Mage::register('megamenu_attribute_options', $optionIdArray); 28 | } 29 | } 30 | 31 | private function getAttributeOptionCollection(array $optionIds) 32 | { 33 | $storeId = Mage::app()->getStore()->getStoreId(); 34 | 35 | return Mage::getResourceModel('eav/entity_attribute_option_collection') 36 | ->addFieldToFilter('main_table.option_id', array('in' => $optionIds)) 37 | ->setStoreFilter($storeId, true); 38 | } 39 | 40 | private function getOptionIds($collection) 41 | { 42 | $optionIdArray = array(); 43 | foreach ($collection as $option) { 44 | $optionIdArray[$option->getOptionId()] = $option; 45 | } 46 | 47 | return $optionIdArray; 48 | } 49 | 50 | private function storeOptionParentAttributeIds($collection, $directiveValues) 51 | { 52 | foreach ($collection as $option) { 53 | if (!in_array($option->getAttributeId(), $directiveValues['attribute_ids'])) { 54 | $directiveValues['attribute_ids'][] = $option->getAttributeId(); 55 | } 56 | } 57 | 58 | return $directiveValues; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/Model/Prefetcher/Cms/Block.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | 11 | class TheExtensionLab_MegaMenu_Model_Prefetcher_Cms_Block implements TheExtensionLab_MegaMenu_Model_Prefetcher_Interface 12 | { 13 | public function prefetchData(&$directiveValues){ 14 | if(isset($directiveValues['static_block_ids'])) 15 | { 16 | $blockCollection = Mage::getModel('cms/block')->getCollection() 17 | ->addFieldToFilter('block_id', array('in' => $directiveValues['static_block_ids'])) 18 | ->load(); 19 | 20 | $this->_filterBlockCollectionContent($blockCollection); 21 | 22 | Mage::register('megamenu_cms_blocks', $blockCollection); 23 | } 24 | } 25 | 26 | private function _filterBlockCollectionContent($blockCollection) 27 | { 28 | foreach ($blockCollection as $block) { 29 | $helper = Mage::helper('cms'); 30 | $processor = $helper->getBlockTemplateProcessor(); 31 | $block->setContent($processor->filter($block->getContent())); 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/Model/Prefetcher/Cms/Page.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | 11 | class TheExtensionLab_MegaMenu_Model_Prefetcher_Cms_Page implements TheExtensionLab_MegaMenu_Model_Prefetcher_Interface 12 | { 13 | public function prefetchData(&$directiveValues) 14 | { 15 | if(isset($directiveValues['cms_page_ids'])) 16 | { 17 | $pageCollection = Mage::getModel('cms/page')->getCollection() 18 | ->addFieldToFilter('page_id', array('in' => $directiveValues['cms_page_ids'])) 19 | ->load(); 20 | 21 | Mage::register('megamenu_cms_pages', $pageCollection); 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/Model/Prefetcher/Interface.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | 11 | interface TheExtensionLab_MegaMenu_Model_Prefetcher_Interface 12 | { 13 | public function prefetchData(&$directiveValues); 14 | } 15 | -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/Model/Prefetcher/Product.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | 11 | class TheExtensionLab_MegaMenu_Model_Prefetcher_Product 12 | implements TheExtensionLab_MegaMenu_Model_Prefetcher_Interface 13 | { 14 | 15 | public function prefetchData(&$directiveValues) 16 | { 17 | if ($this->_hasProductsToLoad($directiveValues)) { 18 | $featuredProductLimit = 20; 19 | 20 | $featuredProductsCollection = Mage::getModel('catalog/product')->getCollection() 21 | ->addAttributeToFilter('entity_id', array('in' => $directiveValues['product_ids'])) 22 | ->addAttributeToSelect(array('name', 'menu_image', 'price', 'special_price', 'url_key')) 23 | ->addFinalPrice() 24 | ->setPageSize($featuredProductLimit) 25 | ->load(); 26 | 27 | Mage::register('megamenu_products_collection', $featuredProductsCollection); 28 | } 29 | } 30 | 31 | protected function _hasProductsToLoad($directiveValues) 32 | { 33 | return isset($directiveValues['product_ids']); 34 | } 35 | 36 | } -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/Model/Prefetcher/Url/Rewrite.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | 11 | class TheExtensionLab_MegaMenu_Model_Prefetcher_Url_Rewrite 12 | implements TheExtensionLab_MegaMenu_Model_Prefetcher_Interface 13 | { 14 | public function prefetchData(&$directiveValues) 15 | { 16 | Varien_Profiler::start('megamenu_url_rewrites_prefetching'); 17 | 18 | if(isset($directiveValues['rewrite_ids'])){ 19 | $rewritesCollection = $this->getRewritesCollection($directiveValues['rewrite_ids']); 20 | $rewriteIdPaths = $this->getRewriteIdPathsFromCollection($rewritesCollection); 21 | 22 | Mage::register('megamenu_url_rewrites', $rewriteIdPaths); 23 | } 24 | 25 | Varien_Profiler::stop('megamenu_url_rewrites_prefetching'); 26 | } 27 | 28 | private function getRewritesCollection(array $rewriteIds) 29 | { 30 | return Mage::getModel('core/url_rewrite')->getCollection() 31 | ->addFieldToFilter('id_path', array('in' => $rewriteIds)); 32 | } 33 | 34 | private function getRewriteIdPathsFromCollection($collection) 35 | { 36 | $rewriteIdPaths = array(); 37 | 38 | foreach ($collection as $rewrite) { 39 | $rewriteIdPaths[$rewrite->getIdPath()] = $rewrite; 40 | } 41 | 42 | return $rewriteIdPaths; 43 | } 44 | 45 | } -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/Model/Resource/Category/Flat.php: -------------------------------------------------------------------------------- 1 | _getReadAdapter()->select() 7 | ->from(array('mt' => $this->getMainStoreTable($this->getStoreId())), array('path')) 8 | ->where('mt.entity_id = ?', $parent); 9 | $parentPath = $this->_getReadAdapter()->fetchOne($select); 10 | 11 | $collection = Mage::getModel('catalog/category')->getCollection() 12 | ->addNameToResult() 13 | ->addUrlRewriteToResult() 14 | ->addParentPathFilter($parentPath) 15 | ->addStoreFilter() 16 | ->addAttributeToFilter('include_in_menu', 1) 17 | ->addSortedField($sorted); 18 | if ($toLoad) { 19 | return $collection->load(); 20 | } 21 | return $collection; 22 | } 23 | return $this->getNodes($parent, $recursionLevel, Mage::app()->getStore()->getId()); 24 | } 25 | 26 | public function getNodes($parentId, $recursionLevel = 0, $storeId = 0) 27 | { 28 | if (!$this->_loaded) { 29 | $selectParent = $this->_getReadAdapter()->select() 30 | ->from($this->getMainStoreTable($storeId)) 31 | ->where('entity_id = ?', $parentId); 32 | if ($parentNode = $this->_getReadAdapter()->fetchRow($selectParent)) { 33 | $parentNode['id'] = $parentNode['entity_id']; 34 | $parentNode = Mage::getModel('catalog/category')->setData($parentNode); 35 | $this->_nodes[$parentNode->getId()] = $parentNode; 36 | $nodes = $this->_loadNodes($parentNode, $recursionLevel, $storeId, false); 37 | $childrenItems = array(); 38 | foreach ($nodes as $node) { 39 | $pathToParent = explode('/', $node->getPath()); 40 | array_pop($pathToParent); 41 | $pathToParent = implode('/', $pathToParent); 42 | $childrenItems[$pathToParent][] = $node; 43 | } 44 | $this->addChildNodes($childrenItems, $parentNode->getPath(), $parentNode); 45 | $childrenNodes = $this->_nodes[$parentNode->getId()]; 46 | if ($childrenNodes->getChildrenNodes()) { 47 | $this->_nodes = $childrenNodes->getChildrenNodes(); 48 | } 49 | else { 50 | $this->_nodes = array(); 51 | } 52 | $this->_loaded = true; 53 | } 54 | } 55 | return $this->_nodes; 56 | } 57 | 58 | } -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/Model/Template/Filter.php: -------------------------------------------------------------------------------- 1 | 'dependDirective', 15 | self::CONSTRUCTION_IF_PATTERN => 'ifDirective', 16 | ) as $pattern => $directive) { 17 | if (preg_match_all($pattern, $value, $constructions, PREG_SET_ORDER)) { 18 | foreach($constructions as $index => $construction) { 19 | $replacedValue = ''; 20 | $callback = array($this, $directive); 21 | if(!is_callable($callback)) { 22 | continue; 23 | } 24 | try { 25 | $replacedValue = call_user_func($callback, $construction); 26 | } catch (Exception $e) { 27 | Mage::logException($e); 28 | } 29 | $value = str_replace($construction[0], $replacedValue, $value); 30 | } 31 | } 32 | } 33 | 34 | if(preg_match_all(self::CONSTRUCTION_PATTERN, $value, $constructions, PREG_SET_ORDER)) { 35 | foreach($constructions as $index=>$construction) { 36 | $replacedValue = ''; 37 | $callback = array($this, $construction[1].'Directive'); 38 | if(!is_callable($callback)) { 39 | continue; 40 | } 41 | try { 42 | $replacedValue = call_user_func($callback, $construction); 43 | } catch (Exception $e) { 44 | Mage::logException($e); 45 | } 46 | $value = str_replace($construction[0], $replacedValue, $value); 47 | } 48 | } 49 | return $value; 50 | } catch (Exception $e) { 51 | $value = ''; 52 | Mage::logException($e); 53 | } 54 | return $value; 55 | } 56 | } -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/Test/Block/Widget/Cms/Page/Featured.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | 11 | class TheExtensionLab_MegaMenu_Test_Block_Widget_Cms_Page_Featured extends EcomDev_PHPUnit_Test_Case 12 | { 13 | public function testFeaturedBlockImplementsWidgetBlockInterface() 14 | { 15 | $class = new ReflectionClass('TheExtensionLab_MegaMenu_Block_Widget_Cms_Page_Featured'); 16 | $this->assertTrue($class->implementsInterface('Mage_Widget_Block_Interface')); 17 | } 18 | } -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/Test/Config/Main.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | 11 | class TheExtensionLab_MegaMenu_Test_Config_Main 12 | extends EcomDev_PHPUnit_Test_Case_Config 13 | { 14 | public function testClassAliases() 15 | { 16 | $this->assertBlockAlias( 17 | 'theextensionlab_megamenu/block', 18 | 'TheExtensionLab_MegaMenu_Block_Block' 19 | ); 20 | $this->assertHelperAlias( 21 | 'theextensionlab_megamenu', 22 | 'TheExtensionLab_MegaMenu_Helper_Data' 23 | ); 24 | $this->assertModelAlias( 25 | 'theextensionlab_megamenu/example', 26 | 'TheExtensionLab_MegaMenu_Model_Example' 27 | ); 28 | } 29 | 30 | public function testSetupResources() 31 | { 32 | $this->assertSetupResourceDefined(); 33 | $this->assertSetupResourceExists(); 34 | } 35 | 36 | public function testFeaturedCmsWidgetNodeExists() 37 | { 38 | $widgetConfig = Mage::getModel('widget/widget'); 39 | $widgetsArray = $widgetConfig->getWidgetsArray(); 40 | 41 | 42 | $this->_assertArrayContainsFeaturedCmsBlock($widgetsArray); 43 | } 44 | 45 | private function _assertArrayContainsFeaturedCmsBlock($widgetsArray) 46 | { 47 | $configContainsCmsFeaturedWidget = false; 48 | foreach ($widgetsArray as $widget) { 49 | if ($widget['code'] == 'featured_cms_page_menu_block' 50 | && $widget['type'] == 'theextensionlab_megamenu/widget_cms_page_featured' 51 | ) { 52 | $configContainsCmsFeaturedWidget = true; 53 | break; 54 | } 55 | } 56 | $this->assertTrue($configContainsCmsFeaturedWidget); 57 | } 58 | 59 | public function testFeaturedCmsWidgetContainsParams() 60 | { 61 | $widgetConfig = Mage::getModel('widget/widget'); 62 | $widgetXml = $widgetConfig->getWidgetsXml(); 63 | foreach ($widgetXml as $code => $widget) { 64 | if ($code == 'featured_cms_page_menu_block') { 65 | $params = $widget->parameters; 66 | $reflection = new ReflectionObject($params); 67 | $this->assertTrue($reflection->hasProperty('title')); 68 | $this->assertTrue($reflection->hasProperty('menu_featured_cms_id')); 69 | $this->assertTrue($reflection->hasProperty('display_on')); 70 | $this->assertTrue($reflection->hasProperty('template')); 71 | } 72 | } 73 | } 74 | 75 | 76 | } -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/Test/Model/Menu/Attributes.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | 11 | class TheExtensionLab_MegaMenu_Test_Model_Menu_Attributes extends EcomDev_PHPUnit_Test_Case 12 | { 13 | private $_attributesModel; 14 | 15 | public function setUp() 16 | { 17 | $this->_attributesModel = new TheExtensionLab_MegaMenu_Model_Menu_Attributes; 18 | } 19 | 20 | /** 21 | * @loadFixture 22 | */ 23 | public function testAttributesConfigGetter() 24 | { 25 | $extraAttributes = $this->_getExtraAttributeByReflection(); 26 | 27 | $this->assertTrue(in_array('a_test_attribute', $extraAttributes)); 28 | $this->assertFalse(in_array('a_disabled_test_attribute', $extraAttributes)); 29 | } 30 | 31 | private function _getExtraAttributeByReflection() 32 | { 33 | $reflectionClass = new \ReflectionClass('TheExtensionLab_MegaMenu_Model_Menu_Attributes'); 34 | $reflectionMethod = $reflectionClass->getMethod('_getExtraAttributesFromConfig'); 35 | $reflectionMethod->setAccessible(true); 36 | 37 | $reflectionProperty = $reflectionClass->getProperty('_extraAttributes'); 38 | $reflectionProperty->setAccessible(true); 39 | 40 | $reflectionMethod->invokeArgs($this->_attributesModel, array()); 41 | 42 | $extraAttributes = $reflectionProperty->getValue($this->_attributesModel); 43 | 44 | return $extraAttributes; 45 | } 46 | 47 | public function testExtraAttributesAddedToFlatSelect() 48 | { 49 | $mockSelect = $this->getMock('TheExtensionLab_MegaMenu_Test_Model_Menu_DbAdapterMock', array('columns')); 50 | $mockSelect->expects($this->once()) 51 | ->method('columns'); 52 | 53 | $this->_attributesModel->addExtraFlatAttributesToSelect($mockSelect); 54 | } 55 | 56 | public function testExtraAttributesAddedToEavSelect() 57 | { 58 | $mockCategoryCollection = $this->getMock( 59 | 'TheExtensionLab_MegaMenu_Test_Model_Menu_CategoryCollectionMock', array('addAttributeToSelect') 60 | ); 61 | $mockCategoryCollection->expects($this->atLeastOnce()) 62 | ->method('addAttributeToSelect'); 63 | 64 | $this->_attributesModel->addExtraAttributesToSelect($mockCategoryCollection); 65 | } 66 | } -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/Test/Model/Menu/CategoryCollectionMock.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | 11 | class TheExtensionLab_MegaMenu_Test_Model_Menu_CategoryCollectionMock 12 | { 13 | public function addAttributeToSelect() 14 | { 15 | 16 | } 17 | } -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/Test/Model/Menu/DbAdapterMock.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | 11 | class TheExtensionLab_MegaMenu_Test_Model_Menu_DbAdapterMock 12 | { 13 | public function columns() 14 | { 15 | 16 | } 17 | } -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/Test/Model/Menu/fixtures/testAttributesConfigGetter.yaml: -------------------------------------------------------------------------------- 1 | config: 2 | theextensionlab_megamenu/extra_attributes/a_test_attribute: 3 | theextensionlab_megamenu/extra_attributes/a_disabled_test_attribute/disabled:1 -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/Test/Model/Parser.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | 11 | class TheExtensionLab_MegaMenu_Test_Model_Parser extends PHPUnit_Framework_TestCase 12 | { 13 | private $parser; 14 | 15 | public function setUp() 16 | { 17 | $defaultParsers = array( 18 | 'featured_product' => 'theextensionlab_megamenu/parser_product_featured', 19 | 'attribute_option' => 'theextensionlab_megamenu/parser_attribute_option', 20 | 'url_rewrite' => 'theextensionlab_megamenu/parser_url_rewrite' 21 | ); 22 | 23 | $this->parser = new TheExtensionLab_MegaMenu_Model_Parser($defaultParsers); 24 | } 25 | 26 | public function testCanGetDirectiveValues() 27 | { 28 | $this->assertTrue(method_exists($this->parser,'getDirectiveValues')); 29 | } 30 | 31 | public function testCanMatchConstructionPattern() 32 | { 33 | $exampleValue = '{{widget type="theextensionlab_megamenu/widget_category_featured" menu_featured_category_id="4" }}'; 34 | $isMatchEmpty = $this->_isValueAMatch($exampleValue); 35 | $this->assertFalse($isMatchEmpty); 36 | } 37 | 38 | public function testConstructionPatternNotMatchedIncorrectly() 39 | { 40 | $exampleValue = '{/;}}{[{A None Matching String }}[['; 41 | $isMatchEmpty = $this->_isValueAMatch($exampleValue); 42 | $this->assertTrue($isMatchEmpty); 43 | $this->assertTrue($isMatchEmpty); 44 | } 45 | 46 | public function testConstructonMatcherGetsCorrectShortcodeType() 47 | { 48 | $exampleValue = '{{widget type="someBlock"}}'; 49 | $match = $this->_getMatches($exampleValue); 50 | $this->assertEquals('widget', $match['0']['1']); 51 | } 52 | 53 | public function testConstructionMatcherGetsParamString() 54 | { 55 | $exampleValue = '{{widget type="theextensionlab_megamenu/widget_category_featured" menu_featured_category_id="4" }}'; 56 | $match = $this->_getMatches($exampleValue); 57 | $matchedParamString = trim($match[0][2]); 58 | $this->assertEquals('type="theextensionlab_megamenu/widget_category_featured" menu_featured_category_id="4"',$matchedParamString); 59 | } 60 | 61 | public function testGetDirectiveValuesStoresSomeData() 62 | { 63 | $exampleValue = '{{widget type="theextensionlab_megamenu/widget_product_featured" 64 | display_on="small,medium,large" template="theextensionlab/megamenu/products/featured.phtml" 65 | megamenu_featured_product_ids="{\"231\":[{\"position\":\"0\"}],\"232\":[{\"position\":\"0\"}]}"}}'; 66 | $directiveValues = $this->parser->getDirectiveValues($exampleValue); 67 | $this->assertTrue(!empty($directiveValues)); 68 | } 69 | 70 | private function _isValueAMatch($value) 71 | { 72 | $isMatchEmpty = empty($this->_getMatches($value)); 73 | return $isMatchEmpty; 74 | } 75 | 76 | private function _getMatches($value){ 77 | $exampleValue = $value; 78 | $match = $this->parser->_matchConstructionPattern($exampleValue); 79 | return $match; 80 | } 81 | } -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/Test/Model/Parser/Cms/Page/Featured.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | 11 | class TheExtensionLab_MegaMenu_Test_Model_Parser_Cms_Page_Featured extends EcomDev_PHPUnit_Test_Case 12 | { 13 | private $_featuredCmsParser; 14 | 15 | public function setUp() 16 | { 17 | $this->_featuredCmsParser = new TheExtensionLab_MegaMenu_Model_Parser_Cms_Page_Featured; 18 | } 19 | 20 | public function testImplementsParserInterface() 21 | { 22 | $class = new ReflectionClass('TheExtensionLab_MegaMenu_Model_Parser_Cms_Page_Featured'); 23 | $this->assertTrue($class->implementsInterface('TheExtensionLab_MegaMenu_Model_Parser_Interface')); 24 | } 25 | 26 | public function testNoCmsIdReturnsEmptyArray() 27 | { 28 | $result = $this->_featuredCmsParser->parse($this->getIdsWithCmsId('')); 29 | $this->assertTrue(empty($result['cms_page_ids'])); 30 | } 31 | 32 | public function testParamsWithCmsIdReturnThatCmsId() 33 | { 34 | $result = $this->_featuredCmsParser->parse($this->getIdsWithCmsId('1')); 35 | $this->assertTrue(in_array('1',$result['cms_page_ids'])); 36 | } 37 | 38 | 39 | public function testParamsWithLargeCmsIdReturnThatCmsId() 40 | { 41 | $result = $this->_featuredCmsParser->parse($this->getIdsWithCmsId('17865358')); 42 | $this->assertTrue(in_array('17865358',$result['cms_page_ids'])); 43 | } 44 | 45 | 46 | public function testParamsWithNumberSpellingIdDoesNotReturnThat() 47 | { 48 | $result = $this->_featuredCmsParser->parse($this->getIdsWithCmsId('one')); 49 | $this->assertTrue(empty($result['cms_page_ids'])); 50 | } 51 | 52 | private function getIdsWithCmsId($cmsId) 53 | { 54 | return array( 55 | 'type' => 'theextensionlab_megamenu/widget_cms_page_featured', 56 | 'menu_featured_cms_id' => $cmsId, 57 | 'display_on' => 'medium,large', 58 | 'template' => 'sometemplate.phtml' 59 | ); 60 | } 61 | } -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/Test/Model/Prefetcher.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | 11 | class TheExtensionLab_MegaMenu_Test_Model_Prefetcher extends EcomDev_PHPUnit_Test_Case 12 | { 13 | private $_prefetcher; 14 | 15 | public function setUp() 16 | { 17 | $this->_prefetcher = new TheExtensionLab_MegaMenu_Model_Prefetcher(); 18 | } 19 | 20 | public function testCanGetPrefetchMethod() 21 | { 22 | $this->assertTrue(method_exists($this->_prefetcher, 'prefetch')); 23 | } 24 | 25 | public function testPrefetchersPassedInCorrectly() 26 | { 27 | $class = new ReflectionClass("TheExtensionLab_MegaMenu_Model_Prefetcher"); 28 | $property = $class->getProperty("_prefetchModels"); 29 | $property->setAccessible(true); 30 | 31 | $prefetchModels = $property->getValue($this->_prefetcher); 32 | 33 | $this->assertArrayHasKey('product', $prefetchModels); 34 | } 35 | 36 | public function testHasParser() 37 | { 38 | $class = new ReflectionClass("TheExtensionLab_MegaMenu_Model_Prefetcher"); 39 | $property = $class->getProperty("_parser"); 40 | $property->setAccessible(true); 41 | 42 | $parser = $property->getValue($this->_prefetcher); 43 | 44 | $this->assertNotEmpty($parser); 45 | } 46 | 47 | public function testChildModelUpdatesEventIsDispatched() 48 | { 49 | $this->assertEventDispatched('megamenu_prepare_prefetch_models_after'); 50 | } 51 | 52 | public function testChildPrefetchDataMethodsCalled() 53 | { 54 | $defaultPrefetchersArray = array( 55 | 'url_rewrite' => 'theextensionlab_megamenu/prefetcher_url_rewrite' 56 | ); 57 | 58 | $this->_prefetcher = new TheExtensionLab_MegaMenu_Model_Prefetcher($defaultPrefetchersArray); 59 | 60 | $mock = $this->getModelMock('theextensionlab_megamenu/prefetcher_url_rewrite',array('prefetchData')); 61 | $mock 62 | ->expects($this->once()) 63 | ->method('prefetchData'); 64 | $this->replaceByMock('model', 'theextensionlab_megamenu/prefetcher_url_rewrite',$mock); 65 | 66 | $this->_prefetcher->prefetch('Some Content'); 67 | } 68 | 69 | } -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/Test/Model/Prefetcher/Cms/Page.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | 11 | class TheExtensionLab_MegaMenu_Test_Model_Prefetcher_Cms_Page extends EcomDev_PHPUnit_Test_Case 12 | { 13 | private $_prefetcher; 14 | public function setUp() 15 | { 16 | $this->_prefetcher = new TheExtensionLab_MegaMenu_Model_Prefetcher_Cms_Page; 17 | } 18 | 19 | public function testImplementsPrefetcherInterface() 20 | { 21 | $class = new ReflectionClass('TheExtensionLab_MegaMenu_Model_Prefetcher_Cms_Page'); 22 | $this->assertTrue($class->implementsInterface('TheExtensionLab_MegaMenu_Model_Prefetcher_Interface')); 23 | } 24 | 25 | public function testNoCmsIdsSetsNoCollection() 26 | { 27 | $directiveValues = array(); 28 | $this->_prefetcher->prefetchData($directiveValues); 29 | $cmsRegistryCollection = Mage::registry('megamenu_cms_pages'); 30 | $this->assertEmpty($cmsRegistryCollection); 31 | } 32 | 33 | public function testCollectionRegisteredWhenCmsIdSet() 34 | { 35 | $directiveValues = array(); 36 | $directiveValues['cms_page_ids'] = array(1); 37 | $this->_prefetcher->prefetchData($directiveValues); 38 | $cmsRegistryCollection = Mage::registry('megamenu_cms_pages'); 39 | $this->assertTrue($cmsRegistryCollection instanceof Mage_Cms_Model_Resource_Page_Collection); 40 | } 41 | } -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/Test/Model/Resource/Setup.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | 11 | class TheExtensionLab_MegaMenu_Test_Model_Resource_Setup 12 | extends EcomDev_PHPUnit_Test_Case_Config 13 | { 14 | public function testSetupAttributeContainsContentColumns() 15 | { 16 | $setupModel = Mage::getModel('theextensionlab_megamenu/resource_setup','theextensionlab_megamenu_setup'); 17 | 18 | $defaultEntites = $setupModel->getDefaultEntities(); 19 | $attributes = $defaultEntites['catalog_category']['attributes']; 20 | 21 | $this->assertArrayHasKey('menu_section_2_content',$attributes); 22 | $this->assertArrayHasKey('menu_section_2_column_width',$attributes); 23 | 24 | $this->assertArrayHasKey('menu_section_7_content',$attributes); 25 | $this->assertArrayHasKey('menu_section_7_column_width',$attributes); 26 | 27 | } 28 | } -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/Test/controller/Adminhtml/Cms/PageController.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | 11 | class TheExtensionLab_MegaMenu_Test_controller_Adminhtml_Cms_PageController 12 | extends EcomDev_PHPUnit_Test_Case_Controller 13 | { 14 | 15 | public function testMenuCmsTabAdded() 16 | { 17 | // Too slow. 18 | // $this->mockAdminUserSession(); 19 | // $this->dispatch('adminhtml/cms_page/edit',array('page_id' => '3')); 20 | // $this->assertLayoutBlockCreated('cms_page_edit_tab_menu'); 21 | // $this->assertLayoutBlockInstanceOf('cms_page_edit_tab_menu','TheExtensionLab_MegaMenu_Block_Adminhtml_Cms_Page_Edit_Tab_Menu'); 22 | } 23 | } -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/controllers/Adminhtml/Menu/Attribute/Option/WidgetController.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | 11 | class TheExtensionLab_MegaMenu_Adminhtml_Menu_Attribute_Option_WidgetController 12 | extends Mage_Adminhtml_Controller_Action 13 | { 14 | protected function _getAttributeIdFromFirstPrevValue($prevValue) 15 | { 16 | $optionIds = json_decode($prevValue,1); 17 | $first_key = key($optionIds); 18 | $option = Mage::getModel('eav/entity_attribute_option')->load($first_key); 19 | 20 | return $option->getAttributeId(); 21 | } 22 | 23 | /** 24 | * Chooser Source action 25 | */ 26 | public function chooserAction() 27 | { 28 | $this->loadLayout(); 29 | $uniqId = $this->getRequest()->getParam('uniq_id'); 30 | $prevValue = $this->getRequest()->getParam('prev_value'); 31 | $attributeId = $this->getRequest()->getParam('attribute_id'); 32 | 33 | if($attributeId === null && $prevValue != null) 34 | { 35 | $attributeId = $this->_getAttributeIdFromFirstPrevValue($prevValue); 36 | } 37 | 38 | $grid = $this->getLayout()->createBlock('theextensionlab_megamenu/adminhtml_attribute_option_chooser', 'adminhtml.megamenu.attribute.option.widget.grid', array( 39 | 'id' => $uniqId, 40 | 'prev_value' => $prevValue, 41 | 'attribute_id' => $attributeId 42 | )); 43 | 44 | $this->getLayout()->getBlock('root')->append($grid); 45 | 46 | $serializer = $this->getLayout()->createBlock('adminhtml/widget_grid_serializer','grouped_grid_serializer') 47 | ->setTemplate('theextensionlab/megamenu/widget/grid/json/serializer.phtml') 48 | ; 49 | $serializer->initSerializerBlock( 50 | 'adminhtml.megamenu.attribute.option.widget.grid', 51 | 'getCallback', 52 | 'megamenu_attribute_options', 53 | 'selected_options' 54 | ); 55 | $serializer->addColumnInputName(array( 56 | 'use_options', 57 | 'position' 58 | )); 59 | 60 | $this->getLayout()->getBlock('root')->append($serializer); 61 | 62 | $this->renderLayout(); 63 | } 64 | 65 | public function chooserGridOnlyAction() 66 | { 67 | $this->loadLayout(); 68 | $uniqId = $this->getRequest()->getParam('uniq_id'); 69 | $attributeId = $this->getRequest()->getParam('attribute_id'); 70 | 71 | $grid = $this->getLayout()->createBlock('theextensionlab_megamenu/adminhtml_attribute_option_chooser', 'adminhtml.megamenu.attribute.option.widget.grid', array( 72 | 'id' => $uniqId, 73 | 'attribute_id' => $attributeId 74 | ))->setSelectedOptions($this->getRequest()->getPost('selected_options', null)); 75 | 76 | $this->getLayout()->getBlock('root')->append($grid); 77 | 78 | $this->renderLayout(); 79 | } 80 | } -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/controllers/Adminhtml/Menu/Attribute/WidgetController.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | 11 | class TheExtensionLab_MegaMenu_Adminhtml_Menu_Attribute_WidgetController 12 | extends Mage_Adminhtml_Controller_Action 13 | { 14 | /** 15 | * Chooser Source action 16 | */ 17 | public function chooserAction() 18 | { 19 | $uniqId = $this->getRequest()->getParam('uniq_id'); 20 | $pagesGrid = $this->getLayout()->createBlock('theextensionlab_megamenu/adminhtml_attribute_chooser', '', array( 21 | 'id' => $uniqId, 22 | )); 23 | $this->getResponse()->setBody($pagesGrid->toHtml()); 24 | } 25 | } -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/controllers/Adminhtml/Menu/Catalog/Category/Draggable/WidgetController.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | 11 | class TheExtensionLab_MegaMenu_Adminhtml_Menu_Catalog_Category_Draggable_WidgetController 12 | extends Mage_Adminhtml_Controller_Action 13 | { 14 | public function chooserAction() 15 | { 16 | $this->getResponse()->setBody( 17 | $this->_getCategoryTreeBlock()->toHtml() 18 | ); 19 | } 20 | 21 | public function categoriesJsonAction() 22 | { 23 | if ($categoryId = (int)$this->getRequest()->getPost('id')) { 24 | 25 | $category = Mage::getModel('catalog/category')->load($categoryId); 26 | if ($category->getId()) { 27 | Mage::register('category', $category); 28 | Mage::register('current_category', $category); 29 | } 30 | $this->getResponse()->setBody( 31 | $this->_getCategoryTreeBlock()->getTreeJson($category) 32 | ); 33 | } 34 | } 35 | 36 | private function _getCategoryTreeBlock() 37 | { 38 | $prevValue = $this->getRequest()->getParam('prev_value'); 39 | return $this->getLayout() 40 | ->createBlock( 41 | 'theextensionlab_megamenu/adminhtml_catalog_category_widget_draggable_chooser', 42 | '', array( 43 | 'id' => $this->getRequest()->getParam('uniq_id'), 44 | 'prev_value' => $prevValue 45 | ) 46 | ); 47 | } 48 | 49 | 50 | } -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/controllers/Adminhtml/Menu/Catalog/Category/WidgetController.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | 11 | class TheExtensionLab_MegaMenu_Adminhtml_Menu_Catalog_Category_WidgetController 12 | extends Mage_Adminhtml_Controller_Action 13 | { 14 | /** 15 | * Chooser Source action 16 | */ 17 | public function chooserAction() 18 | { 19 | $this->getResponse()->setBody( 20 | $this->_getCategoryTreeBlock()->toHtml() 21 | ); 22 | } 23 | 24 | /** 25 | * Categories tree node (Ajax version) 26 | */ 27 | public function categoriesJsonAction() 28 | { 29 | if ($categoryId = (int) $this->getRequest()->getPost('id')) { 30 | 31 | $category = Mage::getModel('catalog/category')->load($categoryId); 32 | if ($category->getId()) { 33 | Mage::register('category', $category); 34 | Mage::register('current_category', $category); 35 | } 36 | $this->getResponse()->setBody( 37 | $this->_getCategoryTreeBlock()->getTreeJson($category) 38 | ); 39 | } 40 | } 41 | 42 | protected function _getCategoryTreeBlock() 43 | { 44 | return $this->getLayout()->createBlock('theextensionlab_megamenu/adminhtml_catalog_category_widget_chooser', '', array( 45 | 'id' => $this->getRequest()->getParam('uniq_id'), 46 | 'use_massaction' => $this->getRequest()->getParam('use_massaction', false) 47 | )); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/controllers/Adminhtml/Menu/Catalog/Product/WidgetController.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | 11 | class TheExtensionLab_MegaMenu_Adminhtml_Menu_Catalog_Product_WidgetController 12 | extends Mage_Adminhtml_Controller_Action 13 | { 14 | public function chooserAction() 15 | { 16 | $this->loadLayout(); 17 | 18 | $this->getLayout()->getBlock('root')->append($this->_initGrid()); 19 | 20 | $serializer = $this->getLayout()->createBlock('adminhtml/widget_grid_serializer', 'megamenu_featured_products_grid_serializer') 21 | ->setTemplate('theextensionlab/megamenu/widget/grid/json/serializer.phtml') 22 | ; 23 | $serializer->initSerializerBlock( 24 | 'adminhtml.megamenu.catalog.product.widget.grid', 25 | 'getCallback', 26 | 'megamenu_featured_products', 27 | 'selected_products' 28 | ); 29 | $serializer->addColumnInputName( 30 | array( 31 | 'in_products', 32 | 'position' 33 | ) 34 | ); 35 | 36 | $this->getLayout()->getBlock('root')->append($serializer); 37 | 38 | $this->renderLayout(); 39 | } 40 | 41 | public function chooserGridOnlyAction() 42 | { 43 | $this->loadLayout(); 44 | $this->getLayout()->getBlock('root')->append($this->_initGrid()); 45 | $this->renderLayout(); 46 | } 47 | 48 | private function _initGrid() 49 | { 50 | $uniqId = $this->getRequest()->getParam('uniq_id'); 51 | $selectedProducts = $this->getRequest()->getParam('selected_products'); 52 | 53 | $grid = $this->getLayout()->createBlock( 54 | 'theextensionlab_megamenu/adminhtml_catalog_product_widget_chooser', 55 | 'adminhtml.megamenu.catalog.product.widget.grid', array( 56 | 'id' => $uniqId, 57 | 'selected_products' => $selectedProducts 58 | ) 59 | ); 60 | 61 | return $grid; 62 | } 63 | } -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/data/theextensionlab_megamenu_setup/data-install-1.0.0.php: -------------------------------------------------------------------------------- 1 | getProcessByCode(Mage_Catalog_Helper_Category_Flat::CATALOG_CATEGORY_FLAT_PROCESS_CODE); 6 | 7 | if(Mage::helper('catalog/category_flat')->isEnabled()){ 8 | $categoryFlatIndexer->reindexEverything(); 9 | }else{ 10 | $categoryFlatIndexer->changeStatus(Mage_Index_Model_Process::STATUS_REQUIRE_REINDEX); 11 | } -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/etc/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | 1.5.7 13 | 14 | 15 | 16 | 17 | 18 | 19 | TheExtensionLab_MegaMenu_Block 20 | 21 | 22 | 23 | 24 | 25 | TheExtensionLab_MegaMenu_Helper 26 | 27 | 28 | 29 | 30 | 31 | TheExtensionLab_MegaMenu_Model 32 | theextensionlab_megamenu_resource 33 | 34 | 35 | 36 | TheExtensionLab_MegaMenu_Model_Resource 37 | 38 | 39 | 40 | 41 | 42 | 43 | TheExtensionLab_MegaMenu 44 | TheExtensionLab_MegaMenu_Model_Resource_Setup 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | disabled 56 | 57 | 58 | 59 | 60 | theextensionlab_megamenu/observer 61 | pageBlockHtmlTopmenuGetHtmlBefore 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | theextensionlab_megamenu/observer 70 | catalogCategoryCollectionLoadBefore 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | theextensionlab_megamenu/observer 79 | catalogCategoryFlatLoadnodesBefore 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | theextensionlab_megamenu/observer 88 | enableWysiwygInWysiwygConfig 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | theextensionlab_megamenu/observer 97 | cmsPagePrepareSave 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | theextensionlab_megamenu/template_filter 106 | theextensionlab_megamenu/prefetcher 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | theextensionlab_megamenu/observer 144 | adminhtmlBlockHtmlBefore 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | TheExtensionLab_MegaMenu.csv 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | theextensionlab/megamenu.xml 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | TheExtensionLab_MegaMenu.csv 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | theextensionlab/megamenu.xml 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 1 193 | 7 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | TheExtensionLab_MegaMenu_Adminhtml 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/etc/system.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | select 18 | adminhtml/system_config_source_yesno 19 | 1100 20 | 1 21 | 1 22 | 1 23 | Responsive menus in a none responsive theme might not work great if for example your theme is not responsive you may want to set this to no. 24 | 25 | 26 | 2000 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/sql/theextensionlab_megamenu_setup/install-1.0.0.php: -------------------------------------------------------------------------------- 1 | startSetup(); 7 | $installer->installEntities(); 8 | $installer->endSetup(); 9 | 10 | $installer->addInstallationSuccessfulNotification(); -------------------------------------------------------------------------------- /app/code/community/TheExtensionLab/MegaMenu/sql/theextensionlab_megamenu_setup/upgrade-1.0.0-1.5.3.php: -------------------------------------------------------------------------------- 1 | updateAttribute( 7 | Mage_Catalog_Model_Category::ENTITY, 8 | 'menu_dropdown_type', 9 | 'is_required', 10 | false 11 | ); 12 | 13 | $installer->updateAttribute( 14 | Mage_Catalog_Model_Category::ENTITY, 15 | 'menu_dropdown_type', 16 | 'default_value', 17 | 1 18 | ); 19 | 20 | $installer->endSetup(); -------------------------------------------------------------------------------- /app/design/adminhtml/default/default/layout/theextensionlab/megamenu.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | skin_csstheextensionlab/megamenu/css/widget/draggable.css 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /app/design/adminhtml/default/default/template/theextensionlab/megamenu/system/config/extension-info.phtml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheExtensionLab/MegaMenu/bde3d07b3dce44a876ca8ba2bd3b2f60ac2fe480/app/design/adminhtml/default/default/template/theextensionlab/megamenu/system/config/extension-info.phtml -------------------------------------------------------------------------------- /app/design/adminhtml/default/default/template/theextensionlab/megamenu/widget/grid/json/serializer.phtml: -------------------------------------------------------------------------------- 1 | 14 | * 15 | */ 16 | ?> 17 | 18 | getFormId()?> 19 | 20 | 34 | 35 | 36 | 39 | -------------------------------------------------------------------------------- /app/design/frontend/base/default/layout/theextensionlab/megamenu.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | 13 | jsvarien/menu.js 14 | skin_jsjs/theextensionlab/megamenu/menu-bp.js 15 | skin_jsjs/theextensionlab/megamenu/menu.js 16 | 17 | 18 | 19 | 20 | 21 | css/theextensionlab/megamenu/grid.css 22 | 23 | 24 | css/theextensionlab/megamenu/main.css 25 | 26 | 27 | css/theextensionlab/megamenu/responsive.css 28 | 29 | 30 | css/theextensionlab/megamenu/theme-specific.css 31 | 32 | 33 | 34 | 35 | 36 | 37 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /app/design/frontend/base/default/template/theextensionlab/megamenu/attributes/li-only-list.phtml: -------------------------------------------------------------------------------- 1 | 8 | */ 9 | ?> 10 | 11 | 12 | 13 | 14 | getOptionIds();?> 15 | 16 | 17 | 18 | 19 | 20 | getAttributeId()];?> 21 | 22 | $value):?> 23 |
  • 24 | 25 | getValue();?> 26 | 27 |
  • 28 | 29 | 30 | -------------------------------------------------------------------------------- /app/design/frontend/base/default/template/theextensionlab/megamenu/attributes/list.phtml: -------------------------------------------------------------------------------- 1 | 8 | */ 9 | ?> 10 | 11 | 12 | 13 | 14 | getOptionIds();?> 15 | 16 | 17 | 18 | 19 | 20 | getAttributeId()];?> 21 | 22 |
    23 | 33 |
    34 | 35 | -------------------------------------------------------------------------------- /app/design/frontend/base/default/template/theextensionlab/megamenu/categories/featured.phtml: -------------------------------------------------------------------------------- 1 | 8 | */ 9 | ?> 10 | 11 | getFeaturedCategoryNode();?> 13 | 14 | 15 | 27 | -------------------------------------------------------------------------------- /app/design/frontend/base/default/template/theextensionlab/megamenu/categories/li-only-list.phtml: -------------------------------------------------------------------------------- 1 | 8 | */ 9 | ?> 10 | 11 | getLoadedMenuNodes(); ?> 12 | getCategoryTree(); ?> 13 | 14 | hasTitle()):?> 15 |
  • 16 | 17 | getTitle();?> 18 | 19 |
  • 20 | 21 | 22 | 23 | 24 | _getCategoryNodeById($childNodes, $category->id);?> 25 | 26 | 27 | 28 |
  • children) && !$this->hasTitle()): echo 'class="section-title"';endif;?>> 29 | 30 | 31 | _getCustomCategoryMenuName($categoryNode,$category);?> 32 | 33 | 34 |
  • 35 | 36 | children)):?> 37 | children as $childCategory){?> 38 | id;?> 39 | 40 | 41 |
  • 42 | 43 | _getCustomCategoryMenuName($childCategoryNode, $childCategory);?> 44 | 45 |
  • 46 | 47 | 48 |
  • children)):echo 'class="view-all small-only-view-all"';endif;?>> 49 | 50 | 51 | __('View All %s', $this->_getCustomCategoryMenuName($categoryNode,$category));?> 52 | 53 | 54 |
  • 55 | 56 | 57 | -------------------------------------------------------------------------------- /app/design/frontend/base/default/template/theextensionlab/megamenu/categories/list.phtml: -------------------------------------------------------------------------------- 1 | 8 | */ 9 | ?> 10 | 11 | getLoadedMenuNodes(); ?> 12 | getCategoryTree(); ?> 13 | 14 |
    15 | 58 |
    -------------------------------------------------------------------------------- /app/design/frontend/base/default/template/theextensionlab/megamenu/cms/block.phtml: -------------------------------------------------------------------------------- 1 | 8 | */ 9 | ?> 10 | 11 | getBlock();?> 12 | 13 | getContent();?> 14 | -------------------------------------------------------------------------------- /app/design/frontend/base/default/template/theextensionlab/megamenu/cms/page/featured.phtml: -------------------------------------------------------------------------------- 1 | 8 | */ 9 | ?> 10 | 11 | getCmsPage()?> 13 | 14 | 26 | -------------------------------------------------------------------------------- /app/design/frontend/base/default/template/theextensionlab/megamenu/page/html/topmenu.phtml: -------------------------------------------------------------------------------- 1 | 14 | * 15 | */ 16 | ?> 17 | 18 | 20 | getHtml('level-top') ?> 21 | 22 | 23 | 24 | 29 | -------------------------------------------------------------------------------- /app/design/frontend/base/default/template/theextensionlab/megamenu/page/html/topmenu/renderer.phtml: -------------------------------------------------------------------------------- 1 | 8 | */ 9 | 10 | /** @var Varien_Data_Tree_Node $menuTree */ 11 | /** @var string $childrenWrapClass */ 12 | ?> 13 | 14 | getChildren();?> 15 | 16 | 17 | getIncludeInMenu()):?> 18 | setCategoryData($child,$menuTree->getLevel());?> 19 |
  • _getRenderedMenuItemAttributes($child);?>> 20 | _isCategoryPlaceholder($child)):?> 21 | 22 | escapeHtml($child->getName())?> 23 | 24 | 25 | escapeHtml($child->getName())?> 26 | 27 | 28 | 29 |
    30 | 31 | 32 | getHasDropDownContent()):?> 33 | 34 | getDropDownInlineStyle($child);?> 35 | 36 |
    > 37 | getColumns() as $column):?> 38 | 39 |
    40 | 41 |
    42 | 43 | 44 |
    45 | 46 | 47 | 48 |
    49 | 50 | 51 |
  • 52 | 53 | -------------------------------------------------------------------------------- /app/design/frontend/base/default/template/theextensionlab/megamenu/products/featured-secondary.phtml: -------------------------------------------------------------------------------- 1 | 8 | */ 9 | ?> 10 | 11 | getFeaturedProductsCollection();?> 12 | helper('catalog/image');?> 13 | 14 | 40 | -------------------------------------------------------------------------------- /app/design/frontend/base/default/template/theextensionlab/megamenu/products/featured.phtml: -------------------------------------------------------------------------------- 1 | 8 | */ 9 | ?> 10 | 11 | getFeaturedProductsCollection(); ?> 12 | helper('catalog/image'); ?> 13 | 14 | 38 | -------------------------------------------------------------------------------- /app/etc/modules/TheExtensionLab_MegaMenu.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | true 13 | community 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /app/locale/de_DE/TheExtensionLab_MegaMenu.csv: -------------------------------------------------------------------------------- 1 | "MegaMenu Contents","MegaMenu Inhalte" 2 | "MegaMenu Settings","MegaMenu Einstellungen" 3 | "Include Responsive Styles","Responsive CSS einbinden" 4 | "Responsive menus in a none responsive theme might not work great if for example your theme is not responsive you may want to set this to no.","Responsive Menüs in nicht responsive Themes könnten nicht gut funktionieren. Wenn Ihr Theme nicht responsive ist, wollen Sie diese Einstellung ggf. auf Nein stellen." 5 | "Serial Key","Seriennummer" 6 | "Menu Name","Menü Name" 7 | "Menu DropDown Type","Menü DropDown Typ" 8 | "Absolute Center (Fullwidth)","Absolut zentriert (volle Breite)" 9 | "Absolute Left","Absolut links" 10 | "Absolute Right","Absolut rechts" 11 | "Relative Center","Relativ zentriert" 12 | "Hang Right","rechts schwebend" 13 | "Hang Left","links schwebend" 14 | "Link Type","Link Typ" 15 | "Default","Standard" 16 | "Internal Link","Interner Link" 17 | "External Link","Externer Link" 18 | "No Link","Kein Link" 19 | "If set this will override the default category name within the menu only.","Wenn definiert, überschreibt dieser Text den Standard Kategorienamen im Menü." 20 | "Section 1 Width","Bereich 1 Breite" 21 | "Section 2 Width","Bereich 2 Breite" 22 | "Section 3 Width","Bereich 3 Breite" 23 | "Section 4 Width","Bereich 4 Breite" 24 | "Section 5 Width","Bereich 5 Breite" 25 | "Section 6 Width","Bereich 6 Breite" 26 | "Section 7 Width","Bereich 7 Breite" 27 | "Section 8 Width","Bereich 8 Breite" 28 | "Section 9 Width","Bereich 9 Breite" 29 | "Section 10 Width","Bereich 10 Breite" 30 | "Section 1 Content","Bereich 1 Inhalt" 31 | "Section 2 Content","Bereich 2 Inhalt" 32 | "Section 3 Content","Bereich 3 Inhalt" 33 | "Section 4 Content","Bereich 4 Inhalt" 34 | "Section 5 Content","Bereich 5 Inhalt" 35 | "Section 6 Content","Bereich 6 Inhalt" 36 | "Section 7 Content","Bereich 7 Inhalt" 37 | "Section 8 Content","Bereich 8 Inhalt" 38 | "Section 9 Content","Bereich 9 Inhalt" 39 | "Section 10 Content","Bereich 10 Inhalt" 40 | "Not Active","Inaktiv" 41 | "%s of %s columns (%s)","%s von %s Spalten (%s)" 42 | "MegaMenu - Category List Section","MegaMenu - Liste von Kategorien" 43 | "Categories","Kategorien" 44 | "Not Selected","Nicht ausgewählt" 45 | "Select and order categories","Kategorien auswählen und sortieren" 46 | "Display On","Anzeigen bei" 47 | "Small (Mobile)","Klein (Smartphone)" 48 | "Medium (Tablet)","Mittel (Tablet)" 49 | "Large (Desktop)","Groß (Desktop)" 50 | "Template","Vorlage" 51 | "Default Categories List","Standard Kategorien Liste" 52 | "Li Only List","nur li Liste" 53 | "Select your categories for this menu block","Kategorien für diesen Menüblock auswählen" 54 | "Drag your categories here","Kategorien hierhin ziehen" 55 | "Your Categories","Ihre Kategorien" 56 | "Default Categories","Standard Kategorien" 57 | "MegaMenu - Featured Category Block","MegaMenu - Block für hervorgehobene Kategorien" 58 | "Add a single featured category for this menu block","Einzelne hervorgehobene Kategorie für diesen Menüblock auswählen" 59 | "Title","Titel" 60 | "Category","Kategorie" 61 | "Select Category...","Kategorie auswählen..." 62 | "Select Image...","Bild auswählen..." 63 | "Category Image","Kategoriebild" 64 | "Default Featured Category Template","Standard Hervorgehobene Kategorie Vorlage" 65 | "MegaMenu - Featured Cms Section","MegaMenu - Hervorgehobener CMS Bereich" 66 | "Cms Image","CMS Bild" 67 | "Cms Page","CMS Seite" 68 | "Select Page...","Seite auswählen..." 69 | "MegaMenu - Featured Product Section","MegaMenu - Hervorgehobene Artikel Bereich" 70 | "Add a featured product","Hervorgehobenen Artikel hinzufügen" 71 | "Product","Artikel" 72 | "Select Product(s)...","Artikel auswählen..." 73 | "MegaMenu - Shop By Attribute List","MegaMenu - Über Attributliste filtern" 74 | "Select Options","Optionen auswählen" 75 | "Select Attribute Options","Attributoptionen auswählen" 76 | "List Columns","Anzahl Spalten" 77 | "Default Shop By List","Standard Filter Liste" 78 | "List Columns","Anzahl Spalten" 79 | "MegaMenu - Static Block","MegaMenu - Statischer Block" 80 | "Add a static block","Statischen Block hinzufügen" 81 | "Block","Block" 82 | "Select Block...","Block auswählen..." 83 | "The Serial Key for TheExtensionLab_MegaMenu is invalid or not present and therefore the functionality of this extension has been limited. (ServerName : %s)","Die Seriennummer für TheExtensionLab_MegaMenu ist ungültig oder nicht vorhanden, sodass die Funktionalität der Extension eingeschränkt wurde. (Server Name : %s)" 84 | "The Serial Key is invalid or not present and therefore the functionality of this extension has been limited. You can enter a serial key at System > Configuration > Catalog > Catalog Navigation (ServerName : %s)","Die Seriennummer ist ungültig oder nicht vorhanden, sodass die Funktionalität der Extension eingeschränkt wurde. Sie können unter System > Konfiguration > Katalog > Katalog Navigation eine Seriennummer eingeben (Server Name : %s)" 85 | "View More","Mehr anzeigen" 86 | "View All %s","Alle anzeigen %s" 87 | "Shop By %s","Filtern nach %s" 88 | -------------------------------------------------------------------------------- /app/locale/en_US/TheExtensionLab_MegaMenu.csv: -------------------------------------------------------------------------------- 1 | "MegaMenu Contents","MegaMenu Contents" 2 | "MegaMenu Settings","MegaMenu Settings" 3 | "Include Responsive Styles","Include Responsive Styles" 4 | "Responsive menus in a none responsive theme might not work great if for example your theme is not responsive you may want to set this to no.","Responsive menus in a none responsive theme might not work great if for example your theme is not responsive you may want to set this to no." 5 | "Serial Key","Serial Key" 6 | "Menu Name","Menu Name" 7 | "Menu DropDown Type","Menu DropDown Type" 8 | "Absolute Center (Fullwidth)","Absolute Center (Fullwidth)" 9 | "Absolute Left","Absolute Left" 10 | "Absolute Right","Absolute Right" 11 | "Relative Center","Relative Center" 12 | "Hang Right","Hang Right" 13 | "Hang Left","Hang Left" 14 | "Link Type","Link Type" 15 | "Default","Default" 16 | "Internal Link","Internal Link" 17 | "External Link","External Link" 18 | "No Link","No Link" 19 | "If set this will override the default category name within the menu only.","If set this will override the default category name within the menu only." 20 | "Section 1 Width","Section 1 Width" 21 | "Section 2 Width","Section 2 Width" 22 | "Section 3 Width","Section 3 Width" 23 | "Section 4 Width","Section 4 Width" 24 | "Section 5 Width","Section 5 Width" 25 | "Section 6 Width","Section 6 Width" 26 | "Section 7 Width","Section 7 Width" 27 | "Section 8 Width","Section 8 Width" 28 | "Section 9 Width","Section 9 Width" 29 | "Section 10 Width","Section 10 Width" 30 | "Section 1 Content","Section 1 Content" 31 | "Section 2 Content","Section 2 Content" 32 | "Section 3 Content","Section 3 Content" 33 | "Section 4 Content","Section 4 Content" 34 | "Section 5 Content","Section 5 Content" 35 | "Section 6 Content","Section 6 Content" 36 | "Section 7 Content","Section 7 Content" 37 | "Section 8 Content","Section 8 Content" 38 | "Section 9 Content","Section 9 Content" 39 | "Section 10 Content","Section 10 Content" 40 | "Not Active","Not Active" 41 | "%s of %s columns (%s)","%s of %s columns (%s)" 42 | "MegaMenu - Category List Section","MegaMenu - Category List Section" 43 | "Categories","Categories" 44 | "Not Selected","Not Selected" 45 | "Select and order categories","Select and order categories" 46 | "Display On","Display On" 47 | "Small (Mobile),"Small (Mobile)" 48 | "Medium (Tablet)","Medium (Tablet)" 49 | "Large (Desktop)","Large (Desktop)" 50 | "Template","Template" 51 | "Default Categories List","Default Categories List" 52 | "Li Only List","Li Only List" 53 | "Select your categories for this menu block","Select your categories for this menu block" 54 | "Drag your categories here","Drag your categories here" 55 | "Your Categories","Your Categories" 56 | "Default Categories","Default Categories" 57 | "MegaMenu - Featured Category Block","MegaMenu - Featured Category Block" 58 | "Add a single featured category for this menu block","Add a single featured category for this menu block" 59 | "Title","Title" 60 | "Category","Category" 61 | "Select Category...","Select Category..." 62 | "Select Image...","Select Image..." 63 | "Category Image","Category Image" 64 | "Default Featured Category Template","Default Featured Category Template" 65 | "MegaMenu - Featured Cms Section","MegaMenu - Featured Cms Section" 66 | "Cms Image","Cms Image" 67 | "Cms Page","Cms Page" 68 | "Select Page...","Select Page..." 69 | "MegaMenu - Featured Product Section","MegaMenu - Featured Product Section" 70 | "Add a featured product","Add a featured product" 71 | "Product","Product" 72 | "Select Product(s)...","Select Product(s)..." 73 | "MegaMenu - Shop By Attribute List","MegaMenu - Shop By Attribute List" 74 | "Select Options","Select Options" 75 | "Select Attribute Options","Select Attribute Options" 76 | "List Columns","List Columns" 77 | "Default Shop By List","Default Shop By List" 78 | "List Columns","List Columns" 79 | "MegaMenu - Static Block","MegaMenu - Static Block" 80 | "Add a static block","Add a static block" 81 | "Block","Block" 82 | "Select Block...","Select Block..." 83 | "The Serial Key for TheExtensionLab_MegaMenu is invalid or not present and therefore the functionality of this extension has been limited. (ServerName : %s)","The Serial Key for TheExtensionLab_MegaMenu is invalid or not present and therefore the functionality of this extension has been limited. (ServerName : %s)" 84 | "The Serial Key is invalid or not present and therefore the functionality of this extension has been limited. You can enter a serial key at System > Configuration > Catalog > Catalog Navigation (ServerName : %s)","The Serial Key is invalid or not present and therefore the functionality of this extension has been limited. You can enter a serial key at System > Configuration > Catalog > Catalog Navigation (ServerName : %s)" 85 | "View More","View More" 86 | "View All %s","View All %s" 87 | "Shop By %s","Shop By %s" 88 | "Optional","Optional" -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name":"theextensionlab/megamenu", 3 | "type":"magento-module", 4 | "homepage":"http://www.theextensionlab.com/magento/mega-menu", 5 | "description":"Magento MegaMenu extension", 6 | "license":"Open Software License (OSL 3.0)", 7 | "authors":[ 8 | { 9 | "name":"James Anelay", 10 | "email":"james@theextensionlab.com" 11 | } 12 | ], 13 | "require":{ 14 | "magento-hackathon/magento-composer-installer":"*", 15 | "theextensionlab/tinymceconfig":"~1.0", 16 | "theextensionlab/widgetimage":"~1.0" 17 | }, 18 | "require-dev": { 19 | "ecomdev/ecomdev_phpunit": "~0.3.7" 20 | }, 21 | "repositories": [ 22 | { 23 | "type": "composer", 24 | "url": "http://packages.firegento.com" 25 | }, 26 | { 27 | "type": "vcs", 28 | "url": "https://github.com/TheExtensionLab/TinyMceConfig.git" 29 | }, 30 | { 31 | "type": "vcs", 32 | "url": "https://github.com/TheExtensionLab/WidgetImage.git" 33 | } 34 | ] 35 | } -------------------------------------------------------------------------------- /js/theextensionlab/megamenu/adminhtml/grid/json/serializer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @category TheExtensionLab 3 | * @package TheExtensionLab_MegaMenu 4 | * @copyright Copyright (c) 2015 TheExtensionLab (http://www.theextensionlab.com) 5 | * @license Open Software License (OSL 3.0 6 | * @author James Anelay @ TheExtensionLab 7 | */ 8 | 9 | String.prototype.addSlashes = function() 10 | { 11 | return this.replace(/[\\"']/g, '\\$&').replace(/\u0000/g, '\\0'); 12 | }; 13 | 14 | var jsonSerializerController = Class.create(); 15 | jsonSerializerController.prototype = Object.extend(Object.clone(serializerController.prototype), { 16 | serializeObject: function(){ 17 | if(this.multidimensionalMode){ 18 | var clone = this.gridData.clone(); 19 | clone.each(function(pair) { 20 | //Put the data in array to avoid "}}" which will conflict with the widget directive we now get ]}] which wont match. 21 | //Not perfect but better than an unreadable base_64 string which is the default for serializer. 22 | if(JSON.stringify(pair.value).charAt(0) != "[") { 23 | clone.set(pair.key, [pair.value]); 24 | } 25 | }); 26 | 27 | return JSON.stringify(clone.toJSON()).addSlashes(); 28 | } 29 | else{ 30 | return this.gridData.values().join('&'); 31 | } 32 | } 33 | }); -------------------------------------------------------------------------------- /js/theextensionlab/megamenu/wysiwyg/widget.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @category TheExtensionLab 3 | * @package TheExtensionLab_MegaMenu 4 | * @copyright Copyright (c) 2015 TheExtensionLab (http://www.theextensionlab.com) 5 | * @license Open Software License (OSL 3.0 6 | * @author James Anelay @ TheExtensionLab 7 | */ 8 | 9 | WysiwygWidget.chooser.prototype.chooseNew = function(newUrl) { 10 | // Show or hide chooser content if it was already loaded 11 | var responseContainerId = this.getResponseContainerId(); 12 | 13 | // Otherwise load content from server 14 | new Ajax.Request(newUrl, 15 | { 16 | parameters: {element_value: this.getElementValue(), element_label: this.getElementLabelText()}, 17 | onSuccess: function(transport) { 18 | try { 19 | widgetTools.onAjaxSuccess(transport); 20 | this.dialogContent = widgetTools.getDivHtml(responseContainerId, transport.responseText); 21 | this.openDialogWindow(this.dialogContent); 22 | } catch(e) { 23 | alert(e.message); 24 | } 25 | }.bind(this) 26 | } 27 | ); 28 | }; 29 | 30 | //This override replaces the regex because the default version doesn't allow escaped quotes in the 31 | //widget option value (Such as what we have with escaped category JSON) 32 | WysiwygWidget.Widget.prototype.initOptionValues = function() { 33 | 34 | if (!this.wysiwygExists()) { 35 | return false; 36 | } 37 | 38 | var e = this.getWysiwygNode(); 39 | if (e != undefined && e.id) { 40 | var widgetCode = Base64.idDecode(e.id); 41 | if (widgetCode.indexOf('{{widget') != -1) { 42 | this.optionValues = new Hash({}); 43 | widgetCode.gsub(/([a-z0-9\_]+)\s*\=\s*\"(.+?)\"(?=\}\}| )/i, function(match){ 44 | if (match[1] == 'type') { 45 | this.widgetEl.value = match[2]; 46 | } else { 47 | this.optionValues.set(match[1], match[2]); 48 | } 49 | }.bind(this)); 50 | 51 | this.loadOptions(); 52 | } 53 | } 54 | }; 55 | 56 | function getNodeData(node, fields) { 57 | var data = {}; 58 | 59 | var nodeId = node.id; 60 | // loop through desired fields 61 | 62 | if(nodeId != 2) { 63 | data['id'] = nodeId; 64 | } 65 | 66 | if (node.hasChildNodes()) { 67 | if(nodeId == 2) { 68 | var categories = data.categories = []; 69 | node.eachChild(function (child) { 70 | categories.push(getNodeData(child, fields)); 71 | }); 72 | } else{ 73 | var children = data.children = []; 74 | node.eachChild(function (child) { 75 | children.push(getNodeData(child, fields)); 76 | }); 77 | } 78 | } 79 | return data; 80 | } -------------------------------------------------------------------------------- /modman: -------------------------------------------------------------------------------- 1 | app/etc/modules/TheExtensionLab_MegaMenu.xml app/etc/modules/TheExtensionLab_MegaMenu.xml 2 | app/code/community/TheExtensionLab/MegaMenu/ app/code/community/TheExtensionLab/MegaMenu/ 3 | app/design/adminhtml/default/default/layout/theextensionlab/megamenu.xml app/design/adminhtml/default/default/layout/theextensionlab/megamenu.xml 4 | app/design/adminhtml/default/default/template/theextensionlab/megamenu/ app/design/adminhtml/default/default/template/theextensionlab/megamenu/ 5 | app/design/frontend/base/default/layout/theextensionlab/megamenu.xml app/design/frontend/base/default/layout/theextensionlab/megamenu.xml 6 | app/design/frontend/base/default/template/theextensionlab/megamenu/ app/design/frontend/base/default/template/theextensionlab/megamenu/ 7 | skin/frontend/base/default/css/theextensionlab/megamenu/ skin/frontend/base/default/css/theextensionlab/megamenu/ 8 | skin/frontend/base/default/scss/theextensionlab/megamenu/ skin/frontend/base/default/scss/theextensionlab/megamenu/ 9 | skin/frontend/default/default/css/theextensionlab/megamenu/ skin/frontend/default/default/css/theextensionlab/megamenu/ 10 | skin/frontend/base/default/js/theextensionlab/megamenu/ skin/frontend/base/default/js/theextensionlab/megamenu/ 11 | skin/adminhtml/default/default/theextensionlab/megamenu/ skin/adminhtml/default/default/theextensionlab/megamenu/ 12 | js/theextensionlab/megamenu js/theextensionlab/megamenu 13 | app/locale/de_DE/TheExtensionLab_MegaMenu.csv app/locale/de_DE/TheExtensionLab_MegaMenu.csv 14 | app/locale/en_US/TheExtensionLab_MegaMenu.csv app/locale/en_US/TheExtensionLab_MegaMenu.csv 15 | -------------------------------------------------------------------------------- /skin/adminhtml/default/default/theextensionlab/megamenu/css/widget/draggable.css: -------------------------------------------------------------------------------- 1 | .tree-container { 2 | background-color: #fff; 3 | float: right; 4 | width: 49%; 5 | border: 1px solid #eaeaea; 6 | box-sizing: border-box; 7 | padding: 10px; 8 | } 9 | 10 | .tree-container.first { 11 | float: left; 12 | } 13 | 14 | .tree-header { 15 | background-color: #6f8992; 16 | font-weight: bold; 17 | padding: 10px; 18 | color: #fff; 19 | } 20 | 21 | .tree-header p { 22 | margin-bottom: 0px; 23 | } 24 | 25 | .tree-content { 26 | padding: 10px; 27 | } 28 | 29 | .categorie-trees-box { 30 | clear: both; 31 | overflow: hidden; 32 | } 33 | 34 | #save-categories { 35 | margin-top: 20px; 36 | float: right; 37 | } -------------------------------------------------------------------------------- /skin/frontend/base/default/css/theextensionlab/megamenu/grid.css: -------------------------------------------------------------------------------- 1 | /* 2 | TheExtensionLab MegaMenu Grid 3 | Based on 960 Grid System - http://960.gs/ & 960 Fluid - http://www.designinfluences.com/ 4 | */ 5 | .column { 6 | float: left; 7 | position: relative; 8 | box-sizing: border-box; 9 | } 10 | 11 | .xlab_grid_container { 12 | width: 100%; 13 | overflow: hidden; 14 | } 15 | 16 | .xlab_grid_container .xlab_column_1_24 { 17 | width: 4.16667%; 18 | } 19 | 20 | .xlab_grid_container .xlab_column_2_24 { 21 | width: 8.33333%; 22 | } 23 | 24 | .xlab_grid_container .xlab_column_3_24 { 25 | width: 12.5%; 26 | } 27 | 28 | .xlab_grid_container .xlab_column_4_24 { 29 | width: 16.66667%; 30 | } 31 | 32 | .xlab_grid_container .xlab_column_5_24 { 33 | width: 20.83333%; 34 | } 35 | 36 | .xlab_grid_container .xlab_column_6_24 { 37 | width: 25%; 38 | } 39 | 40 | .xlab_grid_container .xlab_column_7_24 { 41 | width: 29.16667%; 42 | } 43 | 44 | .xlab_grid_container .xlab_column_8_24 { 45 | width: 33.33333%; 46 | } 47 | 48 | .xlab_grid_container .xlab_column_9_24 { 49 | width: 37.5%; 50 | } 51 | 52 | .xlab_grid_container .xlab_column_10_24 { 53 | width: 41.66667%; 54 | } 55 | 56 | .xlab_grid_container .xlab_column_11_24 { 57 | width: 45.83333%; 58 | } 59 | 60 | .xlab_grid_container .xlab_column_12_24 { 61 | width: 50%; 62 | } 63 | 64 | .xlab_grid_container .xlab_column_13_24 { 65 | width: 54.16667%; 66 | } 67 | 68 | .xlab_grid_container .xlab_column_14_24 { 69 | width: 58.33333%; 70 | } 71 | 72 | .xlab_grid_container .xlab_column_15_24 { 73 | width: 62.5%; 74 | } 75 | 76 | .xlab_grid_container .xlab_column_16_24 { 77 | width: 66.66667%; 78 | } 79 | 80 | .xlab_grid_container .xlab_column_17_24 { 81 | width: 70.83333%; 82 | } 83 | 84 | .xlab_grid_container .xlab_column_18_24 { 85 | width: 75%; 86 | } 87 | 88 | .xlab_grid_container .xlab_column_19_24 { 89 | width: 79.16667%; 90 | } 91 | 92 | .xlab_grid_container .xlab_column_20_24 { 93 | width: 83.33333%; 94 | } 95 | 96 | .xlab_grid_container .xlab_column_21_24 { 97 | width: 87.5%; 98 | } 99 | 100 | .xlab_grid_container .xlab_column_22_24 { 101 | width: 91.66667%; 102 | } 103 | 104 | .xlab_grid_container .xlab_column_23_24 { 105 | width: 95.83333%; 106 | } 107 | 108 | .xlab_grid_container .xlab_column_24_24 { 109 | width: 100%; 110 | } 111 | 112 | .xlab_grid_container .xlab_column_1_5 { 113 | width: 20%; 114 | } 115 | 116 | .xlab_grid_container .xlab_column_2_5 { 117 | width: 40%; 118 | } 119 | 120 | .xlab_grid_container .xlab_column_3_5 { 121 | width: 60%; 122 | } 123 | 124 | .xlab_grid_container .xlab_column_4_5 { 125 | width: 80%; 126 | } 127 | 128 | .xlab_grid_container .xlab_column_5_5 { 129 | width: 100%; 130 | } 131 | 132 | .xlab_grid_container div[class^="xlab_grid_"] { 133 | width: 100%; 134 | } 135 | -------------------------------------------------------------------------------- /skin/frontend/base/default/css/theextensionlab/megamenu/main.css: -------------------------------------------------------------------------------- 1 | /*----------- Main DropDown Positioning ---------------*/ 2 | .megamenu-nav { 3 | position: relative; 4 | z-index: 150; 5 | } 6 | .megamenu-nav li { 7 | position: static; 8 | } 9 | 10 | .megamenu-nav-primary { 11 | display: block; 12 | margin-top: 15px; 13 | } 14 | .megamenu-nav-primary li.level0 { 15 | display: inline-block; 16 | } 17 | .megamenu-nav-primary li.level0 > a, .megamenu-nav-primary li.level0 > span { 18 | text-transform: uppercase; 19 | display: inline-block; 20 | position: relative; 21 | padding: 0 12px 0 8px; 22 | text-decoration: none; 23 | display: block; 24 | cursor: pointer; 25 | } 26 | .megamenu-nav-primary a.level0, .megamenu-nav-primary span.level0 { 27 | padding: 0 25px; 28 | border-bottom: 0px; 29 | } 30 | .megamenu-nav-primary .megamenu { 31 | position: absolute; 32 | display: none; 33 | z-index: 10; 34 | } 35 | .megamenu-nav-primary .megamenu .button { 36 | color: #fff; 37 | } 38 | .megamenu-nav-primary .menu-active .megamenu { 39 | display: block; 40 | } 41 | .megamenu-nav-primary a, .megamenu-nav-primary span.level0 { 42 | color: #636363; 43 | display: block; 44 | } 45 | .megamenu-nav-primary a:hover, .megamenu-nav-primary span.level0:hover { 46 | color: #3399cc; 47 | text-decoration: none; 48 | } 49 | .megamenu-nav-primary a, .megamenu-nav-primary span.level0, .megamenu-nav-primary .section-title span { 50 | line-height: 30px; 51 | } 52 | .megamenu-nav-primary li:hover > a { 53 | color: #3399cc; 54 | text-decoration: none; 55 | } 56 | 57 | /*----------- Main DropDown Styling ---------------*/ 58 | .megamenu-nav div.megamenu { 59 | background-color: #fff; 60 | border: 1px solid #e8eaeb; 61 | } 62 | 63 | .megamenu-nav .megamenu .column:not(:last-child) { 64 | border-right: 1px solid #eceff1; 65 | } 66 | 67 | .megamenu-nav .megamenu-nav-primary div.megamenu { 68 | border-top: 2px solid #64b5f6; 69 | } 70 | 71 | /*----------- Dropdown Types ---------------*/ 72 | .megamenu-nav li.level0 .absolute-center { 73 | left: 0px; 74 | right: 0px; 75 | width: 100% !important; 76 | } 77 | .megamenu-nav li.level0 .absolute-left { 78 | left: 0px; 79 | right: auto; 80 | } 81 | .megamenu-nav li.level0 .absolute-right { 82 | right: 0px; 83 | left: auto; 84 | } 85 | 86 | /*----------- Content Columns ---------------*/ 87 | .content-columns-1 { 88 | -webkit-column-count: 1; 89 | /* Chrome, Safari, Opera */ 90 | -moz-column-count: 1; 91 | /* Firefox */ 92 | column-count: 1; 93 | } 94 | 95 | .content-columns-2 { 96 | -webkit-column-count: 2; 97 | /* Chrome, Safari, Opera */ 98 | -moz-column-count: 2; 99 | /* Firefox */ 100 | column-count: 2; 101 | } 102 | 103 | .content-columns-3 { 104 | -webkit-column-count: 3; 105 | /* Chrome, Safari, Opera */ 106 | -moz-column-count: 3; 107 | /* Firefox */ 108 | column-count: 3; 109 | } 110 | 111 | .content-columns-4 { 112 | -webkit-column-count: 4; 113 | /* Chrome, Safari, Opera */ 114 | -moz-column-count: 4; 115 | /* Firefox */ 116 | column-count: 4; 117 | } 118 | 119 | .content-columns-5 { 120 | -webkit-column-count: 5; 121 | /* Chrome, Safari, Opera */ 122 | -moz-column-count: 5; 123 | /* Firefox */ 124 | column-count: 5; 125 | } 126 | 127 | /*----------- Featured Product ---------------*/ 128 | .megamenu-featured-products { 129 | padding: 27px 27px 0px; 130 | } 131 | 132 | .featured-product { 133 | text-align: center; 134 | } 135 | .featured-product img { 136 | margin: 0 auto 15px; 137 | padding: 10px; 138 | border: 1px solid #eceff1; 139 | box-sizing: border-box; 140 | max-width: 100%; 141 | } 142 | .featured-product .button { 143 | margin-top: 5px; 144 | } 145 | .secondary .featured-product { 146 | text-align: left; 147 | } 148 | .megamenu-nav .secondary .featured-product { 149 | overflow: hidden; 150 | } 151 | .megamenu-nav .secondary .featured-product .bd { 152 | overflow: hidden; 153 | padding: 30px 0px 0px; 154 | } 155 | .megamenu-nav .secondary .featured-product .img { 156 | float: left; 157 | margin-right: 15px; 158 | max-width: 150px; 159 | } 160 | .megamenu-nav .secondary .featured-product .img img { 161 | display: block; 162 | } 163 | .megamenu-nav .secondary .featured-product .imgExt { 164 | float: right; 165 | } 166 | .megamenu-nav .secondary .featured-product .button { 167 | float: left; 168 | padding: 5px; 169 | line-height: 16px; 170 | } 171 | 172 | /*----------- Featured Category ---------------*/ 173 | .featured-section, .featured-section a { 174 | position: relative; 175 | } 176 | 177 | .featured-section { 178 | padding: 15px; 179 | } 180 | .featured-section img { 181 | width: 100%; 182 | } 183 | .featured-section a span { 184 | background-color: rgba(100, 181, 246, 0.35); 185 | bottom: 0; 186 | color: #ffffff; 187 | font-size: 13px; 188 | font-weight: bold; 189 | left: 0; 190 | margin-right: 10px; 191 | padding: 5px 10px; 192 | position: absolute; 193 | text-align: center; 194 | text-transform: uppercase; 195 | width: 100%; 196 | box-sizing: border-box; 197 | } 198 | 199 | /*------------- Component Styles --------------*/ 200 | .section-title { 201 | font-weight: bold; 202 | letter-spacing: 1px; 203 | margin-bottom: 10px; 204 | } 205 | 206 | /*------------- Widget Blocks --------------*/ 207 | .list-block { 208 | margin-left: 20px; 209 | padding: 10px 45px; 210 | } 211 | .list-block:first-of-type { 212 | padding-top: 35px; 213 | } 214 | .list-block:last-of-type { 215 | padding-bottom: 35px; 216 | } 217 | .list-block li a { 218 | padding: 0px; 219 | border: 0px; 220 | } 221 | 222 | /*------------- Display Classes --------------*/ 223 | .small-only-view-all { 224 | display: none; 225 | } 226 | -------------------------------------------------------------------------------- /skin/frontend/base/default/css/theextensionlab/megamenu/responsive.css: -------------------------------------------------------------------------------- 1 | @media only screen and (max-width: 770px) { 2 | /*------------- Widget Blocks --------------*/ 3 | .list-block { 4 | margin-left: 0px; 5 | padding: 10px 25px; 6 | } 7 | .list-block:first-of-type { 8 | padding-top: 15px; 9 | } 10 | .list-block:last-of-type { 11 | padding-bottom: 15px; 12 | } 13 | } 14 | @media only screen and (max-width: 770px) { 15 | .megamenu-nav-primary li.level0 { 16 | display: block; 17 | } 18 | .megamenu-nav-primary li.level0 > a, .megamenu-nav-primary li.level0 > span { 19 | display: block; 20 | } 21 | .megamenu-nav-primary a.level0, .megamenu-nav-primary span.level0 { 22 | border-bottom: 1px solid #cccccc; 23 | } 24 | .megamenu-nav-primary .megamenu { 25 | position: relative; 26 | width: 100% !important; 27 | } 28 | .megamenu-nav-primary .megamenu > div { 29 | width: 100%; 30 | } 31 | 32 | .megamenu-nav-primary li.level0 > a, 33 | .megamenu-nav-primary li.level0 > span { 34 | padding-left: 25px; 35 | } 36 | 37 | .megamenu-nav-primary li.parent > a:after, 38 | .megamenu-nav-primary li.parent > span:after{ 39 | content: ''; 40 | position: absolute; 41 | width: 0; 42 | height: 0; 43 | display: block; 44 | border-top: 5px solid transparent; 45 | border-bottom: 5px solid transparent; 46 | border-left: 5px solid #cccccc; 47 | border-right: none; 48 | top: 50%; 49 | left: 10px; 50 | right: auto; 51 | margin-top: -5px; 52 | } 53 | 54 | .megamenu-nav-primary li.parent.menu-active > a:after, 55 | .megamenu-nav-primary li.parent.menu-active > span:after{ 56 | content: ''; 57 | position: absolute; 58 | width: 0; 59 | height: 0; 60 | display: block; 61 | border-right: 5px solid transparent; 62 | border-left: 5px solid transparent; 63 | border-top: 5px solid #cccccc; 64 | border-bottom: none; 65 | top: 50%; 66 | left: 10px; 67 | right: auto; 68 | margin-top: -5px; 69 | } 70 | 71 | /*----------- Main DropDown Styling ---------------*/ 72 | .megamenu-nav .megamenu-nav-primary div.megamenu { 73 | border-top: 0px; 74 | margin-left: 0px !important; 75 | margin-right: 0px !important; 76 | } 77 | 78 | /*------------- Component Styles --------------*/ 79 | li.section-title { 80 | margin-bottom: 0px; 81 | } 82 | li.section-title span { 83 | display: block; 84 | border-bottom: 1px solid #ccc; 85 | padding: 0 15px 0 25px; 86 | line-height: 30px; 87 | } 88 | li.section-title span > a { 89 | padding: 0px; 90 | border-bottom: 0px; 91 | } 92 | 93 | /*------------- Widget Blocks --------------*/ 94 | .list-block li a { 95 | padding: 0 15px 0 25px; 96 | border-bottom: 1px solid #ccc; 97 | } 98 | 99 | /*------------- Display Classes --------------*/ 100 | .hide-on-small { 101 | display: none !important; 102 | } 103 | 104 | .categories-list-block .list-title { 105 | display: none; 106 | } 107 | 108 | .small-only-view-all { 109 | display: block; 110 | } 111 | 112 | .xlab_grid_container .xlab_column_1_24 { 113 | width: 100%; 114 | } 115 | 116 | .xlab_grid_container .xlab_column_2_24 { 117 | width: 100%; 118 | } 119 | 120 | .xlab_grid_container .xlab_column_3_24 { 121 | width: 100%; 122 | } 123 | 124 | .xlab_grid_container .xlab_column_4_24 { 125 | width: 100%; 126 | } 127 | 128 | .xlab_grid_container .xlab_column_5_24 { 129 | width: 100%; 130 | } 131 | 132 | .xlab_grid_container .xlab_column_6_24 { 133 | width: 100%; 134 | } 135 | 136 | .xlab_grid_container .xlab_column_7_24 { 137 | width: 100%; 138 | } 139 | 140 | .xlab_grid_container .xlab_column_8_24 { 141 | width: 100%; 142 | } 143 | 144 | .xlab_grid_container .xlab_column_9_24 { 145 | width: 100%; 146 | } 147 | 148 | .xlab_grid_container .xlab_column_10_24 { 149 | width: 100%; 150 | } 151 | 152 | .xlab_grid_container .xlab_column_11_24 { 153 | width: 100%; 154 | } 155 | 156 | .xlab_grid_container .xlab_column_12_24 { 157 | width: 100%; 158 | } 159 | 160 | .xlab_grid_container .xlab_column_13_24 { 161 | width: 100%; 162 | } 163 | 164 | .xlab_grid_container .xlab_column_14_24 { 165 | width: 100%; 166 | } 167 | 168 | .xlab_grid_container .xlab_column_15_24 { 169 | width: 100%; 170 | } 171 | 172 | .xlab_grid_container .xlab_column_16_24 { 173 | width: 100%; 174 | } 175 | 176 | .xlab_grid_container .xlab_column_17_24 { 177 | width: 100%; 178 | } 179 | 180 | .xlab_grid_container .xlab_column_18_24 { 181 | width: 100%; 182 | } 183 | 184 | .xlab_grid_container .xlab_column_19_24 { 185 | width: 100%; 186 | } 187 | 188 | .xlab_grid_container .xlab_column_20_24 { 189 | width: 100%; 190 | } 191 | 192 | .xlab_grid_container .xlab_column_21_24 { 193 | width: 100%; 194 | } 195 | 196 | .xlab_grid_container .xlab_column_22_24 { 197 | width: 100%; 198 | } 199 | 200 | .xlab_grid_container .xlab_column_23_24 { 201 | width: 100%; 202 | } 203 | 204 | .xlab_grid_container .xlab_column_24_24 { 205 | width: 100%; 206 | } 207 | 208 | .xlab_grid_container .xlab_column_1_5 { 209 | width: 100%; 210 | } 211 | 212 | .xlab_grid_container .xlab_column_2_5 { 213 | width: 100%; 214 | } 215 | 216 | .xlab_grid_container .xlab_column_3_5 { 217 | width: 100%; 218 | } 219 | 220 | .xlab_grid_container .xlab_column_4_5 { 221 | width: 100%; 222 | } 223 | 224 | .xlab_grid_container .xlab_column_5_5 { 225 | width: 100%; 226 | } 227 | } 228 | @media only screen and (min-width: 771px) and (max-width: 979px) { 229 | .hide-on-medium { 230 | display: none !important; 231 | } 232 | } 233 | @media only screen and (min-width: 980px) { 234 | .hide-on-large { 235 | display: none !important; 236 | } 237 | } 238 | -------------------------------------------------------------------------------- /skin/frontend/base/default/css/theextensionlab/megamenu/theme-specific.css: -------------------------------------------------------------------------------- 1 | /* 2 | This file is used to add theme specific styles for themes such as default or rwd 3 | you can either override this file or put your custom styles in your theme's main css file 4 | */ -------------------------------------------------------------------------------- /skin/frontend/base/default/js/theextensionlab/megamenu/menu-bp.js: -------------------------------------------------------------------------------- 1 | //If you need to update the menu breadpoints simply override this file in your theme. 2 | 3 | var menubp = { 4 | xsmall: 479, 5 | small: 599, 6 | medium: 770, 7 | large: 979, 8 | xlarge: 1199 9 | }; -------------------------------------------------------------------------------- /skin/frontend/base/default/js/theextensionlab/megamenu/menu.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Derivative work based on js/varien/menu.js created by: 3 | * X.commerce, Inc. (http://www.magento.com) 4 | * 5 | * @copyright Copyright (c) 2006-2015 X.commerce, Inc. (http://www.magento.com) 6 | * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) 7 | * 8 | * Changes by: TheExtensionLab 9 | * @package TheExtensionLab_MegaMenu 10 | * @copyright Copyright (c) 2015 TheExtensionLab (http://www.theextensionlab.com) 11 | * @license Open Software License (OSL 3.0 12 | * @author James Anelay @ TheExtensionLab 13 | * 14 | */ 15 | 16 | var windowSize = {}; 17 | 18 | var rtime; 19 | 20 | var getWindowSize = function() { 21 | windowSize.height = document.viewport.getHeight(); 22 | windowSize.width = document.viewport.getWidth(); 23 | }; 24 | 25 | Event.observe(window, "delayed:resize", function() { 26 | getWindowSize(); 27 | }); 28 | 29 | var mainNav = function() { 30 | 31 | getWindowSize(); 32 | 33 | var main = { 34 | obj_nav : $(arguments[0]) || $("megamenu-nav-main"), 35 | 36 | settings : { 37 | show_delay : 0, 38 | hide_delay : 0, 39 | window_resize_delay : 350, 40 | timeout : false 41 | }, 42 | 43 | init : function(obj, level) { 44 | main.initDelayedResizingEvent(); 45 | obj.lists = obj.childElements(); 46 | obj.lists.each(function(el,ind){ 47 | var newChildren = el.select('div,ul,section'); 48 | newChildren.each(function(childel,ind){ 49 | main.handlNavElementBubbling(childel); 50 | }); 51 | main.handlNavElement(el); 52 | }); 53 | }, 54 | 55 | initDelayedResizingEvent : function() 56 | { 57 | Event.observe(window, "resize", function() { 58 | rtime = new Date(); 59 | if (main.settings.timeout === false) { 60 | main.settings.timeout = true; 61 | setTimeout(main.resizeend, main.settings.window_resize_delay); 62 | } 63 | }); 64 | 65 | }, 66 | 67 | resizeend : function() 68 | { 69 | if (new Date() - rtime < main.settings.window_resize_delay) { 70 | setTimeout(main.resizeend, main.settings.window_resize_delay); 71 | } else { 72 | main.settings.timeout = false; 73 | Event.fire(window,"delayed:resize"); 74 | } 75 | }, 76 | 77 | handlNavElementBubbling : function(child) { 78 | child.onclick = function(e){ 79 | e.stopPropagation(); 80 | } 81 | }, 82 | 83 | handlNavElement : function(list) { 84 | if(list !== undefined){ 85 | 86 | list.on('touchstart',function(e){ 87 | list.writeAttribute('was-touch',true); 88 | }); 89 | 90 | list.onmouseover = function(){ 91 | if(windowSize.width < menubp.medium && main.obj_nav.hasClassName('responsive')) { 92 | 93 | }else{ 94 | main.fireNavEvent(this, true); 95 | } 96 | 97 | }; 98 | list.onmouseout = function(){ 99 | if(windowSize.width < menubp.medium && main.obj_nav.hasClassName('responsive')) { 100 | 101 | }else{ 102 | main.fireNavEvent(this, false); 103 | } 104 | }; 105 | 106 | list.onclick = function(e){ 107 | 108 | if(windowSize.width < menubp.medium || list.readAttribute('was-touch')) { 109 | if(this.hasClassName('parent') && main.obj_nav.hasClassName('responsive')) { 110 | e.stop(); 111 | main.fireNavEvent(this, 'toggle'); 112 | } 113 | } 114 | 115 | list.writeAttribute('was-touch',false);//cleanup 116 | } 117 | } 118 | }, 119 | 120 | 121 | fireNavEvent : function(element,active) { 122 | if(element != undefined) { 123 | if (active == true) { 124 | element.addClassName("menu-active"); 125 | } else if (active == false) { 126 | element.removeClassName("menu-active"); 127 | } else if (active == "toggle") { 128 | element.toggleClassName("menu-active"); 129 | } 130 | } 131 | } 132 | }; 133 | if (arguments[1]) { 134 | main.settings = Object.extend(main.settings, arguments[1]); 135 | } 136 | if (main.obj_nav) { 137 | main.init(main.obj_nav, false); 138 | } 139 | }; 140 | 141 | document.observe("dom:loaded", function() { 142 | mainNav("nav", {"show_delay":"100","hide_delay":"100"}); 143 | 144 | $$('.relative-center').each(function (item, index) { 145 | var parentLi = $(item).up('li'); 146 | var parentLiWidth = parentLi.getWidth(); 147 | var itemWidth = $(item).getWidth(); 148 | var requiredRightMargin = ((itemWidth - parentLiWidth) / 2) * -1; 149 | $(item).setStyle({ 150 | 'margin-left': requiredRightMargin + 'px' 151 | }); 152 | }); 153 | 154 | $$('.hang-left').each(function (item,index) { 155 | var parentLi = $(item).up('li'); 156 | var parentLiWidth = parentLi.getWidth(); 157 | var itemWidth = $(item).getWidth(); 158 | var requiredRightMargin = (itemWidth - parentLiWidth) * -1; 159 | $(item).setStyle({ 160 | 'margin-left': requiredRightMargin + 'px' 161 | }); 162 | }); 163 | }); 164 | -------------------------------------------------------------------------------- /skin/frontend/base/default/scss/theextensionlab/megamenu/_settings.scss: -------------------------------------------------------------------------------- 1 | //RWD DEFAULTS 2 | //$bp-xsmall: 479px; 3 | //$bp-small: 599px; 4 | //$bp-medium: 770px; 5 | //$bp-large: 979px; 6 | //$bp-xlarge: 1199px; 7 | 8 | $medium-up: "only screen and (min-width: 771px)"; 9 | $small-only: "only screen and (max-width: 770px)"; 10 | $medium-only: "only screen and (min-width:771px) and (max-width: 979px)"; 11 | $large-only: "only screen and (min-width:980px)"; 12 | $large-up: "only screen and (min-width:980px)"; 13 | 14 | $medium-down: "only screen and (max-width: 770px)"; 15 | $small-down:"only screen and (max-width: 770px)"; 16 | 17 | $class-prefix: 'xlab_'; 18 | $grid-columns: 24; 19 | $container-class: '#{$class-prefix}grid_container'; -------------------------------------------------------------------------------- /skin/frontend/base/default/scss/theextensionlab/megamenu/grid.scss: -------------------------------------------------------------------------------- 1 | /* 2 | TheExtensionLab MegaMenu Grid 3 | Based on 960 Grid System - http://960.gs/ & 960 Fluid - http://www.designinfluences.com/ 4 | */ 5 | @import "settings"; 6 | @import "mixins/main"; 7 | @import "mixins/grid"; 8 | 9 | .column { 10 | float: left; 11 | position: relative; 12 | box-sizing: border-box; 13 | } 14 | 15 | .#{$container-class} { 16 | width: 100%; 17 | overflow: hidden; 18 | } 19 | 20 | @for $i from 1 through $grid-columns { 21 | .#{$container-class} .#{$class-prefix}column_#{$i}_#{$grid-columns} { 22 | @include grid_column($i); 23 | } 24 | //@media #{$small-only}{ 25 | // .#{$container-class}.responsive .#{$class-prefix}column_#{$i}_#{$grid-columns} { 26 | // @include grid_column($grid-columns); //if has .responsive class set columns to 100% on small screens 27 | // } 28 | //} 29 | } 30 | 31 | @for $i from 1 through 5 { 32 | .#{$container-class} .#{$class-prefix}column_#{$i}_5 { 33 | @include grid_column($i, 5); 34 | } 35 | //@media #{$small-only}{ 36 | // .#{$container-class}.responsive .#{$class-prefix}column_#{$i}_5 { 37 | // @include grid_column($grid-columns); //if has .responsive class set columns to 100% on small screens 38 | // } 39 | //} 40 | } 41 | 42 | .#{$container-class} div[class^="#{$class-prefix}grid_"] { 43 | @include grid_column(24, 24); 44 | } -------------------------------------------------------------------------------- /skin/frontend/base/default/scss/theextensionlab/megamenu/main.scss: -------------------------------------------------------------------------------- 1 | @import "mixins/main"; 2 | @import "settings"; 3 | 4 | $dropdown-background-color: #fff; 5 | $dropdown-internals-border-color: #eceff1; 6 | $dropdwon-external-border-color: #e8eaeb; 7 | 8 | /*----------- Main DropDown Positioning ---------------*/ 9 | .megamenu-nav{ 10 | position: relative; 11 | z-index: 150; 12 | 13 | li{ 14 | position: static; 15 | } 16 | } 17 | 18 | .megamenu-nav-primary { 19 | display: block; 20 | margin-top: 15px; 21 | li.level0{ 22 | display: inline-block; 23 | & > a, & > span{ 24 | text-transform: uppercase; 25 | display: inline-block; 26 | position:relative; 27 | padding: 0 12px 0 8px; 28 | text-decoration: none; 29 | display:block; 30 | cursor:pointer; 31 | } 32 | } 33 | 34 | a.level0,span.level0{ 35 | padding: 0 25px; 36 | border-bottom:0px; 37 | } 38 | 39 | .megamenu{ 40 | position: absolute; 41 | display:none; 42 | z-index: 10; 43 | 44 | .button{ 45 | color:#fff; 46 | } 47 | } 48 | 49 | .menu-active{ 50 | .megamenu{ 51 | display:block; 52 | } 53 | } 54 | 55 | a,span.level0 { 56 | color: #636363; 57 | display:block; 58 | &:hover{ 59 | color:#3399cc; 60 | text-decoration:none; 61 | } 62 | } 63 | 64 | a,span.level0,.section-title span{ 65 | line-height:30px; 66 | } 67 | 68 | li{ 69 | &:hover{ 70 | > a{ 71 | color:#3399cc; 72 | text-decoration:none; 73 | } 74 | } 75 | } 76 | } 77 | 78 | /*----------- Main DropDown Styling ---------------*/ 79 | 80 | .megamenu-nav div.megamenu { 81 | background-color: $dropdown-background-color; 82 | border: 1px solid $dropdwon-external-border-color; 83 | } 84 | 85 | .megamenu-nav .megamenu .column:not(:last-child) { 86 | border-right: 1px solid $dropdown-internals-border-color; 87 | } 88 | 89 | .megamenu-nav .megamenu-nav-primary div.megamenu { 90 | border-top: 2px solid #64b5f6; 91 | } 92 | 93 | /*----------- Dropdown Types ---------------*/ 94 | .megamenu-nav { 95 | li { 96 | &.level0 { 97 | .absolute-center { 98 | left: 0px; 99 | right: 0px; 100 | width: 100% !important; 101 | } 102 | 103 | .absolute-left { 104 | left: 0px; 105 | right: auto; 106 | } 107 | 108 | .absolute-right { 109 | right: 0px; 110 | left: auto; 111 | } 112 | } 113 | } 114 | } 115 | 116 | /*----------- Content Columns ---------------*/ 117 | $max-content-columns: 5; 118 | @for $i from 1 through $max-content-columns { 119 | .content-columns-#{$i} { 120 | -webkit-column-count: $i; /* Chrome, Safari, Opera */ 121 | -moz-column-count: $i; /* Firefox */ 122 | column-count: $i; 123 | } 124 | } 125 | 126 | /*----------- Featured Product ---------------*/ 127 | 128 | .megamenu-featured-products { 129 | padding: 27px 27px 0px; 130 | } 131 | 132 | .featured-product { 133 | text-align: center; 134 | 135 | img { 136 | margin: 0 auto 15px; 137 | padding: 10px; 138 | border: 1px solid $dropdown-internals-border-color; 139 | box-sizing: border-box; 140 | max-width: 100%; 141 | } 142 | 143 | .button { 144 | margin-top: 5px; 145 | } 146 | 147 | .secondary & { 148 | text-align: left; 149 | 150 | .megamenu-nav & { 151 | //increase specificity due to resets 152 | @include media_object($image-margin: 15px, $max-image-width: 150px, $bd-padding: 30px 0px 0px); 153 | 154 | .button { 155 | float: left; 156 | padding: 5px; 157 | line-height: 16px; 158 | } 159 | 160 | } 161 | } 162 | } 163 | 164 | /*----------- Featured Category ---------------*/ 165 | .featured-section, .featured-section a { 166 | position: relative; 167 | } 168 | 169 | .featured-section { 170 | padding: 15px; 171 | img { 172 | width: 100%; 173 | } 174 | a { 175 | span { 176 | background-color: rgba(100, 181, 246, 0.35); 177 | bottom: 0; 178 | color: #ffffff; 179 | font-size: 13px; 180 | font-weight: bold; 181 | left: 0; 182 | margin-right: 10px; 183 | padding: 5px 10px; 184 | position: absolute; 185 | text-align: center; 186 | text-transform: uppercase; 187 | width: 100%; 188 | box-sizing: border-box; 189 | } 190 | } 191 | } 192 | 193 | /*------------- Component Styles --------------*/ 194 | 195 | .section-title { 196 | font-weight: bold; 197 | letter-spacing: 1px; 198 | margin-bottom: 10px; 199 | } 200 | 201 | 202 | /*------------- Widget Blocks --------------*/ 203 | 204 | .list-block { 205 | margin-left:20px; 206 | padding: 10px 45px; 207 | &:first-of-type { 208 | padding-top: 35px; 209 | } 210 | &:last-of-type { 211 | padding-bottom: 35px; 212 | } 213 | 214 | li { 215 | a { 216 | padding: 0px; 217 | border: 0px; 218 | } 219 | } 220 | } 221 | 222 | /*------------- Display Classes --------------*/ 223 | .small-only-view-all{ 224 | display:none; 225 | } -------------------------------------------------------------------------------- /skin/frontend/base/default/scss/theextensionlab/megamenu/mixins/_grid.scss: -------------------------------------------------------------------------------- 1 | @mixin grid_column($columns,$grid-columns:$grid-columns){ 2 | width: 100% / ($grid-columns/$columns); 3 | } -------------------------------------------------------------------------------- /skin/frontend/base/default/scss/theextensionlab/megamenu/mixins/_main.scss: -------------------------------------------------------------------------------- 1 | @mixin media_object($image-margin:null,$bd-padding:null,$max-image-width:null){ 2 | overflow:hidden; 3 | 4 | .bd{ 5 | overflow:hidden; 6 | @if $bd-padding != null{ 7 | padding: $bd-padding; 8 | } 9 | } 10 | 11 | .img{ 12 | float:left; 13 | @if $image-margin != null{ 14 | margin-right: $image-margin; 15 | } 16 | @if $max-image-width != null{ 17 | max-width: $max-image-width; 18 | } 19 | img{ 20 | display:block; 21 | } 22 | } 23 | 24 | .imgExt{ 25 | float:right; 26 | } 27 | } -------------------------------------------------------------------------------- /skin/frontend/base/default/scss/theextensionlab/megamenu/responsive.scss: -------------------------------------------------------------------------------- 1 | @import "mixins/main"; 2 | @import "settings"; 3 | @import "mixins/main"; 4 | @import "mixins/grid"; 5 | 6 | @media #{$medium-down}{ 7 | /*------------- Widget Blocks --------------*/ 8 | .list-block { 9 | margin-left: 0px; 10 | padding: 10px 25px; 11 | &:first-of-type { 12 | padding-top: 15px; 13 | } 14 | &:last-of-type { 15 | padding-bottom: 15px; 16 | } 17 | } 18 | } 19 | 20 | @media #{$small-down}{ 21 | .megamenu-nav-primary{ 22 | li.level0{ 23 | display: block; 24 | & > a,& > span{ 25 | display:block; 26 | } 27 | } 28 | a.level0,span.level0{ 29 | border-bottom: 1px solid #cccccc; 30 | } 31 | .megamenu{ 32 | position:relative; 33 | width:100% !important; 34 | & > div{ 35 | width:100%; 36 | } 37 | } 38 | } 39 | 40 | .megamenu-nav-primary li.level0 > a, 41 | .megamenu-nav-primary li.level0 > span{ 42 | padding-left:25px; 43 | } 44 | 45 | .megamenu-nav-primary li.parent > a:after, 46 | .megamenu-nav-primary li.parent > span:after{ 47 | content: ''; 48 | position: absolute; 49 | width: 0; 50 | height: 0; 51 | display: block; 52 | border-top: 5px solid transparent; 53 | border-bottom: 5px solid transparent; 54 | border-left: 5px solid #cccccc; 55 | border-right: none; 56 | top: 50%; 57 | left: 10px; 58 | right: auto; 59 | margin-top: -5px; 60 | } 61 | 62 | .megamenu-nav-primary li.parent.menu-active > a:after, 63 | .megamenu-nav-primary li.parent.menu-active > span:after{ 64 | content: ''; 65 | position: absolute; 66 | width: 0; 67 | height: 0; 68 | display: block; 69 | border-right: 5px solid transparent; 70 | border-left: 5px solid transparent; 71 | border-top: 5px solid #cccccc; 72 | border-bottom: none; 73 | top: 50%; 74 | left: 10px; 75 | right: auto; 76 | margin-top: -5px; 77 | } 78 | 79 | /*----------- Main DropDown Styling ---------------*/ 80 | .megamenu-nav .megamenu-nav-primary div.megamenu { 81 | border-top:0px; 82 | margin-left:0px !important; 83 | margin-right:0px !important; 84 | } 85 | 86 | /*------------- Component Styles --------------*/ 87 | 88 | li.section-title { 89 | margin-bottom:0px; 90 | 91 | span{ 92 | display:block; 93 | border-bottom: 1px solid #ccc; 94 | padding:0 15px 0 25px; 95 | line-height:30px; 96 | 97 | > a { 98 | padding:0px; 99 | border-bottom:0px; 100 | } 101 | } 102 | } 103 | 104 | /*------------- Widget Blocks --------------*/ 105 | .list-block { 106 | li { 107 | a { 108 | padding: 0 15px 0 25px; 109 | border-bottom: 1px solid #ccc; 110 | } 111 | } 112 | } 113 | 114 | 115 | /*------------- Display Classes --------------*/ 116 | .hide-on-small { 117 | display: none !important; 118 | } 119 | 120 | .categories-list-block .list-title { 121 | display: none; 122 | } 123 | 124 | .small-only-view-all{ 125 | display:block; 126 | } 127 | 128 | 129 | @for $i from 1 through $grid-columns { 130 | .#{$container-class} .#{$class-prefix}column_#{$i}_#{$grid-columns} { 131 | @include grid_column($grid-columns); 132 | } 133 | } 134 | 135 | @for $i from 1 through 5 { 136 | .#{$container-class} .#{$class-prefix}column_#{$i}_5 { 137 | @include grid_column($grid-columns); 138 | } 139 | } 140 | } 141 | 142 | @media #{$medium-only} { 143 | .hide-on-medium{ 144 | display:none !important; 145 | } 146 | } 147 | 148 | @media #{$large-only} { 149 | .hide-on-large{ 150 | display:none !important; 151 | } 152 | } -------------------------------------------------------------------------------- /skin/frontend/default/default/css/theextensionlab/megamenu/theme-specific.css: -------------------------------------------------------------------------------- 1 | nav.megamenu-nav{ 2 | background: #0a263d url("../images/bkg_nav0.jpg") repeat-y scroll 50% 0; 3 | width:950px; 4 | text-align:left; 5 | margin:0 auto; 6 | } 7 | 8 | nav.megamenu-nav a.level0, 9 | nav.megamenu-nav li.level0 > span{ 10 | color:#a7c6dd; 11 | font-weight:bold; 12 | text-transform:none; 13 | } 14 | 15 | nav.megamenu-nav .megamenu-nav-primary{ 16 | margin-top:0px; 17 | } --------------------------------------------------------------------------------