├── CHANGELOG.md ├── README.md └── app ├── code └── community │ └── JR │ └── CleverCms │ ├── Block │ ├── Adminhtml │ │ ├── Cms │ │ │ └── Page │ │ │ │ ├── Edit.php │ │ │ │ ├── Permissions │ │ │ │ └── Tree.php │ │ │ │ ├── Tree.php │ │ │ │ └── Widget │ │ │ │ └── Chooser.php │ │ └── Customer │ │ │ └── Group │ │ │ └── Switcher.php │ ├── Catalog │ │ └── Navigation.php │ └── Cms │ │ └── Page.php │ ├── Helper │ └── Cms │ │ └── Page.php │ ├── Model │ ├── Adminhtml │ │ └── Cms │ │ │ └── Page │ │ │ └── Observer.php │ ├── Cms │ │ ├── Page.php │ │ └── Page │ │ │ └── Permission.php │ └── Resource │ │ ├── Cms │ │ ├── Page.php │ │ └── Page │ │ │ ├── Collection.php │ │ │ ├── Permission.php │ │ │ └── Tree.php │ │ ├── Setup.php │ │ └── Sitemap │ │ └── Cms │ │ └── Page.php │ ├── controllers │ ├── Adminhtml │ │ └── Cms │ │ │ ├── Page │ │ │ └── PermissionsController.php │ │ │ └── PageController.php │ └── Cms │ │ └── IndexController.php │ ├── etc │ ├── config.xml │ └── system.xml │ └── sql │ └── clever_cms_setup │ ├── mysql4-install-0.1.0.php │ └── mysql4-upgrade-2.0.0-2.1.0.php ├── design ├── adminhtml │ └── default │ │ └── clever │ │ ├── layout │ │ └── local.xml │ │ └── template │ │ ├── cms │ │ └── page │ │ │ ├── ajax-edit.phtml │ │ │ ├── index.phtml │ │ │ ├── permissions │ │ │ ├── index.phtml │ │ │ └── tree.phtml │ │ │ ├── store │ │ │ └── switcher.phtml │ │ │ └── tree.phtml │ │ └── customer │ │ └── group │ │ └── switcher.phtml └── frontend │ └── default │ └── clever │ └── template │ └── catalog │ └── navigation │ └── top.phtml ├── etc └── modules │ └── JR_CleverCms.xml └── locale └── fr_FR └── JR_CleverCms.csv /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 2.1.2 (branch: master) (2012-03-06) 2 | 3 | ### Fixes 4 | 5 | * Fixed bug 'cms_page_tree_store does not exist' 6 | * Fixed installation when single store mode 7 | 8 | ## 2.1.1 (branch: master) (2012-03-05) 9 | 10 | ### Fixes 11 | 12 | * Fixed bug 'Integrity constraint violation: 1062 Duplicate entry' during installation (thanks to vmarmiesse) 13 | 14 | ## 2.1.0 (branch: master) (2012-03-05) 15 | 16 | ### Features 17 | 18 | * Added Store View filter on global pages 19 | 20 | ## 2.0.1 (branch: master) (2012-03-04) 21 | 22 | ### Fixes 23 | 24 | * Fixed bug with html cache block in frontend navigation 25 | 26 | ## 2.0.0 (branch: master) (2012-02-16) 27 | 28 | ### Features 29 | 30 | * Added possibility to manage an unique tree for all store views 31 | * Entire extension structure refactoring 32 | 33 | ## 1.2.3 (branch: 1.2) (2012-02-16) 34 | 35 | ### Fixes 36 | 37 | * Fixed bug with unexpected T_PAAMAYIM_NEKUDOTAYIM 38 | 39 | ## 1.2.2 (2012-02-15) 40 | 41 | ### Fixes 42 | 43 | * Fixed bug with homepage breadcrumb 44 | 45 | ## 1.2.1 (2012-01-22) 46 | 47 | ### Fixes 48 | 49 | * Fixed bug with sort in frontend navigation 50 | 51 | ## 1.2.0 (2011-11-15) 52 | 53 | ### Features 54 | 55 | * Automatically set read permission when creating a page (thanks to zarembisty) 56 | 57 | ### Fixes 58 | 59 | * Fixed bug in url key initialization (thanks to jstern81) 60 | * Fixed bug when renaming pages with the same name (thanks to jstern81) 61 | * Fixed bug when deleting nested pages (thanks to jstern81) 62 | 63 | ## 1.1.0 (2011-10-26) 64 | 65 | ### Features 66 | 67 | * Added 301 permanent redirects option (Configuration > Content Management > Clever CMS) 68 | * Added URL Key configuration option for nested CMS pages for setting a URL Key independent of page title (thanks to jstern81) 69 | * Added Include in Navigation Menu option for Nested CMS pages (thanks to jstern81) 70 | 71 | ### Improvements 72 | 73 | * Enhanced the Navigation Menu css classes to more closely match those of the Categories navigation menu (thanks to jstern81) 74 | * Improved the Clever theme example Navigation Menu (thanks to jstern81) 75 | 76 | ### Fixes 77 | 78 | * Breadcrumb CMS links now end with a trailing slash (thanks to jstern81) 79 | * Fixed navigation menu items for CMS levels deeper than 3 (thanks to jstern81) 80 | 81 | ## 1.0.0 (2011-10-13) 82 | 83 | ### Features 84 | 85 | * Added frontend navigation (enable "clever" theme and "default" package to have an example of top navigation) 86 | 87 | ### Fixes 88 | 89 | * Fixed position sorting bug (thanks to kmb@deam.org) 90 | * Fixed sitemap bug (thanks to matsola) 91 | * Fixed bug with native homepage identifier (caused crash when uninstalling extension) 92 | 93 | ## 0.2.0 (2011-04-10) 94 | 95 | ### Features 96 | 97 | * Added permissions management 98 | * Added french translation 99 | 100 | ## 0.1.1 (2011-04-01) 101 | 102 | ### Fixes 103 | 104 | * Fixed widget cms page link 105 | * Fixed breadcrumbs in frontend 106 | * Fixed wrong level when new page is added 107 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Magento CMS pages as a tree structure 2 | 3 | ![Clever CMS](http://i.imgur.com/3NOIN.jpg) 4 | 5 | ## Features 6 | * CMS pages as a tree structure, drag & drop pages 7 | * Restrict CMS pages access to customer groups (if enabled) 8 | * Create 301 permanent redirects for old urls (if enabled) 9 | * Manage a global tree and a store view independent tree 10 | * Frontend navigation 11 | 12 | ## Installation 13 | 14 | ### Magento CE 1.6+ 15 | 16 | Install with [modgit](https://github.com/jreinke/modgit): 17 | 18 | $ cd /path/to/magento 19 | $ modgit init 20 | $ modgit -e README.md -e CHANGELOG.md clone clever-cms https://github.com/jreinke/magento-clever-cms.git 21 | 22 | or download package manually: 23 | 24 | * Download latest version [here](https://github.com/jreinke/magento-clever-cms/downloads) 25 | * Unzip in Magento root folder 26 | * Clean cache 27 | 28 | ### Magento CE 1.4.x, 1.5.x 29 | 30 | **Compatibility of master branch is not guaranteed with versions of Magento above!** 31 | **Please download/clone 1.2 branch** 32 | 33 | Install with [modgit](https://github.com/jreinke/modgit): 34 | 35 | $ cd /path/to/magento 36 | $ modgit init 37 | $ modgit -e README.md -e CHANGELOG.md clone clever-cms https://github.com/jreinke/magento-clever-cms.git --branch 1.2 38 | 39 | or download package manually: 40 | 41 | * Download 1.2.x version [here](https://github.com/jreinke/magento-clever-cms/tags) 42 | * Unzip in Magento root folder 43 | * Clean cache 44 | 45 | ## Full overview 46 | 47 | I wrote an article on my blog for full extension overview, [click here](http://www.johannreinke.com/en/2012/01/10/magento-cms-pages-in-a-tree-structure/). 48 | -------------------------------------------------------------------------------- /app/code/community/JR/CleverCms/Block/Adminhtml/Cms/Page/Edit.php: -------------------------------------------------------------------------------- 1 | _removeButton('back'); 9 | $this->_removeButton('reset'); 10 | $this->_removeButton('saveandcontinue'); 11 | $page = Mage::registry('cms_page'); 12 | if ($page && $page->getId() && $page->getParentId()) { 13 | $this->_addButton('delete', array( 14 | 'label' => Mage::helper('cms')->__('Delete Page'), 15 | 'onclick' => 'deleteConfirm(\'' . Mage::helper('adminhtml')->__('Are you sure you want to do this?') 16 | . '\', \'' . Mage::helper('adminhtml')->getUrl('*/*/delete', array('page_id' => $page->getId())) . '\')', 17 | 'class' => 'scalable delete', 18 | 'level' => -1 19 | )); 20 | } 21 | } 22 | 23 | public function getFormActionUrl() 24 | { 25 | $args = array(); 26 | 27 | if ($this->getRequest()->has('store')) { 28 | $args['store'] = $this->getRequest()->getParam('store'); 29 | } 30 | if ($this->getRequest()->has('parent')) { 31 | $args['parent'] = $this->getRequest()->getParam('parent'); 32 | } 33 | 34 | return $this->getUrl('*/*/save', $args); 35 | } 36 | } -------------------------------------------------------------------------------- /app/code/community/JR/CleverCms/Block/Adminhtml/Cms/Page/Permissions/Tree.php: -------------------------------------------------------------------------------- 1 | getPagesByStoreAndCustomerGroup($this->getStoreId(), $this->getCustomerGroupId()); 13 | $this->setSelectedResources($selectedPages); 14 | } 15 | 16 | public function getStore() 17 | { 18 | $storeId = (int) $this->getRequest()->getParam('store'); 19 | 20 | return Mage::app()->getStore($storeId); 21 | } 22 | 23 | public function getStoreId() 24 | { 25 | return $this->getStore()->getId(); 26 | } 27 | 28 | public function getCustomerGroup() 29 | { 30 | $groupId = (int) $this->getRequest()->getParam('group'); 31 | 32 | return Mage::getModel('customer/group')->load($groupId); 33 | } 34 | 35 | public function getCustomerGroupId() 36 | { 37 | return $this->getCustomerGroup()->getId(); 38 | } 39 | 40 | public function getRoot() 41 | { 42 | if (null === $this->_root) { 43 | $storeId = $this->getStoreId(); 44 | $this->_root = Mage::getModel('cms/page')->loadRootByStoreId($storeId); 45 | if (! $this->_root->getId()) { 46 | $this->_root = JR_CleverCms_Model_Cms_Page::createDefaultStoreRootPage($storeId); 47 | } 48 | } 49 | 50 | return $this->_root; 51 | } 52 | 53 | public function getRootId() 54 | { 55 | return $this->getRoot()->getId(); 56 | } 57 | 58 | public function getResTreeJson() 59 | { 60 | $root = $this->getRoot(); 61 | $rootArray = $this->_getNodeJson($root); 62 | $json = Mage::helper('core')->jsonEncode(array($rootArray)); 63 | 64 | return $json; 65 | } 66 | 67 | protected function _sortTree($a, $b) 68 | { 69 | return $a['sort_order'] < $b['sort_order'] ? -1 : ($a['sort_order'] > $b['sort_order'] ? 1 : 0); 70 | } 71 | 72 | protected function _getNodeJson(JR_CleverCms_Model_Cms_Page $page) 73 | { 74 | $item = array(); 75 | $selres = $this->getSelectedResources(); 76 | 77 | $item['text'] = $page->getTitle(); 78 | $item['sort_order'] = $page->getPosition(); 79 | $item['id'] = $page->getId(); 80 | 81 | if (in_array($item['id'], $selres)) { 82 | $item['checked'] = true; 83 | } 84 | 85 | $children = $page->getChildren(); 86 | 87 | if (empty($children)) { 88 | return $item; 89 | } 90 | 91 | if ($children) { 92 | $item['children'] = array(); 93 | foreach ($children as $child) { 94 | $item['children'][] = $this->_getNodeJson($child); 95 | } 96 | if (! empty($item['children'])) { 97 | usort($item['children'], array($this, '_sortTree')); 98 | } 99 | } 100 | 101 | return $item; 102 | } 103 | } -------------------------------------------------------------------------------- /app/code/community/JR/CleverCms/Block/Adminhtml/Cms/Page/Tree.php: -------------------------------------------------------------------------------- 1 | setUseAjax(true); 11 | $this->_withChildrenCount = true; 12 | } 13 | 14 | protected function _prepareLayout() 15 | { 16 | $addUrl = $this->getUrl("*/*/add", array( 17 | '_current'=>true, 18 | 'id'=>null, 19 | '_query' => false 20 | )); 21 | 22 | $this->setChild('add_sub_button', 23 | $this->getLayout()->createBlock('adminhtml/widget_button') 24 | ->setData(array( 25 | 'label' => Mage::helper('cms')->__('Add Page'), 26 | 'onclick' => "addNew('".$addUrl."', false)", 27 | 'class' => 'add', 28 | 'id' => 'add_subpage_button', 29 | 'style' => $this->canAddSubPage() ? '' : 'display: none;' 30 | )) 31 | ); 32 | 33 | $this->setChild('store_switcher', 34 | $this->getLayout()->createBlock('adminhtml/store_switcher') 35 | ->setSwitchUrl($this->getUrl('*/*/switch', array('_current'=>true, '_query'=>false, 'store'=>null))) 36 | ->setTemplate('cms/page/store/switcher.phtml') 37 | ); 38 | return parent::_prepareLayout(); 39 | } 40 | 41 | protected function _getDefaultStoreId() 42 | { 43 | return 0; 44 | } 45 | 46 | public function getPageCollection() 47 | { 48 | $storeId = $this->getRequest()->getParam('store', $this->_getDefaultStoreId()); 49 | $collection = $this->getData('page_collection'); 50 | if (is_null($collection)) { 51 | $collection = Mage::getModel('cms/page')->getCollection(); 52 | 53 | /* @var $collection Mage_Cms_Model_Mysql4_Page_Collection */ 54 | $collection->addStoreFilter($storeId); 55 | 56 | $this->setData('page_collection', $collection); 57 | } 58 | return $collection; 59 | } 60 | 61 | public function getAddRootButtonHtml() 62 | { 63 | return $this->getChildHtml('add_root_button'); 64 | } 65 | 66 | public function getAddSubButtonHtml() 67 | { 68 | return $this->getChildHtml('add_sub_button'); 69 | } 70 | 71 | public function getExpandButtonHtml() 72 | { 73 | return $this->getChildHtml('expand_button'); 74 | } 75 | 76 | public function getCollapseButtonHtml() 77 | { 78 | return $this->getChildHtml('collapse_button'); 79 | } 80 | 81 | public function getStoreSwitcherHtml() 82 | { 83 | return $this->getChildHtml('store_switcher'); 84 | } 85 | 86 | public function getLoadTreeUrl($expanded=null) 87 | { 88 | $params = array('_current'=>true, 'id'=>null,'store'=>null); 89 | if ( 90 | (is_null($expanded) && Mage::getSingleton('admin/session')->getIsTreeWasExpanded()) 91 | || $expanded == true) { 92 | $params['expand_all'] = true; 93 | } 94 | return $this->getUrl('*/*/pagesJson', $params); 95 | } 96 | 97 | public function getNodesUrl() 98 | { 99 | return $this->getUrl('*/cms_page/jsonTree'); 100 | } 101 | 102 | public function getSwitchTreeUrl() 103 | { 104 | return $this->getUrl("*/cms_page/tree", array('_current'=>true, 'store'=>null, '_query'=>false, 'id'=>null, 'parent'=>null)); 105 | } 106 | 107 | public function getIsWasExpanded() 108 | { 109 | return Mage::getSingleton('admin/session')->getIsTreeWasExpanded(); 110 | } 111 | 112 | public function getMoveUrl() 113 | { 114 | return $this->getUrl('*/cms_page/move', array('store'=>$this->getRequest()->getParam('store'))); 115 | } 116 | 117 | public function getTree($parenNodePage=null) 118 | { 119 | $rootArray = $this->_getNodeJson($this->getRoot($parenNodePage)); 120 | $tree = isset($rootArray['children']) ? $rootArray['children'] : array(); 121 | return $tree; 122 | } 123 | 124 | public function getTreeJson($parenNodePage=null) 125 | { 126 | $rootArray = $this->_getNodeJson($this->getRoot($parenNodePage)); 127 | $json = Mage::helper('core')->jsonEncode(isset($rootArray['children']) ? $rootArray['children'] : array()); 128 | return $json; 129 | } 130 | 131 | public function getBreadcrumbsJavascript($path, $javascriptVarName) 132 | { 133 | if (empty($path)) { 134 | return ''; 135 | } 136 | 137 | $pages = Mage::getResourceSingleton('cms/page_tree') 138 | ->setStoreId($this->getStore()->getId())->loadBreadcrumbsArray($path); 139 | if (empty($pages)) { 140 | return ''; 141 | } 142 | foreach ($pages as $key => $page) { 143 | $pages[$key] = $this->_getNodeJson($page); 144 | } 145 | return 146 | ''; 150 | } 151 | 152 | /** 153 | * Get JSON of a tree node or an associative array 154 | * 155 | * @param Varien_Data_Tree_Node|array $node 156 | * @param int $level 157 | * @return string 158 | */ 159 | protected function _getNodeJson($node, $level = 0) 160 | { 161 | // create a node from data array 162 | if (is_array($node)) { 163 | $node = new Varien_Data_Tree_Node($node, 'entity_id', new Varien_Data_Tree); 164 | } 165 | 166 | $item = array(); 167 | $item['text'] = $this->buildNodeName($node); 168 | 169 | //$rootForStores = Mage::getModel('core/store')->getCollection()->loadByPageIds(array($node->getEntityId())); 170 | $rootForStores = in_array($node->getEntityId(), $this->getRootIds()); 171 | 172 | $item['id'] = $node->getId(); 173 | $item['store'] = (int) $this->getStore()->getId(); 174 | $item['path'] = $node->getData('path'); 175 | 176 | $item['cls'] = 'folder ' . ($node->getIsActive() ? 'active-category' : 'no-active-category'); 177 | //$item['allowDrop'] = ($level<3) ? true : false; 178 | $allowMove = $this->_isPageMoveable($node); 179 | $item['allowDrop'] = $allowMove; 180 | // disallow drag if it's first level and page is root of a store 181 | $item['allowDrag'] = $allowMove && (($node->getLevel()==1 && $rootForStores) ? false : true); 182 | 183 | if ((int)$node->getChildrenCount()>0) { 184 | $item['children'] = array(); 185 | } 186 | 187 | $isParent = $this->_isParentSelectedPage($node); 188 | 189 | if ($node->hasChildren()) { 190 | $item['children'] = array(); 191 | if (!($this->getUseAjax() && $node->getLevel() > 1 && !$isParent)) { 192 | foreach ($node->getChildren() as $child) { 193 | $item['children'][] = $this->_getNodeJson($child, $level+1); 194 | } 195 | } 196 | } 197 | 198 | if ($isParent || $node->getLevel() < 2) { 199 | $item['expanded'] = true; 200 | } 201 | 202 | return $item; 203 | } 204 | 205 | /** 206 | * Get page name 207 | * 208 | * @param Varien_Object $node 209 | * @return string 210 | */ 211 | public function buildNodeName($node) 212 | { 213 | $result = $this->htmlEscape($node->getTitle()); 214 | if ($this->_withChildrenCount) { 215 | $result .= ' (' . $node->getChildrenCount() . ')'; 216 | } 217 | return $result; 218 | } 219 | 220 | protected function _isPageMoveable($node) 221 | { 222 | $options = new Varien_Object(array( 223 | 'is_moveable' => true, 224 | 'page' => $node 225 | )); 226 | 227 | Mage::dispatchEvent('adminhtml_page_tree_is_moveable', 228 | array('options'=>$options) 229 | ); 230 | 231 | return $options->getIsMoveable(); 232 | } 233 | 234 | protected function _isParentSelectedPage($node) 235 | { 236 | if ($node && $this->getPage()) { 237 | $pathIds = $this->getPage()->getPathIds(); 238 | if (in_array($node->getId(), $pathIds)) { 239 | return true; 240 | } 241 | } 242 | 243 | return false; 244 | } 245 | 246 | public function canAddRootPage() 247 | { 248 | return false; 249 | } 250 | 251 | public function canAddSubPage() 252 | { 253 | $options = new Varien_Object(array('is_allow'=>true)); 254 | Mage::dispatchEvent( 255 | 'adminhtml_page_tree_can_add_sub_page', 256 | array( 257 | 'page' => $this->getPage(), 258 | 'options' => $options, 259 | 'store' => $this->getStore()->getId() 260 | ) 261 | ); 262 | 263 | return $options->getIsAllow(); 264 | } 265 | 266 | public function getPage() 267 | { 268 | return Mage::registry('cms_page'); 269 | } 270 | 271 | public function getPageId() 272 | { 273 | if ($this->getPage()) { 274 | return $this->getPage()->getId(); 275 | } 276 | return Mage::getResourceModel('cms/page')->getStoreRootId($this->getStoreId()); 277 | } 278 | 279 | public function getPageName() 280 | { 281 | return $this->getPage()->getName(); 282 | } 283 | 284 | public function getPagePath() 285 | { 286 | if ($this->getPage()) { 287 | return $this->getPage()->getPath(); 288 | } 289 | return ''; 290 | } 291 | 292 | public function hasStoreRootPage() 293 | { 294 | $root = $this->getRoot(); 295 | if ($root && $root->getId()) { 296 | return true; 297 | } 298 | return false; 299 | } 300 | 301 | public function getStore() 302 | { 303 | $storeId = (int) $this->getRequest()->getParam('store'); 304 | return Mage::app()->getStore($storeId); 305 | } 306 | 307 | public function getStoreId() 308 | { 309 | return $this->getStore()->getId(); 310 | } 311 | 312 | public function getRoot($parentNodePage = null, $recursionLevel = 3) 313 | { 314 | if (!is_null($parentNodePage) && $parentNodePage->getId()) { 315 | return $this->getNode($parentNodePage, $recursionLevel); 316 | } 317 | $root = Mage::registry('root'); 318 | if (is_null($root)) { 319 | $storeId = (int) $this->getRequest()->getParam('store'); 320 | $rootId = Mage::getResourceModel('cms/page')->getStoreRootId($storeId); 321 | if (! $rootId) { 322 | $newRoot = JR_CleverCms_Model_Cms_Page::createDefaultStoreRootPage($storeId); 323 | $rootId = $newRoot->getId(); 324 | } 325 | 326 | $tree = Mage::getResourceSingleton('cms/page_tree') 327 | ->load(null, $recursionLevel); 328 | 329 | if ($this->getPage()) { 330 | $tree->loadEnsuredNodes($this->getPage(), $tree->getNodeById($rootId)); 331 | } 332 | 333 | $tree->addCollectionData($this->getPageCollection()); 334 | $root = $tree->getNodeById($rootId); 335 | 336 | if (!$root) { 337 | Mage::throwException('Could not retrieve root page of store ' . $storeId); 338 | } 339 | 340 | $root->setIsVisible(true); 341 | $root->setName($root->getTitle()); 342 | if ($this->_withChildrenCount) { 343 | $root->setName($root->getName() . ' (' . $root->getChildrenCount() . ')'); 344 | } 345 | 346 | Mage::register('root', $root); 347 | } 348 | 349 | return $root; 350 | } 351 | 352 | public function getRootByIds($ids) 353 | { 354 | $root = Mage::registry('root'); 355 | if (null === $root) { 356 | $storeId = (int) $this->getRequest()->getParam('store'); 357 | $pageTreeResource = Mage::getResourceSingleton('cms/page_tree'); 358 | $ids = $pageTreeResource->getExistingPageIdsBySpecifiedIds($ids); 359 | $tree = $pageTreeResource->loadByIds($ids); 360 | $rootId = Mage::getResourceModel('cms/page')->getStoreRootId($storeId); 361 | if (! $rootId) { 362 | $newRoot = $this->_createStoreRootPage($storeId); 363 | $rootId = $newRoot->getId(); 364 | } 365 | $root = $tree->getNodeById($rootId); 366 | 367 | if (!$root) { 368 | Mage::throwException('Could not retrieve root page of store ' . $storeId); 369 | } 370 | 371 | $tree->addCollectionData($this->getPageCollection()); 372 | Mage::register('root', $root); 373 | } 374 | return $root; 375 | } 376 | 377 | public function getNode($parentNodePage, $recursionLevel=2) 378 | { 379 | $tree = Mage::getResourceModel('cms/page_tree'); 380 | 381 | $nodeId = $parentNodePage->getId(); 382 | $parentId = $parentNodePage->getParentId(); 383 | 384 | $node = $tree->loadNode($nodeId); 385 | $node->loadChildren($recursionLevel); 386 | 387 | $tree->addCollectionData($this->getPageCollection()); 388 | 389 | return $node; 390 | } 391 | 392 | public function getSaveUrl(array $args = array()) 393 | { 394 | $params = array('_current'=>true); 395 | $params = array_merge($params, $args); 396 | return $this->getUrl('*/*/save', $params); 397 | } 398 | 399 | public function getEditUrl() 400 | { 401 | return $this->getUrl("*/cms_page/edit", array('_current'=>true, 'store'=>$this->getRequest()->getParam('store'), '_query'=>false, 'id'=>null, 'parent'=>null)); 402 | } 403 | 404 | public function getRootIds() 405 | { 406 | $ids = $this->getData('root_ids'); 407 | if (is_null($ids)) { 408 | $ids = array(); 409 | foreach (Mage::app()->getGroups() as $store) { 410 | $ids[] = $store->getRootPageId(); 411 | } 412 | $this->setData('root_ids', $ids); 413 | } 414 | return $ids; 415 | } 416 | } 417 | -------------------------------------------------------------------------------- /app/code/community/JR/CleverCms/Block/Adminhtml/Cms/Page/Widget/Chooser.php: -------------------------------------------------------------------------------- 1 | load(); 8 | $element->setData('after_element_html', $tree->toSelectHtml('parameters[page_id]', $element->getValue())); 9 | $element->setValue(); // Not needed because page is already selected in select box 10 | 11 | return $element; 12 | } 13 | } -------------------------------------------------------------------------------- /app/code/community/JR/CleverCms/Block/Adminhtml/Customer/Group/Switcher.php: -------------------------------------------------------------------------------- 1 | getRequest()->getParam('group'); 8 | } 9 | 10 | public function getCustomerGroups() 11 | { 12 | return Mage::getModel('customer/group')->getCollection(); 13 | } 14 | 15 | public function getSwitchUrl() 16 | { 17 | if ($url = $this->getData('switch_url')) { 18 | return $url; 19 | } 20 | return $this->getUrl('*/*/*', array('_current' => true, 'group' => null)); 21 | } 22 | } -------------------------------------------------------------------------------- /app/code/community/JR/CleverCms/Block/Catalog/Navigation.php: -------------------------------------------------------------------------------- 1 | addData(array( 10 | 'cache_lifetime' => false, 11 | 'cache_tags' => array( 12 | Mage_Catalog_Model_Category::CACHE_TAG, 13 | Mage_Core_Model_Store_Group::CACHE_TAG, 14 | self::CACHE_TAG, 15 | ), 16 | )); 17 | } 18 | 19 | public function getCacheKeyInfo() 20 | { 21 | $shortCacheId = array( 22 | 'CATALOG_NAVIGATION', 23 | Mage::app()->getStore()->getId(), 24 | Mage::getDesign()->getPackageName(), 25 | Mage::getDesign()->getTheme('template'), 26 | Mage::getSingleton('customer/session')->getCustomerGroupId(), 27 | 'template' => $this->getTemplate(), 28 | 'name' => $this->getNameInLayout(), 29 | $this->getCurrenCategoryKey(), 30 | 'page_id' => $this->getCurrentCmsPage() ? $this->getCurrentCmsPage()->getId() : false 31 | ); 32 | $cacheId = $shortCacheId; 33 | 34 | $shortCacheId = array_values($shortCacheId); 35 | $shortCacheId = implode('|', $shortCacheId); 36 | $shortCacheId = md5($shortCacheId); 37 | 38 | $cacheId['category_path'] = $this->getCurrenCategoryKey(); 39 | $cacheId['short_cache_id'] = $shortCacheId; 40 | 41 | return $cacheId; 42 | } 43 | 44 | /** 45 | * Render CMS to html 46 | * 47 | * @param Mage_Cms_Model_Page $page 48 | * @param int Nesting level number 49 | * @param boolean Whether or not this item is last, affects list item class 50 | * @param boolean Whether or not this item is first, affects list item class 51 | * @param boolean Whether or not this item is outermost, affects list item class 52 | * @param string Extra class of outermost list items 53 | * @param string If specified wraps children list in div with this class 54 | * @param boolean Whether or not to add on* attributes to list item 55 | * @return string 56 | */ 57 | protected function _renderCmsMenuItemHtml($page, $level = 0, $isLast = false, $isFirst = false, 58 | $isOutermost = false, $outermostItemClass = '', $childrenWrapClass = '', $noEventAttributes = false) 59 | { 60 | if (! $this->_isAllowed($page)) { 61 | return ''; 62 | } 63 | $html = array(); 64 | 65 | // get all children 66 | $children = $page->getChildren(); 67 | if (Mage::helper('cms/page')->isPermissionsEnabled($this->getStore())) { 68 | $children->addPermissionsFilter($this->getCustomerGroupId()); 69 | } 70 | $childrenCount = $children->count(); 71 | $hasChildren = ($children && $childrenCount); 72 | 73 | // select active children 74 | $activeChildren = array(); 75 | foreach ($children as $child) { 76 | if ($child->getIsActive() && $child->getIncludeInMenu()) { 77 | $activeChildren[] = $child; 78 | } 79 | } 80 | $activeChildrenCount = count($activeChildren); 81 | $hasActiveChildren = ($activeChildrenCount > 0); 82 | 83 | // prepare list item html classes 84 | $classes = array(); 85 | $classes[] = 'level'.$level; 86 | // note: not dealing with the 'nav-' class at the moment 87 | if ($this->isCmsPageActive($page)) { 88 | $classes[] = 'active'; 89 | } 90 | $linkClass = ''; 91 | if ($isOutermost && $outermostItemClass) { 92 | $classes[] = $outermostItemClass; 93 | $linkClass = ' class="'.$outermostItemClass.'"'; 94 | } 95 | if ($isFirst) { 96 | $classes[] = 'first'; 97 | } 98 | if ($isLast) { 99 | $classes[] = 'last'; 100 | } 101 | if ($hasActiveChildren) { 102 | $classes[] = 'parent'; 103 | } 104 | 105 | // prepare list item attributes 106 | $attributes = array(); 107 | if (count($classes) > 0) { 108 | $attributes['class'] = implode(' ', $classes); 109 | } 110 | if ($hasActiveChildren && !$noEventAttributes) { 111 | $attributes['onmouseover'] = 'toggleMenu(this,1)'; 112 | $attributes['onmouseout'] = 'toggleMenu(this,0)'; 113 | } 114 | 115 | // assemble list item with attributes 116 | $htmlLi = ' $attrValue) { 118 | $htmlLi .= ' ' . $attrName . '="' . str_replace('"', '\"', $attrValue) . '"'; 119 | } 120 | $htmlLi .= '>'; 121 | $html[] = $htmlLi; 122 | $html[] .= ''; 123 | $html[] .= ''. $this->escapeHtml($page->getTitle()) .''; 124 | $html[] .= ''; 125 | 126 | // render children 127 | $htmlChildren = ''; 128 | $j = 0; 129 | foreach ($activeChildren as $child) { 130 | $htmlChildren .= $this->_renderCmsMenuItemHtml( 131 | $child, 132 | ($level + 1), 133 | ($j == $activeChildrenCount - 1), // is last 134 | ($j == 0), // is first 135 | false, // is outermost 136 | $outermostItemClass, 137 | $childrenWrapClass, 138 | $noEventAttributes 139 | ); 140 | $j++; 141 | } 142 | 143 | if (!empty($htmlChildren)) { 144 | if ($childrenWrapClass) { 145 | $html[] = '
'; 146 | } 147 | $html[] = ''; 150 | if ($childrenWrapClass) { 151 | $html[] = '
'; 152 | } 153 | } 154 | 155 | $html[] = ''; 156 | 157 | $html = implode("\n", $html); 158 | return $html; 159 | } 160 | 161 | /** 162 | * Render CMS menu in HTML 163 | * 164 | * @param int Level number for list item class to start from 165 | * @param bool Whether or not this group of items is last, affects list item class 166 | * @param bool Whether or not this group of items is first, affects list item class 167 | * @param string Extra class of outermost list items 168 | * @param string If specified wraps children list in div with this class 169 | * @return string 170 | */ 171 | public function renderCmsMenuHtml($level = 0, $isLast = true, $isFirst = true, $outermostItemClass = '', $childrenWrapClass = '') 172 | { 173 | $activePages = array(); 174 | foreach ($this->getStoreCmsPages() as $child) { 175 | if ($child->getIsActive() && $child->getIncludeInMenu()) { 176 | $activePages[] = $child; 177 | } 178 | } 179 | 180 | $activePagesCount = count($activePages); 181 | $hasActivePagesCount = ($activePagesCount > 0); 182 | 183 | if (!$hasActivePagesCount) { 184 | return ''; 185 | } 186 | 187 | $html = ''; 188 | $j = 0; 189 | foreach ($activePages as $page) { 190 | $html .= $this->_renderCmsMenuItemHtml( 191 | $page, 192 | $level, 193 | ($isLast && $j == $activePagesCount - 1), // is last 194 | ($isFirst && $j == 0), // is first 195 | true, // is outermost 196 | $outermostItemClass, 197 | $childrenWrapClass, 198 | true 199 | ); 200 | $j++; 201 | } 202 | 203 | return $html; 204 | } 205 | 206 | 207 | /** 208 | * Render categories menu in HTML. Unfortunately in order to 'overload' the 209 | * renderCategoriesMenuHtml() and add the two new parameters $isLast and 210 | * $isFirst, I had to copy the original method here and rename. 211 | * 212 | * @param int Level number for list item class to start from 213 | * @param bool Whether or not this group of items is last, affects list item class 214 | * @param bool Whether or not this group of items is first, affects list item class 215 | * @param string Extra class of outermost list items 216 | * @param string If specified wraps children list in div with this class 217 | * @return string 218 | */ 219 | public function renderCategoriesMenuHtmlClever($level = 0, $isLast = true, $isFirst = true, $outermostItemClass = '', $childrenWrapClass = '') 220 | { 221 | $activeCategories = array(); 222 | foreach ($this->getStoreCategories() as $child) { 223 | if ($child->getIsActive()) { 224 | $activeCategories[] = $child; 225 | } 226 | } 227 | $activeCategoriesCount = count($activeCategories); 228 | $hasActiveCategoriesCount = ($activeCategoriesCount > 0); 229 | 230 | if (!$hasActiveCategoriesCount) { 231 | return ''; 232 | } 233 | 234 | $html = ''; 235 | $j = 0; 236 | foreach ($activeCategories as $category) { 237 | $html .= $this->_renderCategoryMenuItemHtml( 238 | $category, 239 | $level, 240 | ($isLast && $j == $activeCategoriesCount - 1), 241 | ($isFirst && $j == 0), 242 | true, 243 | $outermostItemClass, 244 | $childrenWrapClass, 245 | true 246 | ); 247 | $j++; 248 | } 249 | 250 | return $html; 251 | } 252 | 253 | /** 254 | * Get top level CMS pages of current store 255 | * 256 | * @return array of Mage_Cms_Model_Page 257 | */ 258 | public function getStoreCmsPages() 259 | { 260 | $collection = $this->getCmsRootPage(0)->getChildren(); 261 | foreach ($this->getCmsRootPage()->getChildren() as $page) { 262 | $collection->addItem($page); 263 | } 264 | 265 | return $collection; 266 | } 267 | 268 | /** 269 | * Return the root CMS page for this store 270 | * 271 | * @return Mage_Cms_Model_Page 272 | */ 273 | public function getCmsRootPage($storeId = null) 274 | { 275 | if (null === $storeId) { 276 | $storeId = $this->getStore()->getId(); 277 | } 278 | 279 | return Mage::getModel('cms/page')->loadRootByStoreId($storeId); 280 | } 281 | 282 | /** 283 | * Returns true if $page is the current page, or is on the path (is a parent) 284 | * of the current page. The root (index) page must be handled specially and 285 | * this function will *not* return true when it is the active page. 286 | * 287 | * @param Mage_Cms_Model_Page 288 | * @return bool 289 | */ 290 | public function isCmsPageActive($page) 291 | { 292 | $current = $this->getCurrentCmsPage(); 293 | 294 | if ($current) { 295 | return in_array($page->getId(), $current->getPathIds()); 296 | } 297 | return false; 298 | } 299 | 300 | /** 301 | * Get the current CMS page. The root (index) page must be handled specially and 302 | * this function will *not* return it when it is the active page. 303 | * 304 | * @return Mage_Cms_Model_Page the current CMS page, or false if the current 305 | * page is not CMS 306 | */ 307 | public function getCurrentCmsPage() 308 | { 309 | $page = Mage::getSingleton('cms/page'); 310 | 311 | if (count($page->getData()) > 0 && !$page->isRoot()) { 312 | return $page; 313 | } 314 | 315 | return false; 316 | } 317 | 318 | /** 319 | * Returns true if there is at least one active top level CMS page to display 320 | * in the navigation menu. 321 | * 322 | * @return bool 323 | */ 324 | public function hasCmsNavigationMenuPages() 325 | { 326 | foreach ($this->getStoreCmsPages() as $child) { 327 | if ($child->getIsActive() && $child->getIncludeInMenu()) { 328 | return true; 329 | } 330 | } 331 | 332 | return false; 333 | } 334 | 335 | /** 336 | * Returns true if there is at least one active top level Category page to 337 | * display in the navigation menu. 338 | */ 339 | public function hasCategoriesNavigationMenuPages() 340 | { 341 | foreach ($this->getStoreCategories() as $child) { 342 | if ($child->getIsActive()) { 343 | return true; 344 | } 345 | } 346 | 347 | return false; 348 | } 349 | 350 | public function getStore($id = null) 351 | { 352 | return Mage::app()->getStore($id); 353 | } 354 | 355 | public function getCustomerGroupId() 356 | { 357 | return Mage::getSingleton('customer/session')->getCustomerGroupId(); 358 | } 359 | 360 | protected function _isAllowed($page) 361 | { 362 | return Mage::helper('cms/page')->isAllowed($this->getStore()->getId(), $this->getCustomerGroupId(), $page->getId()); 363 | } 364 | } -------------------------------------------------------------------------------- /app/code/community/JR/CleverCms/Block/Cms/Page.php: -------------------------------------------------------------------------------- 1 | getPage(); 8 | /* @var $page JR_CleverCms_Model_Cms_Page */ 9 | 10 | // show breadcrumbs 11 | if (!$page->isRoot() 12 | && Mage::getStoreConfig('web/default/show_cms_breadcrumbs') 13 | && ($breadcrumbs = $this->getLayout()->getBlock('breadcrumbs')) 14 | && ($page->getIdentifier() !== Mage::getStoreConfig('web/default/cms_home_page')) 15 | && ($page->getIdentifier() !== Mage::getStoreConfig('web/default/cms_no_route'))) 16 | { 17 | $breadcrumbs->addCrumb('home', array('label' => Mage::helper('cms')->__('Home'), 'title' => Mage::helper('cms')->__('Go to Home Page'), 'link' => Mage::getBaseUrl())); 18 | foreach ($page->getParentIds() as $k => $parentId) { 19 | $parent = Mage::getModel('cms/page')->load($parentId); 20 | if ($parent->getId() && $parent->getParentId()) { 21 | $breadcrumbs->addCrumb('cms_page_' . $k, array('label' => $parent->getTitle(), 'title' => $parent->getTitle(), 'link' => rtrim(Mage::getBaseUrl() . $parent->getIdentifier(), '/') . '/')); 22 | } 23 | } 24 | $breadcrumbs->addCrumb('cms_page', array('label' => $page->getTitle(), 'title' => $page->getTitle())); 25 | } 26 | 27 | $root = $this->getLayout()->getBlock('root'); 28 | if ($root) { 29 | $root->addBodyClass('cms-' . $page->getIdentifier()); 30 | } 31 | 32 | $head = $this->getLayout()->getBlock('head'); 33 | if ($head) { 34 | $head->setTitle($page->getTitle()); 35 | $head->setKeywords($page->getMetaKeywords()); 36 | $head->setDescription($page->getMetaDescription()); 37 | } 38 | 39 | return $this; 40 | } 41 | } -------------------------------------------------------------------------------- /app/code/community/JR/CleverCms/Helper/Cms/Page.php: -------------------------------------------------------------------------------- 1 | getStore()->getId(); 8 | $customerGroupId = Mage::getSingleton('customer/session')->getCustomerGroupId(); 9 | if (! $this->isAllowed($storeId, $customerGroupId, $pageId)) { 10 | return false; 11 | } 12 | 13 | return parent::renderPage($action, $pageId); 14 | } 15 | 16 | public function isAllowed($storeId, $customerGroupId, $pageId) 17 | { 18 | $page = Mage::getModel('cms/page')->load($pageId); 19 | if ($page->getStoreId() == 0 && !in_array($storeId, $page->getStores())) { 20 | return false; 21 | } 22 | 23 | if (! $this->isPermissionsEnabled($storeId)) { 24 | return true; 25 | } 26 | 27 | return Mage::getResourceModel('cms/page_permission')->exists($storeId, $customerGroupId, $pageId); 28 | } 29 | 30 | public function isPermissionsEnabled($store = null) 31 | { 32 | return Mage::getStoreConfigFlag('cms/clever/permissions_enabled', Mage::app()->getStore($store)); 33 | } 34 | 35 | public function isCreatePermanentRedirects($store = null) 36 | { 37 | return Mage::getStoreConfigFlag('cms/clever/save_rewrites_history', Mage::app()->getStore($store)); 38 | } 39 | } -------------------------------------------------------------------------------- /app/code/community/JR/CleverCms/Model/Adminhtml/Cms/Page/Observer.php: -------------------------------------------------------------------------------- 1 | getEvent()->getForm(); 9 | $includeInMenuDisabled = $urlKeyDisabled = false; 10 | 11 | // add our 'url_key' field so that users can set a URL identifier independent of the CMS page title 12 | if ($page->getPageId()) { 13 | $store = Mage::app()->getStore($page->getStoreId()); 14 | $storeCode = null; 15 | if (Mage::getStoreConfigFlag(Mage_Core_Model_Store::XML_PATH_STORE_IN_URL)) { 16 | $storeCode = $store->getCode() . '/'; 17 | } 18 | // disable the 'url key' and 'include in menu' configuration options for the root CMS page 19 | if ($page->isRoot()) { 20 | $includeInMenuDisabled = $urlKeyDisabled = true; 21 | } 22 | } 23 | 24 | $form->getElement('base_fieldset')->addField('url_key', 'text', array( 25 | 'name' => 'url_key', 26 | 'label' => Mage::helper('cms')->__('URL Key'), 27 | 'title' => Mage::helper('cms')->__('URL Key'), 28 | 'note' => Mage::helper('cms')->__('Leave blank for automatic generation.
URL is relative to parent URL. Current URL: %s', $page->getUrl()), 29 | 'value' => $page->getIdentifier(), 30 | 'disabled' => $urlKeyDisabled 31 | )); 32 | 33 | if (!Mage::app()->isSingleStoreMode() && $page->getStoreId() == 0) { 34 | $form->getElement('base_fieldset') 35 | ->removeField('stores'); 36 | $form->getElement('base_fieldset')->addField('stores', 'multiselect', array( 37 | 'name' => 'stores[]', 38 | 'label' => Mage::helper('cms')->__('Store View'), 39 | 'title' => Mage::helper('cms')->__('Store View'), 40 | 'required' => false, 41 | 'values' => Mage::getSingleton('adminhtml/system_store')->getStoreValuesForForm(), 42 | )); 43 | } 44 | 45 | $form->getElement('base_fieldset')->addField('include_in_menu', 'select', array( 46 | 'name' => 'include_in_menu', 47 | 'label' => Mage::helper('cms')->__('Include in Navigation Menu'), 48 | 'title' => Mage::helper('cms')->__('Include in Navigation Menu'), 49 | 'note' => Mage::helper('cms')->__('Set clever theme and default package to have an example of navigation'), 50 | 'values' => array('1' => Mage::helper('adminhtml')->__('Yes'), '0' => Mage::helper('adminhtml')->__('No')), 51 | 'disabled' => $includeInMenuDisabled, 52 | )); 53 | 54 | $form->getElement('base_fieldset') 55 | ->removeField('identifier') 56 | ->removeField('store_id'); 57 | $form->addField('store_id', 'hidden', array('name' => 'store')); 58 | $form->addField('parent_id', 'hidden', array('name' => 'parent')); 59 | $form->addField('identifier', 'hidden', array('name' => 'identifier')); 60 | 61 | if (null === $page->getIncludeInMenu()) { 62 | $page->setIncludeInMenu(true); 63 | } 64 | } 65 | 66 | public function prepareSave($observer) 67 | { 68 | $request = $observer->getEvent()->getRequest(); 69 | $page = $observer->getEvent()->getPage(); 70 | if ($request->has('store')) { 71 | $page->setStoreId($request->getParam('store')); 72 | } 73 | if ($request->has('parent')) { 74 | $page->setParentId($request->getParam('parent')); 75 | } 76 | } 77 | } -------------------------------------------------------------------------------- /app/code/community/JR/CleverCms/Model/Cms/Page.php: -------------------------------------------------------------------------------- 1 | setStores(array($this->getStoreId())) 13 | ->load($parentId); 14 | 15 | if (!$parent->getId()) { 16 | Mage::throwException( 17 | Mage::helper('cms')->__('Page move operation is not possible: the new parent page was not found.') 18 | ); 19 | } 20 | 21 | $eventParams = array( 22 | $this->_eventObject => $this, 23 | 'parent' => $parent, 24 | 'page_id' => $this->getId(), 25 | 'prev_parent_id' => $this->getParentId(), 26 | 'parent_id' => $parentId 27 | ); 28 | $moveComplete = false; 29 | 30 | $this->_getResource()->beginTransaction(); 31 | try { 32 | Mage::dispatchEvent('cms_page_tree_move_before', $eventParams); 33 | Mage::dispatchEvent($this->_eventPrefix.'_move_before', $eventParams); 34 | 35 | $this->getResource()->changeParent($this, $parent, $afterPageId); 36 | 37 | Mage::dispatchEvent($this->_eventPrefix.'_move_after', $eventParams); 38 | Mage::dispatchEvent('cms_page_tree_move_after', $eventParams); 39 | $this->_getResource()->commit(); 40 | 41 | $moveComplete = true; 42 | } catch (Exception $e) { 43 | $this->_getResource()->rollBack(); 44 | throw $e; 45 | } 46 | if ($moveComplete) { 47 | Mage::dispatchEvent('page_move', $eventParams); 48 | } 49 | 50 | return $this; 51 | } 52 | 53 | public function getParentIds() 54 | { 55 | return array_diff($this->getPathIds(), array($this->getId())); 56 | } 57 | 58 | public function getPathIds() 59 | { 60 | $ids = $this->getData('path_ids'); 61 | if (is_null($ids)) { 62 | $ids = explode('/', $this->getPath()); 63 | $this->setData('path_ids', $ids); 64 | } 65 | 66 | return $ids; 67 | } 68 | 69 | public function getParentPage() 70 | { 71 | if (!$this->hasData('parent_page')) { 72 | $this->setData('parent_page', Mage::getModel('cms/page')->load($this->getParentId())); 73 | } 74 | 75 | return $this->_getData('parent_page'); 76 | } 77 | 78 | public function formatUrlKey($str) 79 | { 80 | $str = Mage::helper('core')->removeAccents($str); 81 | $urlKey = preg_replace('#[^0-9a-z]+#i', '-', $str); 82 | $urlKey = strtolower($urlKey); 83 | $urlKey = trim($urlKey, '-'); 84 | 85 | return $urlKey; 86 | } 87 | 88 | public function loadRootByStoreId($storeId) 89 | { 90 | $rootId = $this->_getResource()->getStoreRootId($storeId); 91 | if ($rootId) { 92 | $this->load($rootId); 93 | } 94 | 95 | return $this; 96 | } 97 | 98 | public function getChildren() 99 | { 100 | return $this->getCollection()->addChildrenFilter($this); 101 | } 102 | 103 | public function getUrl() 104 | { 105 | return Mage::getBaseUrl() . $this->getIdentifier(); 106 | } 107 | 108 | public function isRoot() 109 | { 110 | return 0 === (int) $this->getParentId(); 111 | } 112 | 113 | public static function createDefaultStoreRootPage($storeId, $data = array()) 114 | { 115 | $newRoot = Mage::getModel('cms/page')->setData(array( 116 | 'title' => Mage::helper('cms')->__('Home'), 117 | 'root_template' => 'two_columns_right', 118 | 'store_id' => $storeId, 119 | 'parent_id' => 0, 120 | 'level' => 1, 121 | )) 122 | ->addData($data) // will override default data 123 | ->setCreateDefaultPermission(true) 124 | ->save(); 125 | 126 | return $newRoot; 127 | } 128 | 129 | protected function _beforeDelete() 130 | { 131 | parent::_beforeDelete(); 132 | $this->getResource()->decreaseChildrenCount($this, $this->getParentIds()); 133 | 134 | return $this; 135 | } 136 | 137 | protected function _afterDelete() 138 | { 139 | parent::_afterDelete(); 140 | $this->getResource()->deleteChildren($this); 141 | 142 | return $this; 143 | } 144 | 145 | protected function _beforeSave() 146 | { 147 | if ($this->isRoot()) { 148 | $this->setIdentifier(''); 149 | } else { 150 | if ($this->getPageId()) { 151 | // Edit existant page 152 | $identifiers = explode('/', $this->getIdentifier()); 153 | array_pop($identifiers); 154 | } else { 155 | // Add new page 156 | $parent = $this->getParentPage(); 157 | $identifiers = explode('/', $parent->getIdentifier()); 158 | $this->getResource()->increaseChildrenCount($this, $parent->getPathIds()); 159 | $this->setCreateDefaultPermission(true); 160 | } 161 | $identifier = $this->getUrlKey() ? $this->getUrlKey() : $this->getTitle(); 162 | array_push($identifiers, $this->formatUrlKey($identifier)); 163 | $this->setIdentifier(trim(implode('/', $identifiers), '/')); 164 | } 165 | 166 | parent::_beforeSave(); 167 | 168 | $oldPage = Mage::getModel('cms/page')->load($this->getPageId()); // old page data 169 | 170 | if (!$this->isRoot() && Mage::helper('cms/page')->isCreatePermanentRedirects($this->getStoreId())) { 171 | // 301 Redirects 172 | $this->getResource()->updatePermanentRedirects($oldPage, $this); 173 | } 174 | 175 | $this->getResource()->updateChildrenIdentifiers($oldPage, $this->getIdentifier()); 176 | 177 | return $this; 178 | } 179 | 180 | protected function _afterSave() 181 | { 182 | if (! $this->getPath() && $this->getPageId()) { 183 | if (! $this->getPosition()) { 184 | $this->setPosition($this->getPageId()); 185 | } 186 | $path = ''; 187 | if ($this->getParentId()) { 188 | $parent = $this->getParentPage(); 189 | $path = $parent->getPath(); 190 | } 191 | $path .= '/' . $this->getPageId(); 192 | $path = trim($path, '/'); 193 | $this->setPath($path) 194 | ->setLevel(count(explode('/', $path))) 195 | ->save(); 196 | } 197 | 198 | if ($this->getCreateDefaultPermission()) { 199 | $storeId = $this->getStoreId(); 200 | $customerGroupId = Mage_Customer_Model_Group::NOT_LOGGED_IN_ID; 201 | $resourceModel = Mage::getResourceModel('cms/page_permission'); 202 | if ($this->isRoot() || $resourceModel->exists($storeId, $customerGroupId, $this->getParentId())) { 203 | Mage::getModel('cms/page_permission')->addData(array( 204 | 'store_id' => $storeId, 205 | 'customer_group_id' => $customerGroupId, 206 | 'page_id' => $this->getPageId(), 207 | )) 208 | ->save(); 209 | } 210 | $this->setCreateDefaultPermission(false); 211 | } 212 | 213 | return $this; 214 | } 215 | 216 | protected function _afterLoad() 217 | { 218 | parent::_afterLoad(); 219 | $identifiers = explode('/', $this->getIdentifier()); 220 | $this->setUrlKey(array_pop($identifiers)); 221 | 222 | return $this; 223 | } 224 | } 225 | -------------------------------------------------------------------------------- /app/code/community/JR/CleverCms/Model/Cms/Page/Permission.php: -------------------------------------------------------------------------------- 1 | _init('cms/page_permission'); 8 | } 9 | } -------------------------------------------------------------------------------- /app/code/community/JR/CleverCms/Model/Resource/Cms/Page.php: -------------------------------------------------------------------------------- 1 | getTablePrefix(); 11 | Mage::getSingleton('core/resource')->setMappedTableName('cms_page', $tablePrefix . 'cms_page_tree'); 12 | if ($this->_tableTreeStoreExists()) { 13 | Mage::getSingleton('core/resource')->setMappedTableName('cms_page_store', $tablePrefix . 'cms_page_tree_store'); 14 | } 15 | } 16 | 17 | public function changeParent(Mage_Cms_Model_Page $page, Mage_Cms_Model_Page $newParent, $afterPageId = null) 18 | { 19 | $childrenCount = $this->getChildrenCount($page->getId()) + 1; 20 | $table = $this->getTable('cms/page'); 21 | $adapter = $this->_getWriteAdapter(); 22 | $pageId = $page->getId(); 23 | /** 24 | * Decrease children count for all old page parent pages 25 | */ 26 | $this->decreaseChildrenCount($page, $page->getParentIds()); 27 | /** 28 | * Increase children count for new page parents 29 | */ 30 | $this->increaseChildrenCount($page, $newParent->getPathIds()); 31 | 32 | $position = $this->_processPositions($page, $newParent, $afterPageId); 33 | 34 | $newPath = $newParent->getPath().'/'.$page->getId(); 35 | $identifiers = explode('/', $page->getIdentifier()); 36 | $newIdentifier = trim($newParent->getIdentifier().'/'.array_pop($identifiers), '/'); 37 | $newLevel= $newParent->getLevel()+1; 38 | $levelDisposition = $newLevel - $page->getLevel(); 39 | 40 | if (Mage::helper('cms/page')->isCreatePermanentRedirects($page->getStoreId())) { 41 | $newPage = clone $page; 42 | $newPage->setIdentifier($newIdentifier); 43 | $this->updatePermanentRedirects($page, $newPage); 44 | } 45 | 46 | /** 47 | * Update children nodes identifiers 48 | */ 49 | $this->updateChildrenIdentifiers($page, $newIdentifier); 50 | 51 | /** 52 | * Update children nodes path 53 | */ 54 | $sql = "UPDATE {$table} SET 55 | `path` = REPLACE(`path`, '{$page->getPath()}/', '{$newPath}/'), 56 | `level` = `level` + {$levelDisposition} 57 | WHERE ". $adapter->quoteInto('path LIKE ?', $page->getPath().'/%'); 58 | $adapter->query($sql); 59 | 60 | /** 61 | * Update moved page data 62 | */ 63 | $data = array( 64 | 'path' => $newPath, 65 | 'level' => $newLevel, 66 | 'identifier' => $newIdentifier, 67 | 'position' => $position, 68 | 'parent_id' => $newParent->getId() 69 | ); 70 | $adapter->update($table, $data, $adapter->quoteInto('page_id=?', $page->getId())); 71 | 72 | // Update page object to new data 73 | $page->addData($data); 74 | 75 | return $this; 76 | } 77 | 78 | public function decreaseChildrenCount(Mage_Cms_Model_Page $page, $pageIds) 79 | { 80 | $this->_updateChildrenCount($page, $pageIds, '-'); 81 | } 82 | 83 | public function increaseChildrenCount(Mage_Cms_Model_Page $page, $pageIds) 84 | { 85 | $this->_updateChildrenCount($page, $pageIds, '+'); 86 | } 87 | 88 | public function updateChildrenIdentifiers(Mage_Cms_Model_Page $page, $newIdentifier) 89 | { 90 | $table = $this->getTable('cms/page'); 91 | $adapter = $this->_getWriteAdapter(); 92 | $oldIdentifier = str_replace('/', '\/', $page->getIdentifier()); 93 | $children = Mage::getModel('cms/page')->getCollection() 94 | ->addFieldToFilter('path', array('like' => $page->getPath().'/%')); 95 | foreach ($children as $child) { 96 | $identifier = preg_replace("/^{$oldIdentifier}\/(.*)/i", "{$newIdentifier}/\$1", $child->getIdentifier()); 97 | $sql = "UPDATE {$table} SET " 98 | . $adapter->quoteInto('identifier = ? ', $identifier) 99 | . $adapter->quoteInto('WHERE page_id = ?', $child->getPageId()); 100 | $adapter->query($sql); 101 | } 102 | 103 | return $this; 104 | } 105 | 106 | public function getChildrenCount($pageId) 107 | { 108 | $select = $this->_getReadAdapter()->select() 109 | ->from($this->getTable('cms/page'), 'children_count') 110 | ->where('page_id=?', $pageId); 111 | 112 | $child = $this->_getReadAdapter()->fetchOne($select); 113 | 114 | return $child; 115 | } 116 | 117 | public function getStoreRootId($storeId) 118 | { 119 | $select = $this->_getReadAdapter()->select() 120 | ->from($this->getTable('cms/page'), 'page_id') 121 | ->where('parent_id = 0') 122 | ->where('store_id = ?', $storeId); 123 | 124 | return $this->_getReadAdapter()->fetchOne($select); 125 | } 126 | 127 | public function checkIdentifier($identifier, $storeId) 128 | { 129 | $select = $this->_getReadAdapter()->select()->from(array('main_table'=>$this->getMainTable()), 'page_id') 130 | ->where('main_table.identifier=?', $identifier) 131 | ->where('main_table.is_active=1 AND main_table.store_id IN (0, ?)', $storeId) 132 | ->order('main_table.store_id DESC'); 133 | 134 | return $this->_getReadAdapter()->fetchOne($select); 135 | } 136 | 137 | public function getCmsPageTitleByIdentifier($identifier) 138 | { 139 | $select = $this->_getReadAdapter()->select(); 140 | /* @var $select Zend_Db_Select */ 141 | $select->from(array('main_table' => $this->getMainTable()), 'title') 142 | ->where('main_table.identifier = ?', $identifier) 143 | ->where('main_table.store_id = ?', $this->getStore()->getId()) 144 | ->order('main_table.store_id DESC'); 145 | return $this->_getReadAdapter()->fetchOne($select); 146 | } 147 | 148 | public function getIsUniquePageToStores(Mage_Core_Model_Abstract $object) 149 | { 150 | $select = $this->_getWriteAdapter()->select() 151 | ->from($this->getMainTable()) 152 | ->where($this->getMainTable().'.identifier = ?', $object->getData('identifier')) 153 | ->where($this->getMainTable().'.store_id = ?', $object->getStoreId()); 154 | if ($object->getId()) { 155 | $select->where($this->getMainTable().'.page_id <> ?',$object->getId()); 156 | } 157 | 158 | if ($this->_getWriteAdapter()->fetchRow($select)) { 159 | return false; 160 | } 161 | 162 | return true; 163 | } 164 | 165 | public function updatePermanentRedirects(Mage_Cms_Model_Page $oldPage, Mage_Cms_Model_Page $newPage) 166 | { 167 | $this->deletePermanentRedirects($newPage); 168 | 169 | $children = $newPage->getCollection() 170 | ->addAllChildrenFilter($oldPage); 171 | $children->addItem($oldPage); // 301 redirect for me too 172 | foreach ($children as $child) { 173 | $newIdentifier = str_replace($oldPage->getIdentifier(), $newPage->getIdentifier(), $child->getIdentifier()); 174 | if ($newIdentifier != $child->getIdentifier()) { 175 | $data = array( 176 | 'request_path' => $child->getIdentifier(), 177 | 'target_path' => $newIdentifier, 178 | 'id_path' => microtime(), 179 | 'store_id' => $newPage->getStoreId(), 180 | 'is_system' => 0, 181 | 'options' => 'RP', 182 | ); 183 | $url = Mage::getModel('core/url_rewrite') 184 | ->setStoreId($newPage->getStoreId()) 185 | ->loadByRequestPath($child->getIdentifier()) 186 | ->addData($data) 187 | ->save(); 188 | } 189 | } 190 | } 191 | 192 | public function deletePermanentRedirects(Mage_Cms_Model_Page $page) 193 | { 194 | $urls = Mage::getModel('core/url_rewrite')->getCollection() 195 | ->addFieldToFilter('store_id', $page->getStoreId()) 196 | ->addFieldToFilter('request_path', array('like' => $page->getIdentifier() . '%')); 197 | foreach ($urls as $url) { 198 | $url->delete(); // Removing old url to avoid infinite loop 199 | } 200 | } 201 | 202 | public function deleteChildren(Mage_Cms_Model_Page $page) 203 | { 204 | $table = $this->getTable('cms/page'); 205 | $adapter = $this->_getWriteAdapter(); 206 | $path = $page->getPath(); 207 | $sql = "DELETE FROM {$table} WHERE path LIKE '{$path}%'"; 208 | $adapter->query($sql); 209 | } 210 | 211 | protected function _updateChildrenCount(Mage_Cms_Model_Page $page, $pageIds, $operator) 212 | { 213 | $table = $this->getTable('cms/page'); 214 | $childrenCount = $this->getChildrenCount($page->getId()) + 1; 215 | $adapter = $this->_getWriteAdapter(); 216 | $sql = "UPDATE {$table} SET children_count=children_count {$operator} {$childrenCount} WHERE page_id IN(?)"; 217 | $adapter->query($adapter->quoteInto($sql, $pageIds)); 218 | } 219 | 220 | protected function isValidPageIdentifier(Mage_Core_Model_Abstract $object) 221 | { 222 | // Homepage case 223 | if (!$object->getParentId() && $object->getData('identifier') === '') { 224 | return true; 225 | } 226 | return preg_match('/^[a-z0-9][a-z0-9_\/-]+(\.[a-z0-9_-]+)?$/', $object->getData('identifier')); 227 | } 228 | 229 | protected function _afterSave(Mage_Core_Model_Abstract $object) 230 | { 231 | Mage::app()->cleanCache(array(JR_CleverCms_Block_Catalog_Navigation::CACHE_TAG)); 232 | 233 | if ($object->getStoreId() === '0' && $this->_tableTreeStoreExists()) { 234 | return parent::_afterSave($object); 235 | } 236 | 237 | return $this; 238 | } 239 | 240 | protected function _afterLoad(Mage_Core_Model_Abstract $object) 241 | { 242 | if ($object->getId() && $this->_tableTreeStoreExists()) { 243 | $stores = $this->lookupStoreIds($object->getId()); 244 | $object->setData('stores', $stores); 245 | } 246 | 247 | return $this; 248 | } 249 | 250 | protected function _getLoadSelect($field, $value, $object) 251 | { 252 | $select = $this->_getReadAdapter()->select() 253 | ->from($this->getMainTable()) 254 | ->where($this->getMainTable().'.'.$field.'=?', $value); 255 | return $select; 256 | } 257 | 258 | protected function _processPositions($page, $newParent, $afterPageId) 259 | { 260 | $table = $this->getTable('cms/page'); 261 | $adapter = $this->_getWriteAdapter(); 262 | 263 | $sql = "UPDATE {$table} SET `position`=`position`-1 WHERE " 264 | . $adapter->quoteInto('parent_id=? AND ', $page->getParentId()) 265 | . $adapter->quoteInto('position>?', $page->getPosition()); 266 | $adapter->query($sql); 267 | 268 | /** 269 | * Prepare position value 270 | */ 271 | if ($afterPageId) { 272 | $sql = "SELECT `position` FROM {$table} WHERE page_id=?"; 273 | $position = $adapter->fetchOne($adapter->quoteInto($sql, $afterPageId)); 274 | 275 | $sql = "UPDATE {$table} SET `position`=`position`+1 WHERE " 276 | . $adapter->quoteInto('parent_id=? AND ', $newParent->getId()) 277 | . $adapter->quoteInto('position>?', $position); 278 | $adapter->query($sql); 279 | } elseif ($afterPageId !== null) { 280 | $position = 0; 281 | $sql = "UPDATE {$table} SET `position`=`position`+1 WHERE " 282 | . $adapter->quoteInto('parent_id=? AND ', $newParent->getId()) 283 | . $adapter->quoteInto('position>?', $position); 284 | $adapter->query($sql); 285 | } else { 286 | $sql = "SELECT MIN(`position`) FROM {$table} WHERE parent_id=?"; 287 | $position = $adapter->fetchOne($adapter->quoteInto($sql, $newParent->getId())); 288 | } 289 | $position+=1; 290 | 291 | return $position; 292 | } 293 | 294 | protected function _tableTreeStoreExists() 295 | { 296 | if (null === $this->_tableTreeStoreExists) { 297 | $this->_tableTreeStoreExists = $this->getReadConnection() 298 | ->isTableExists(Mage::getConfig()->getTablePrefix() . 'cms_page_tree_store'); 299 | } 300 | 301 | return $this->_tableTreeStoreExists; 302 | } 303 | } 304 | -------------------------------------------------------------------------------- /app/code/community/JR/CleverCms/Model/Resource/Cms/Page/Collection.php: -------------------------------------------------------------------------------- 1 | _init('cms/page'); 8 | $this->_map['fields']['page_id'] = 'main_table.page_id'; 9 | $this->_map['fields']['store'] = 'main_table.store_id'; 10 | } 11 | 12 | public function addChildrenFilter(JR_CleverCms_Model_Cms_Page $page) 13 | { 14 | $this->setOrder('position', Varien_Data_Collection::SORT_ORDER_ASC); 15 | $this->getSelect() 16 | ->where('main_table.store_id = ?', $page->getStoreId()) 17 | ->where('main_table.parent_id = ?', $page->getId()); 18 | 19 | $currentStoreId = Mage::app()->getStore()->getId(); 20 | if ($page->getStoreId() == 0 && $currentStoreId) { 21 | $this->getSelect() 22 | ->join(array('stores' => $this->getTable('cms/page_store')), 'main_table.page_id = stores.page_id', '') 23 | ->where('stores.store_id = ?', $currentStoreId); 24 | } 25 | 26 | return $this; 27 | } 28 | 29 | public function addIdFilter($pageIds) 30 | { 31 | if (is_array($pageIds)) { 32 | if (empty($pageIds)) { 33 | $condition = ''; 34 | } else { 35 | $condition = array('in' => $pageIds); 36 | } 37 | } elseif (is_numeric($pageIds)) { 38 | $condition = $pageIds; 39 | } elseif (is_string($pageIds)) { 40 | $ids = explode(',', $pageIds); 41 | if (empty($ids)) { 42 | $condition = $pageIds; 43 | } else { 44 | $condition = array('in' => $ids); 45 | } 46 | } 47 | $this->addFieldToFilter('page_id', $condition); 48 | 49 | return $this; 50 | } 51 | 52 | public function addPermissionsFilter($customerGroupId) 53 | { 54 | $this->getSelect()->join( 55 | array('p' => $this->getTable('cms/page_permission')), 56 | 'p.page_id = main_table.page_id', 57 | '' 58 | )->where('p.customer_group_id = ?', $customerGroupId); 59 | 60 | return $this; 61 | } 62 | 63 | public function addIncludeInMenuFilter() 64 | { 65 | return $this->addFieldToFilter('include_in_menu', '1'); 66 | } 67 | 68 | public function addAllChildrenFilter(JR_CleverCms_Model_Cms_Page $page) 69 | { 70 | $this->addFieldToFilter('identifier', array('like' => $page->getIdentifier() . '/%')) 71 | ->addFieldToFilter('store_id', $page->getStoreId()); 72 | 73 | return $this; 74 | } 75 | 76 | protected function _afterLoad() 77 | { 78 | if ($this->_previewFlag) { 79 | $items = $this->getColumnValues('page_id'); 80 | if (count($items)) { 81 | $select = $this->getConnection()->select() 82 | ->from($this->getTable('cms/page')) 83 | ->where($this->getTable('cms/page').'.store_id IN (?)', $items); 84 | if ($result = $this->getConnection()->fetchPairs($select)) { 85 | foreach ($this as $item) { 86 | if (!isset($result[$item->getData('page_id')])) { 87 | continue; 88 | } 89 | if ($result[$item->getData('page_id')] == 0) { 90 | $stores = Mage::app()->getStores(false, true); 91 | $storeId = current($stores)->getId(); 92 | $storeCode = key($stores); 93 | } else { 94 | $storeId = $result[$item->getData('page_id')]; 95 | $storeCode = Mage::app()->getStore($storeId)->getCode(); 96 | } 97 | $item->setData('_first_store_id', $storeId); 98 | $item->setData('store_code', $storeCode); 99 | } 100 | } 101 | } 102 | } 103 | 104 | parent::_afterLoad(); 105 | } 106 | 107 | protected function _renderFiltersBefore() 108 | { 109 | return $this; 110 | } 111 | } -------------------------------------------------------------------------------- /app/code/community/JR/CleverCms/Model/Resource/Cms/Page/Permission.php: -------------------------------------------------------------------------------- 1 | _init('cms/page_permission', 'permission_id'); 8 | } 9 | 10 | public function getPagesByStoreAndCustomerGroup($storeId, $customerGroupId) 11 | { 12 | $select = $this->_getReadAdapter() 13 | ->select() 14 | ->from($this->getMainTable(), 'page_id') 15 | ->where('store_id = ?', $storeId) 16 | ->where('customer_group_id = ?', $customerGroupId); 17 | 18 | return $this->_getReadAdapter()->fetchCol($select); 19 | } 20 | 21 | public function savePermissions($storeId, $customerGroupId, $pages) 22 | { 23 | $adapter = $this->_getWriteAdapter(); 24 | 25 | $adapter->delete( 26 | $this->getMainTable(), 27 | $adapter->quoteInto('store_id = ?', $storeId) . ' AND ' 28 | . $adapter->quoteInto('customer_group_id = ?', $customerGroupId)); 29 | 30 | $insert = array(); 31 | foreach ($pages as $pageId) { 32 | if ($pageId) { 33 | $insert[] = array( 34 | 'store_id' => $storeId, 35 | 'customer_group_id' => $customerGroupId, 36 | 'page_id' => $pageId, 37 | ); 38 | } 39 | } 40 | if (! empty($insert)) { 41 | $adapter->insertMultiple($this->getMainTable(), $insert); 42 | } 43 | 44 | return $this; 45 | } 46 | 47 | public function exists($storeId, $customerGroupId, $pageId) 48 | { 49 | $select = $this->_getReadAdapter() 50 | ->select() 51 | ->from($this->getMainTable()) 52 | ->where('store_id IN (0, ?)', $storeId) 53 | ->where('customer_group_id = ?', $customerGroupId) 54 | ->where('page_id = ?', $pageId); 55 | 56 | return $this->_getReadAdapter()->fetchRow($select); 57 | } 58 | } -------------------------------------------------------------------------------- /app/code/community/JR/CleverCms/Model/Resource/Cms/Page/Tree.php: -------------------------------------------------------------------------------- 1 | getConnection('write'), 14 | $resource->getTableName('cms_page_tree'), 15 | array( 16 | Varien_Data_Tree_Dbp::ID_FIELD => 'page_id', 17 | Varien_Data_Tree_Dbp::PATH_FIELD => 'path', 18 | Varien_Data_Tree_Dbp::ORDER_FIELD => 'position', 19 | Varien_Data_Tree_Dbp::LEVEL_FIELD => 'level', 20 | ) 21 | ); 22 | } 23 | 24 | public function setStoreId($storeId) 25 | { 26 | $this->_storeId = (int) $storeId; 27 | return $this; 28 | } 29 | 30 | public function getStoreId() 31 | { 32 | if ($this->_storeId === null) { 33 | $this->_storeId = Mage::app()->getStore()->getId(); 34 | } 35 | return $this->_storeId; 36 | } 37 | 38 | public function addCollectionData($collection=null, $sorted=false, $exclude=array(), $toLoad=true, $onlyActive = false) 39 | { 40 | if (is_null($collection)) { 41 | $collection = $this->getCollection($sorted); 42 | } else { 43 | $this->setCollection($collection); 44 | } 45 | 46 | if (!is_array($exclude)) { 47 | $exclude = array($exclude); 48 | } 49 | 50 | $nodeIds = array(); 51 | foreach ($this->getNodes() as $node) { 52 | if (!in_array($node->getId(), $exclude)) { 53 | $nodeIds[] = $node->getId(); 54 | } 55 | } 56 | $collection->addIdFilter($nodeIds); 57 | if ($onlyActive) { 58 | 59 | $disabledIds = $this->_getDisabledIds($collection); 60 | if ($disabledIds) { 61 | $collection->addFieldToFilter('page_id', array('nin'=>$disabledIds)); 62 | } 63 | } 64 | 65 | if($toLoad) { 66 | $collection->load(); 67 | 68 | foreach ($collection as $page) { 69 | if ($this->getNodeById($page->getId())) { 70 | $this->getNodeById($page->getId()) 71 | ->addData($page->getData()); 72 | } 73 | } 74 | 75 | foreach ($this->getNodes() as $node) { 76 | if (!$collection->getItemById($node->getId()) && $node->getParent()) { 77 | $this->removeNode($node); 78 | } 79 | } 80 | } 81 | 82 | return $this; 83 | } 84 | 85 | protected function _getItemIsActive($id) 86 | { 87 | if (!in_array($id, $this->_inactiveItems)) { 88 | return true; 89 | } 90 | return false; 91 | } 92 | 93 | public function getCollection($sorted=false) 94 | { 95 | if (is_null($this->_collection)) { 96 | $this->_collection = $this->_getDefaultCollection($sorted); 97 | } 98 | return $this->_collection; 99 | } 100 | 101 | public function setCollection($collection) 102 | { 103 | if (!is_null($this->_collection)) { 104 | destruct($this->_collection); 105 | } 106 | $this->_collection = $collection; 107 | return $this; 108 | } 109 | 110 | protected function _getDefaultCollection($sorted = false) 111 | { 112 | $collection = Mage::getModel('cms/page')->getCollection(); 113 | /* @var $collection JR_CleverCms_Model_Resource_Cms_Page_Collection */ 114 | 115 | if ($sorted) { 116 | if (is_string($sorted)) { 117 | // $sorted is supposed to be attribute name 118 | $collection->addAttributeToSort($sorted); 119 | } else { 120 | $collection->addAttributeToSort('name'); 121 | } 122 | } 123 | 124 | return $collection; 125 | } 126 | 127 | public function toSelectHtml($name = '', $value = false) 128 | { 129 | $html = ''; 146 | 147 | return $html; 148 | } 149 | } -------------------------------------------------------------------------------- /app/code/community/JR/CleverCms/Model/Resource/Setup.php: -------------------------------------------------------------------------------- 1 | getNode('modules')->children(); 15 | $myModule = substr(__CLASS__, 0, strpos(__CLASS__, '_Model')); 16 | foreach ($modules as $moduleName => $moduleNode) { 17 | if ($moduleName != $myModule) { 18 | Mage::getConfig()->addAllowedModules($moduleName); 19 | } 20 | } 21 | Mage::getConfig()->reinit(); 22 | 23 | return $this; 24 | } 25 | 26 | return parent::applyUpdates(); 27 | } 28 | } -------------------------------------------------------------------------------- /app/code/community/JR/CleverCms/Model/Resource/Sitemap/Cms/Page.php: -------------------------------------------------------------------------------- 1 | setMappedTableName('cms_page', Mage::getConfig()->getTablePrefix() . 'cms_page_tree'); 11 | $this->_init('cms/page', 'page_id'); 12 | } 13 | 14 | public function getCollection($storeId) 15 | { 16 | $pages = array(); 17 | $select = $this->_getWriteAdapter() 18 | ->select() 19 | ->from(array('main_table' => $this->getMainTable()), array($this->getIdFieldName(), 'identifier AS url')) 20 | ->where('main_table.is_active = 1') 21 | ->where('main_table.store_id IN (?)', array(0, $storeId)); 22 | $query = $this->_getWriteAdapter()->query($select); 23 | 24 | while ($row = $query->fetch()) { 25 | if ($row['url'] == Mage_Cms_Model_Page::NOROUTE_PAGE_ID) { 26 | continue; 27 | } 28 | $page = $this->_prepareObject($row); 29 | $pages[$page->getId()] = $page; 30 | } 31 | 32 | return $pages; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /app/code/community/JR/CleverCms/controllers/Adminhtml/Cms/Page/PermissionsController.php: -------------------------------------------------------------------------------- 1 | loadLayout() 9 | ->_setActiveMenu('cms/page_permissions') 10 | ->_addBreadcrumb(Mage::helper('cms')->__('CMS'), Mage::helper('cms')->__('CMS')) 11 | ->_addBreadcrumb(Mage::helper('cms')->__('Manage Pages Permissions'), Mage::helper('cms')->__('Manage Pages Permissions')); 12 | 13 | return $this; 14 | } 15 | 16 | public function preDispatch() 17 | { 18 | parent::preDispatch(); 19 | Mage::getDesign()->setTheme('clever'); 20 | 21 | return $this; 22 | } 23 | 24 | public function indexAction() 25 | { 26 | $storeId = $this->getRequest()->getParam('store'); 27 | $groupId = $this->getRequest()->getParam('group'); 28 | if (null === $storeId || null === $groupId) { 29 | if (null === $storeId) { 30 | $storeId = Mage::getSingleton('admin/session')->getCmsLastViewedStore(); 31 | if (null === $storeId) { 32 | if (Mage::app()->isSingleStoreMode()) { 33 | $storeId = Mage::app()->getDefaultStoreView()->getId(); 34 | } else { 35 | $storeId = 0; 36 | } 37 | } 38 | } 39 | if (! $groupId) { 40 | $groupId = Mage_Customer_Model_Group::NOT_LOGGED_IN_ID; 41 | } 42 | $this->_redirect('*/*/', array('store' => $storeId, 'group' => $groupId)); 43 | return; 44 | } 45 | 46 | Mage::getSingleton('admin/session') 47 | ->setCmsLastViewedStore($storeId); 48 | 49 | if (! Mage::getStoreConfigFlag('cms/clever/permissions_enabled')) { 50 | $this->_getSession()->addNotice($this->__('Permissions are currently disabled. To enable permissions, go to System > Configuration > Content Management > Clever CMS.')); 51 | } 52 | 53 | $this->_title($this->__('CMS')) 54 | ->_title($this->__('Pages')) 55 | ->_title($this->__('Manage Content Permissions')); 56 | 57 | $this->_initAction(); 58 | $this->renderLayout(); 59 | } 60 | 61 | public function saveAction() 62 | { 63 | $storeId = $this->getRequest()->getParam('store'); 64 | $customerGroupId = $this->getRequest()->getParam('group'); 65 | $pages = explode(',', $this->getRequest()->getPost('pages')); 66 | 67 | try { 68 | if (null === $storeId || null === $customerGroupId) { 69 | Mage::throwException($this->__('An error occurred while saving permissions.')); 70 | } 71 | Mage::getResourceModel('cms/page_permission')->savePermissions($storeId, $customerGroupId, $pages); 72 | Mage::getSingleton('adminhtml/session')->addSuccess($this->__('Permissions have been successfully saved.')); 73 | } catch (Exception $e) { 74 | Mage::getSingleton('adminhtml/session')->addError($e->getMessage()); 75 | } 76 | 77 | $this->_redirect('*/*/', array('store' => $storeId, 'group' => $customerGroupId)); 78 | return; 79 | } 80 | } -------------------------------------------------------------------------------- /app/code/community/JR/CleverCms/controllers/Adminhtml/Cms/PageController.php: -------------------------------------------------------------------------------- 1 | setTheme('clever'); 11 | 12 | return $this; 13 | } 14 | 15 | protected function _initPage() 16 | { 17 | $pageId = (int) $this->getRequest()->getParam('id'); 18 | $page = Mage::getModel('cms/page')->load($pageId); 19 | Mage::register('cms_page', $page); 20 | Mage::getSingleton('cms/wysiwyg_config')->setStoreId($this->getRequest()->getParam('store')); 21 | 22 | return $page; 23 | } 24 | 25 | public function indexAction() 26 | { 27 | $storeId = $this->getRequest()->getParam('store'); 28 | if (null === $storeId) { 29 | $storeId = Mage::getSingleton('admin/session')->getCmsLastViewedStore(); 30 | if (null === $storeId) { 31 | if (Mage::app()->isSingleStoreMode()) { 32 | $storeId = Mage::app()->getDefaultStoreView()->getId(); 33 | } else { 34 | $storeId = 0; 35 | } 36 | } 37 | $this->_redirect('*/*/', array('store' => $storeId)); 38 | return; 39 | } 40 | 41 | if ($pageId = Mage::getSingleton('admin/session')->getLastEditedPage()) { 42 | $page = Mage::getModel('cms/page')->load($pageId); 43 | if ($page->getId()) { 44 | Mage::register('cms_page', $page); 45 | } 46 | } 47 | 48 | $this->_title($this->__('CMS')) 49 | ->_title($this->__('Pages')) 50 | ->_title($this->__('Manage Content')); 51 | 52 | $this->_initAction(); 53 | $this->renderLayout(); 54 | } 55 | 56 | public function addAction() 57 | { 58 | Mage::getSingleton('admin/session') 59 | ->unsLastEditedPage(); 60 | $this->_forward('edit'); 61 | } 62 | 63 | public function editAction() 64 | { 65 | $this->_title($this->__('CMS')) 66 | ->_title($this->__('Pages')) 67 | ->_title($this->__('Manage Content')); 68 | 69 | // 1. Get ID and create model 70 | $storeId = (int) $this->getRequest()->getParam('store'); 71 | $parentId = (int) $this->getRequest()->getParam('parent'); 72 | $id = (int) $this->getRequest()->getParam('id'); 73 | 74 | if ($storeId && !$id && !$parentId) { 75 | $store = Mage::app()->getStore($storeId); 76 | } 77 | 78 | $page = Mage::getModel('cms/page'); 79 | 80 | // 2. Initial checking 81 | if ($id) { 82 | $page->load($id); 83 | if (! $page->getId()) { 84 | Mage::getSingleton('adminhtml/session')->addError(Mage::helper('cms')->__('This page no longer exists.')); 85 | $this->_redirect('*/*/'); 86 | return; 87 | } 88 | } else { 89 | $page->setStoreId($storeId); 90 | if ($storeId === 0 && ! Mage::app()->isSingleStoreMode()) { 91 | $page->setStores(array_keys(Mage::app()->getStores())); 92 | } 93 | } 94 | 95 | $this->_title($page->getId() ? $page->getTitle() : $this->__('New Page')); 96 | 97 | // 3. Set entered data if was error when we do save 98 | $data = Mage::getSingleton('adminhtml/session')->getFormData(true); 99 | if (! empty($data)) { 100 | $page->setData($data); 101 | } 102 | 103 | Mage::getSingleton('admin/session') 104 | ->setCmsLastViewedStore($storeId); 105 | Mage::getSingleton('admin/session') 106 | ->setLastEditedPage($page->getId()); 107 | 108 | // 4. Register model to use later in blocks 109 | Mage::register('cms_page', $page); 110 | 111 | // 5. Build edit form 112 | $this->_initAction() 113 | ->_addBreadcrumb($id ? Mage::helper('cms')->__('Edit Page') : Mage::helper('cms')->__('New Page'), $id ? Mage::helper('cms')->__('Edit Page') : Mage::helper('cms')->__('New Page')); 114 | 115 | if ($this->getRequest()->isXmlHttpRequest()) { 116 | $this->getLayout()->getBlock('root')->setTemplate('cms/page/ajax-edit.phtml'); 117 | } 118 | 119 | $this->renderLayout(); 120 | } 121 | 122 | public function treeAction() 123 | { 124 | $storeId = (int) $this->getRequest()->getParam('store'); 125 | $pageId = (int) $this->getRequest()->getParam('id'); 126 | 127 | if ($storeId) { 128 | if (!$pageId) { 129 | $rootId = Mage::getResourceModel('cms/page')->getStoreRootId($storeId); 130 | $this->getRequest()->setParam('id', $rootId); 131 | } 132 | Mage::getSingleton('admin/session') 133 | ->setCmsLastViewedStore($storeId); 134 | } 135 | 136 | $page = $this->_initPage(); 137 | $block = $this->getLayout()->createBlock('jr_clevercms/adminhtml_cms_page_tree'); 138 | $root = $block->getRoot(); 139 | $this->getResponse()->setBody(Mage::helper('core')->jsonEncode(array( 140 | 'data' => $block->getTree(), 141 | 'parameters' => array( 142 | 'text' => $block->buildNodeName($root), 143 | 'draggable' => false, 144 | 'allowDrop' => ($root->getIsVisible()) ? true : false, 145 | 'id' => (int) $root->getId(), 146 | 'expanded' => (int) $block->getIsWasExpanded(), 147 | 'store_id' => (int) $block->getStore()->getId(), 148 | 'page_id' => (int) $page->getId(), 149 | 'root_visible'=> (int) $root->getIsVisible() 150 | )))); 151 | } 152 | 153 | public function moveAction() 154 | { 155 | $pageId = (int) $this->getRequest()->getParam('id'); 156 | $page = $this->_initPage(); 157 | if (!$page) { 158 | $this->getResponse()->setBody(Mage::helper('cms')->__('Page move error')); 159 | return; 160 | } 161 | /** 162 | * New parent page identifier 163 | */ 164 | $parentNodeId = $this->getRequest()->getPost('pid', false); 165 | /** 166 | * Page id after which we have put our page 167 | */ 168 | $prevNodeId = $this->getRequest()->getPost('aid', false); 169 | 170 | try { 171 | $page->move($parentNodeId, $prevNodeId); 172 | $this->getResponse()->setBody("SUCCESS"); 173 | } 174 | catch (Mage_Core_Exception $e) { 175 | $this->getResponse()->setBody($e->getMessage()); 176 | } 177 | catch (Exception $e){ 178 | $this->getResponse()->setBody(Mage::helper('cms')->__('Page move error'.$e)); 179 | Mage::logException($e); 180 | } 181 | } 182 | 183 | public function pagesJsonAction() 184 | { 185 | if ($this->getRequest()->getParam('expand_all')) { 186 | Mage::getSingleton('admin/session')->setIsTreeWasExpanded(true); 187 | } else { 188 | Mage::getSingleton('admin/session')->setIsTreeWasExpanded(false); 189 | } 190 | if ($pageId = (int) $this->getRequest()->getPost('id')) { 191 | $this->getRequest()->setParam('id', $pageId); 192 | 193 | if (!$page = $this->_initPage()) { 194 | return; 195 | } 196 | $this->getResponse()->setBody( 197 | $this->getLayout()->createBlock('jr_clevercms/adminhtml_cms_page_tree') 198 | ->getTreeJson($page) 199 | ); 200 | } 201 | } 202 | 203 | public function saveAction() 204 | { 205 | // check if data sent 206 | if ($data = $this->getRequest()->getPost()) { 207 | $data = $this->_filterPostData($data); 208 | //init model and set data 209 | $model = Mage::getModel('cms/page'); 210 | 211 | if ($id = $this->getRequest()->getParam('page_id')) { 212 | $model->load($id); 213 | } 214 | 215 | $data['parent_id'] = $this->getRequest()->getParam('parent'); 216 | $data['store_id'] = $this->getRequest()->getParam('store'); 217 | 218 | if (!isset($data['stores'])) { 219 | $data['stores'] = array(); 220 | } 221 | 222 | $model->addData($data); 223 | 224 | Mage::dispatchEvent('cms_page_prepare_save', array('page' => $model, 'request' => $this->getRequest())); 225 | 226 | // try to save it 227 | try { 228 | // save the data 229 | $model->save(); 230 | 231 | Mage::getSingleton('admin/session') 232 | ->setLastEditedPage($model->getId()); 233 | 234 | // display success message 235 | Mage::getSingleton('adminhtml/session')->addSuccess(Mage::helper('cms')->__('The page has been saved.')); 236 | // clear previously saved data from session 237 | Mage::getSingleton('adminhtml/session')->setFormData(false); 238 | // go to grid 239 | $this->_redirect('*/*/'); 240 | return; 241 | 242 | } catch (Mage_Core_Exception $e) { 243 | $this->_getSession()->addError($e->getMessage()); 244 | } catch (Exception $e) { 245 | $this->_getSession()->addException($e, Mage::helper('cms')->__('An error occurred while saving the page.')); 246 | } 247 | 248 | $this->_getSession()->setFormData($data); 249 | $this->_redirect('*/*/index', array('store' => $data['store_id'])); 250 | return; 251 | } 252 | $this->_redirect('*/*/'); 253 | } 254 | 255 | public function switchAction() 256 | { 257 | Mage::getSingleton('admin/session') 258 | ->unsCmsLastViewedStore() 259 | ->unsLastEditedPage(); 260 | $this->_forward('index'); 261 | } 262 | } -------------------------------------------------------------------------------- /app/code/community/JR/CleverCms/controllers/Cms/IndexController.php: -------------------------------------------------------------------------------- 1 | getStore(); 10 | $pageId = Mage::getResourceModel('cms/page')->getStoreRootId($store->getId()); 11 | if (!$pageId) { 12 | $pageId = Mage::getResourceModel('cms/page')->getStoreRootId(0); 13 | } 14 | if (!Mage::helper('cms/page')->renderPage($this, $pageId)) { 15 | $this->_forward('defaultIndex'); 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /app/code/community/JR/CleverCms/etc/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 2.1.2 6 | 7 | 8 | 9 | 10 | 11 | 12 | JR_CleverCms 13 | JR_CleverCms_Model_Resource_Setup 14 | 15 | 16 | 17 | 18 | 19 | 20 | JR_CleverCms_Model_Cms_Page 21 | JR_CleverCms_Model_Cms_Page_Permission 22 | 23 | 24 | 25 | 26 | JR_CleverCms_Model_Resource_Cms_Page 27 | JR_CleverCms_Model_Resource_Cms_Page_Tree 28 | JR_CleverCms_Model_Resource_Cms_Page_Collection 29 | JR_CleverCms_Model_Resource_Cms_Page_Permission 30 | 31 | 32 | cms_page_permission
33 |
34 |
35 | 36 | 37 | JR_CleverCms_Model_Resource_Sitemap_Cms_Page 38 | 39 | 40 |
41 | 42 | 43 | JR_CleverCms_Block 44 | 45 | 46 | 47 | JR_CleverCms_Block_Cms_Page 48 | 49 | 50 | 51 | 52 | JR_CleverCms_Block_Catalog_Navigation 53 | 54 | 55 | 56 | 57 | JR_CleverCms_Block_Adminhtml_Cms_Page_Edit 58 | JR_CleverCms_Block_Adminhtml_Cms_Page_Widget_Chooser 59 | 60 | 61 | 62 | 63 | 64 | 65 | JR_CleverCms_Helper_Cms_Page 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | singleton 74 | JR_CleverCms_Model_Adminhtml_Cms_Page_Observer 75 | prepareForm 76 | 77 | 78 | 79 | 80 | 81 | 82 | singleton 83 | JR_CleverCms_Model_Adminhtml_Cms_Page_Observer 84 | prepareSave 85 | 86 | 87 | 88 | 89 |
90 | 91 | 92 | 93 | 94 | 95 | JR_CleverCms_Cms 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | JR_CleverCms_Adminhtml 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | CMS 116 | 70 117 | 118 | 119 | Pages 120 | 121 | 122 | Manage Content 123 | adminhtml/cms_page 124 | 125 | 126 | Manage Permissions 127 | adminhtml/cms_page_permissions 128 | 129 | 130 | 131 | 132 | Static Blocks 133 | adminhtml/cms_block 134 | 10 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | JR_CleverCms.csv 144 | 145 | 146 | 147 | 148 | 149 |
-------------------------------------------------------------------------------- /app/code/community/JR/CleverCms/etc/system.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | text 9 | 200 10 | 1 11 | 1 12 | 1 13 | 14 | 15 | 16 | select 17 | adminhtml/system_config_source_yesno 18 | adminhtml/system_config_backend_store 19 | 1 20 | 1 21 | 1 22 | 1 23 | 24 | 25 | 26 | select 27 | adminhtml/system_config_source_yesno 28 | adminhtml/system_config_backend_store 29 | 2 30 | 1 31 | 1 32 | 1 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 0 43 | 0 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /app/code/community/JR/CleverCms/sql/clever_cms_setup/mysql4-install-0.1.0.php: -------------------------------------------------------------------------------- 1 | startSetup(); 5 | 6 | $connection = $installer->getConnection(); 7 | $tablePage = $installer->getTable('cms_page'); 8 | $tablePageStore = $installer->getTable('cms_page_store'); 9 | $tablePageTree = $installer->getTable('cms_page_tree'); 10 | $tableCoreStore = $installer->getTable('core_store'); 11 | $tablePermission = $installer->getTable('cms_page_permission'); 12 | $tableStore = $installer->getTable('core_store'); 13 | $tableCustomerGroup = $installer->getTable('customer_group'); 14 | 15 | try { 16 | $connection->beginTransaction(); 17 | 18 | $installer->run(" 19 | DROP TABLE IF EXISTS `{$tablePageTree}`; 20 | CREATE TABLE `{$tablePageTree}` LIKE `{$tablePage}`; 21 | 22 | ALTER TABLE `{$tablePageTree}` 23 | ADD `store_id` SMALLINT( 5 ) UNSIGNED NOT NULL DEFAULT 0, 24 | ADD `parent_id` SMALLINT( 6 ) NOT NULL DEFAULT 0, 25 | ADD `path` VARCHAR( 255 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, 26 | ADD `position` SMALLINT( 6 ) UNSIGNED NOT NULL DEFAULT 0, 27 | ADD `level` TINYINT( 3 ) UNSIGNED NOT NULL DEFAULT 0, 28 | ADD `include_in_menu` TINYINT( 1 ) UNSIGNED NOT NULL DEFAULT '1', 29 | ADD `children_count` TINYINT( 3 ) UNSIGNED NOT NULL DEFAULT 0; 30 | 31 | ALTER TABLE `{$tablePageTree}` CHANGE `identifier` `identifier` VARCHAR( 255 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT ''; 32 | 33 | ALTER TABLE `{$tablePageTree}` ADD INDEX ( `store_id` ); 34 | 35 | ALTER TABLE `{$tablePageTree}` ADD FOREIGN KEY ( `store_id` ) REFERENCES `{$tableCoreStore}` ( 36 | `store_id` 37 | ) ON DELETE CASCADE ON UPDATE CASCADE; 38 | 39 | ALTER TABLE `{$tablePageTree}` ADD UNIQUE ( 40 | `identifier` , 41 | `store_id` 42 | ); 43 | 44 | DROP TABLE IF EXISTS `{$tablePermission}`; 45 | CREATE TABLE `{$tablePermission}` ( 46 | `permission_id` MEDIUMINT(8) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, 47 | `store_id` SMALLINT(5) UNSIGNED NOT NULL, 48 | `customer_group_id` SMALLINT(3) UNSIGNED NOT NULL, 49 | `page_id` SMALLINT(6) NOT NULL 50 | ) ENGINE = INNODB CHARACTER SET utf8 COLLATE utf8_general_ci; 51 | 52 | ALTER TABLE `{$tablePermission}` ADD INDEX (`store_id`); 53 | ALTER TABLE `{$tablePermission}` ADD INDEX (`customer_group_id`); 54 | ALTER TABLE `{$tablePermission}` ADD INDEX (`page_id`); 55 | ALTER TABLE `{$tablePermission}` ADD UNIQUE (`store_id`, `customer_group_id`, `page_id`); 56 | 57 | ALTER TABLE `{$tablePermission}` ADD FOREIGN KEY (`store_id`) REFERENCES `{$tableStore}` ( 58 | `store_id` 59 | ) ON DELETE CASCADE ON UPDATE CASCADE; 60 | 61 | ALTER TABLE `{$tablePermission}` ADD FOREIGN KEY (`customer_group_id`) REFERENCES `{$tableCustomerGroup}` ( 62 | `customer_group_id` 63 | ) ON DELETE CASCADE ON UPDATE CASCADE; 64 | 65 | ALTER TABLE `{$tablePermission}` ADD FOREIGN KEY (`page_id`) REFERENCES `{$tablePageTree}` ( 66 | `page_id` 67 | ) ON DELETE CASCADE ON UPDATE CASCADE; 68 | "); 69 | 70 | Mage::app()->reinitStores(); // needed to have store list 71 | $isSingleStoreMode = Mage::app()->isSingleStoreMode(); 72 | $stores = Mage::app()->getStores(!$isSingleStoreMode); 73 | 74 | // Create pages 75 | foreach ($stores as $store) { 76 | $storeId = $store->getId(); 77 | 78 | // Retrieve old store pages 79 | $select = $connection->select() 80 | ->from(array('pages' => $tablePage)) 81 | ->join(array('stores' => $tablePageStore), 'pages.page_id = stores.page_id', '') 82 | ->where('stores.store_id = ?', $storeId); 83 | 84 | if ($isSingleStoreMode) { 85 | $select->orWhere('stores.store_id = 0'); 86 | } 87 | 88 | $pages = $connection->fetchAll($select); 89 | 90 | // Create default root page for this store 91 | $home = JR_CleverCms_Model_Cms_Page::createDefaultStoreRootPage($storeId); 92 | $homeId = $home->getId(); 93 | 94 | if (count($pages) > 0) { 95 | $insertedPages = array(); 96 | $childrenCount = 0; 97 | foreach ($pages as $page) { 98 | if (!isset($insertedPages[$page['identifier']])) { 99 | $insertedPages[$page['identifier']] = 0; 100 | } else { 101 | $insertedPages[$page['identifier']]++; 102 | $page['identifier'] = $page['identifier'] . '-' . $insertedPages[$page['identifier']]; 103 | } 104 | unset($page['page_id']); 105 | $page['parent_id'] = $homeId; 106 | $page['store_id'] = $storeId; 107 | $connection->insert($tablePageTree, $page); 108 | $childrenCount++; 109 | } 110 | $installer->run(" 111 | UPDATE `{$tablePageTree}` SET 112 | `parent_id` = '{$homeId}', 113 | `path` = CONCAT('{$homeId}/', `page_id`), 114 | `position` = `page_id`, 115 | `level` = '2' 116 | WHERE `store_id` = {$storeId} AND `page_id` != {$homeId}; 117 | 118 | UPDATE `{$tablePageTree}` SET 119 | `path` = '{$homeId}', 120 | `identifier` = '', 121 | `level` = '1', 122 | `position` = '1', 123 | `children_count` = {$childrenCount} 124 | WHERE `store_id` = {$storeId} AND `page_id` = {$homeId}; 125 | "); 126 | } 127 | } 128 | 129 | // Reinit default permissions 130 | $connection->truncateTable($tablePermission); 131 | 132 | // Create default permissions 133 | foreach (Mage::getModel('cms/page')->getCollection() as $page) { 134 | foreach (Mage::getModel('customer/group')->getCollection() as $customerGroup) { 135 | $storeId = $page->getStoreId(); 136 | $customerGroupId = $customerGroup->getId(); 137 | $pageId = $page->getId(); 138 | $installer->run("INSERT INTO `{$tablePermission}` (`store_id`, `customer_group_id`, `page_id`) VALUES ('{$storeId}', '{$customerGroupId}', '{$pageId}');"); 139 | } 140 | } 141 | 142 | $connection->commit(); 143 | } catch (Exception $e) { 144 | $connection->rollback(); 145 | throw $e; 146 | } 147 | 148 | $installer->endSetup(); 149 | -------------------------------------------------------------------------------- /app/code/community/JR/CleverCms/sql/clever_cms_setup/mysql4-upgrade-2.0.0-2.1.0.php: -------------------------------------------------------------------------------- 1 | startSetup(); 5 | 6 | $connection = $installer->getConnection(); 7 | $tablePageStore = $installer->getTable('cms_page_store'); 8 | $tablePageTree = $installer->getTable('cms_page_tree'); 9 | $tablePageTreeStore = $installer->getTable('cms_page_tree_store'); 10 | 11 | try { 12 | $connection->beginTransaction(); 13 | 14 | $installer->run(" 15 | DROP TABLE IF EXISTS `{$tablePageTreeStore}`; 16 | CREATE TABLE `{$tablePageTreeStore}` LIKE `{$tablePageStore}`; 17 | "); 18 | 19 | Mage::app()->reinitStores(); // needed to have store list 20 | $storeIds = array_keys(Mage::app()->getStores(false)); 21 | foreach ($storeIds as $storeId) { 22 | $installer->run(" 23 | INSERT INTO `{$tablePageTreeStore}` (`page_id`, `store_id`) 24 | SELECT `page_id`, {$storeId} AS `store_id` FROM `{$tablePageTree}` WHERE `store_id` = '0'; 25 | "); 26 | } 27 | 28 | $connection->commit(); 29 | } catch (Exception $e) { 30 | $connection->rollback(); 31 | throw $e; 32 | } 33 | 34 | $installer->endSetup(); 35 | -------------------------------------------------------------------------------- /app/design/adminhtml/default/clever/layout/local.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 1 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 1 21 | 22 | 23 | 24 | 25 | 26 | 1 27 | 28 | 29 | 30 | 31 | 0 32 | 33 | 34 | 0 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /app/design/adminhtml/default/clever/template/cms/page/ajax-edit.phtml: -------------------------------------------------------------------------------- 1 |
2 |
3 | getChildHtml('left')): ?> 4 | 5 |
6 |
7 | getChildHtml('left') ?> 8 |
9 |
10 |
11 |
getMessagesBlock()->getGroupedHtml() ?>
12 | getChildHtml('content') ?> 13 | 17 |
18 |
19 |
20 | 21 | 22 |
getMessagesBlock()->getGroupedHtml() ?>
23 | getChildHtml('content') ?> 24 | 25 |
26 |
27 | getChildHtml('js') ?> 28 | -------------------------------------------------------------------------------- /app/design/adminhtml/default/clever/template/cms/page/index.phtml: -------------------------------------------------------------------------------- 1 | 14 | 15 | 16 | 17 | getChildHtml('head') ?> 18 | 19 | 20 | getBodyClass()?'class="'.$this->getBodyClass().'"':'' ?>> 21 | getChildHtml('notification_window'); ?> 22 |
23 | getChildHtml('global_notices') ?> 24 |
25 | getChildHtml('header') ?> 26 |
27 | getChildHtml('menu') ?> 28 |
29 | getChildHtml('notifications'); ?> 30 |
31 |
32 | getChildHtml('left')): ?> 33 | 34 |
35 |
36 | getChildHtml('left') ?> 37 |
38 |
getMessagesBlock()->getGroupedHtml() ?>
39 |
40 |
41 | getChildHtml('content') ?> 42 |
43 |
44 |
45 | 46 | 47 |
getMessagesBlock()->getGroupedHtml() ?>
48 | getChildHtml('content') ?> 49 | 50 |
51 |
52 | 55 |
56 | getChildHtml('js') ?> 57 | getChildHtml('profiler') ?> 58 | 61 | 62 | getChildHtml('before_body_end') ?> 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /app/design/adminhtml/default/clever/template/cms/page/permissions/index.phtml: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 | 5 | 8 | 9 |

__('Manage Content Permissions') ?>

6 | 7 |
10 |
11 |
12 | getBlockHtml('formkey')?> 13 | getChildHtml() ?> 14 |
15 | -------------------------------------------------------------------------------- /app/design/adminhtml/default/clever/template/cms/page/permissions/tree.phtml: -------------------------------------------------------------------------------- 1 |
2 |
3 |

__('Pages Permissions') ?>

4 |
5 | 6 |
7 | 8 | 9 |
10 |
11 |
12 |
13 |
14 |
15 | getResTreeJson() ?> 16 | 17 | 109 | -------------------------------------------------------------------------------- /app/design/adminhtml/default/clever/template/cms/page/store/switcher.phtml: -------------------------------------------------------------------------------- 1 | getWebsites()): ?> 2 |

3 | 26 |

27 | 47 | 48 | -------------------------------------------------------------------------------- /app/design/adminhtml/default/clever/template/cms/page/tree.phtml: -------------------------------------------------------------------------------- 1 |
2 |
3 |

__('Pages') ?>

4 | getRoot()): ?> 5 | getAddSubButtonHtml() ?> 6 | 7 |
8 | getStoreSwitcherHtml();?> 9 |
10 | getRoot()): ?> 11 | __('Collapse All'); ?> | __('Expand All'); ?> 12 | 13 |
14 | getRoot()): ?> 15 |
16 |
17 |
18 |
19 | 429 | 430 | 431 | 585 | getChildHtml('googleoptimizer_js') ?> -------------------------------------------------------------------------------- /app/design/adminhtml/default/clever/template/customer/group/switcher.phtml: -------------------------------------------------------------------------------- 1 | getCustomerGroups()): ?> 2 |

3 | 8 |

9 | 29 | 30 | -------------------------------------------------------------------------------- /app/design/frontend/default/clever/template/catalog/navigation/top.phtml: -------------------------------------------------------------------------------- 1 | 8 | hasCategoriesNavigationMenuPages(); 10 | $_categoriesIsLast = !$this->hasCmsNavigationMenuPages(); 11 | 12 | $_menu = $this->renderCategoriesMenuHtmlClever(0, $_categoriesIsLast, true, 'level-top'); 13 | $_menu .= $this->renderCmsMenuHtml(0, true, $_cmsIsFirst, 'level-top'); 14 | ?> 15 | 16 | 21 | -------------------------------------------------------------------------------- /app/etc/modules/JR_CleverCms.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | true 6 | community 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /app/locale/fr_FR/JR_CleverCms.csv: -------------------------------------------------------------------------------- 1 | "Enable Permissions","Activer la gestion des droits" 2 | "Permissions are currently disabled. To enable permissions, go to System > Configuration > Content Management > Clever CMS.","La gestion des droits est actuellement désactivée. Pour l'activer, allez dans Système > Configuration > Gestion de contenu > Clever CMS." 3 | "An error occurred while saving permissions.","Une erreur est survenue lors de la sauvegarde des droits." 4 | "Permissions have been successfully saved.","Les droits ont été enregistrés avec succès." 5 | "Manage Content Permissions","Gestion des droits sur les pages de contenu" 6 | "Save Permissions","Sauvegarder les droits" 7 | "Pages Permissions","Liste des droits sur les pages de contenu" 8 | "Choose Customer Group","Choisir un groupe utilisateur" 9 | "Please confirm customer group switching. All data that hasn't been saved will be lost.","Veuillez confirmer le changement de groupe utilisateur. Les données non sauvegardées seront perdues." 10 | "Permissions","Gérer les droits" 11 | "Manage Content","Gérer le contenu" 12 | "Manage Permissions","Gérer les droits" 13 | "URL Key","Clé d'url" 14 | "Include in Navigation Menu","Inclure dans le menu de navigation" 15 | "Leave blank for automatic generation.
URL is relative to parent URL. Current URL: %s","Laissez vide pour génération automatique.
L'url est relative à l'url de la page parente. URL actuelle : %s" 16 | "Set clever theme and default package to have an example of navigation","Activez le thème clever et le package default pour avoir un exemple de navigation" 17 | "Create Permanent Redirect for URLs if URL Key Changed","Créer des redirections d'URL permanentes si celles-ci changent" 18 | "Add Page", "Ajouter une page" 19 | "Save Page", "Sauvegarder la page" 20 | "Page Title","Titre de la page" 21 | "Status","Statut" 22 | "Yes","Oui" 23 | "No","Non" 24 | "Enabled","Activé" 25 | "Disabled","Désactivé" 26 | "Content","Contenu" 27 | "Meta Data","Méta-données" 28 | "Collapse All","Tout réduire" 29 | "Expand All","Tout développer" 30 | "Page Information","Informations de la page" 31 | "Content Heading","En-tête du contenu" 32 | "Show / Hide Editor","Afficher/masquer l'éditeur" 33 | "Keywords","Mots-clés" 34 | "Description","Description" 35 | "Page Layout","Mise en page" 36 | "Layout","Mise en page" 37 | "Layout Update XML","XML de mise à jour d'agencement" 38 | "Custom Design","Design personnalisé" 39 | "Custom Design From","Design personnalisé à partir du" 40 | "Custom Design To","Design personnalisé jusqu'au" 41 | "Custom Layout","Agencement personnalisé" 42 | "Custom Layout Update XML","XML de mise à jour de l'agencement personnalisé" 43 | "Store View","Vue magasin" 44 | "Edit Page '%s'","Modifier la page '%s'" 45 | "New Page","Nouvelle page" 46 | --------------------------------------------------------------------------------