Added permissions/options for pages/menu items
authorMarcel Werk <burntime@woltlab.com>
Thu, 17 Mar 2016 18:01:42 +0000 (19:01 +0100)
committerMarcel Werk <burntime@woltlab.com>
Thu, 17 Mar 2016 18:02:50 +0000 (19:02 +0100)
com.woltlab.wcf/page.xml
wcfsetup/install/files/lib/data/menu/Menu.class.php
wcfsetup/install/files/lib/data/menu/item/MenuItem.class.php
wcfsetup/install/files/lib/data/menu/item/MenuItemNodeTree.class.php
wcfsetup/install/files/lib/data/page/Page.class.php
wcfsetup/install/files/lib/system/package/plugin/PagePackageInstallationPlugin.class.php
wcfsetup/setup/db/install.sql

index 85995c9c95ef837b5362eeceaeaa2fa9fd5c3f21..5144bc891650801e121d0455c614097a8bef9a16 100644 (file)
@@ -6,12 +6,15 @@
                        <controller>wcf\page\DashboardPage</controller>
                        <name language="de"><![CDATA[Dashboard]]></name>
                        <name language="en"><![CDATA[Dashboard]]></name>
+                       <options>module_dashboard_page</options>
                </page>
                
                <page identifier="com.woltlab.wcf.MembersList">
                        <controller>wcf\page\MembersListPage</controller>
                        <name language="de"><![CDATA[Mitglieder]]></name>
                        <name language="en"><![CDATA[Members]]></name>
+                       <permissions>user.profile.canViewMembersList</permissions>
+                       <options>module_members_list</options>
                </page>
                <page identifier="com.woltlab.wcf.RecentActivityList">
                        <controller>wcf\page\RecentActivityListPage</controller>
                        <name language="de"><![CDATA[Benutzer Online]]></name>
                        <name language="en"><![CDATA[Users Online]]></name>
                        <parent>com.woltlab.wcf.MembersList</parent>
+                       <permissions>user.profile.canViewUsersOnlineList</permissions>
+                       <options>module_users_online</options>
                </page>
                <page identifier="com.woltlab.wcf.Team">
                        <controller>wcf\page\TeamPage</controller>
                        <name language="de"><![CDATA[Team]]></name>
                        <name language="en"><![CDATA[Team]]></name>
                        <parent>com.woltlab.wcf.MembersList</parent>
+                       <permissions>user.profile.canViewMembersList</permissions>
+                       <options>module_team_page</options>
                </page>
                <page identifier="com.woltlab.wcf.UserSearch">
                        <controller>wcf\page\UserSearchForm</controller>
                        <name language="de"><![CDATA[Benutzer suchen]]></name>
                        <name language="en"><![CDATA[Search Users]]></name>
                        <parent>com.woltlab.wcf.MembersList</parent>
+                       <permissions>user.profile.canViewMembersList</permissions>
+                       <options>module_members_list</options>
                </page>
                
                <!-- static -->
                <page identifier="com.woltlab.wcf.PrivacyPolicy">
                        <name language="en">Privacy Policy</name>
                        <name language="de">Datenschutzerklärung</name>
+                       <options>module_privacy_policy_page</options>
                        
                        <content language="en">
                                <title>Privacy Policy</title>
index 009984aec7d2332b3be2f0cd7a9a1eb0383c5016..53e4fc20c06d39f6f44c1d239224118670f3887e 100644 (file)
@@ -67,8 +67,7 @@ class Menu extends DatabaseObject {
         * @return      boolean
         */
        public function hasContent() {
-               return true; // @todo
-               //return count(MenuCache::getInstance()->getMenuItemsByMenuID($this->menuID)->getNodeList());
+               return $this->getMenuItemNodeTree()->getVisibleItemCount() > 0;
        }
        
        /**
@@ -104,7 +103,7 @@ class Menu extends DatabaseObject {
        }
        
        /**
-        * @return MenuItemNodeTree
+        * @return      MenuItemNodeTree
         */
        protected function getMenuItemNodeTree() {
                if ($this->menuItemNodeTree === null) {
index 1fe322c4bfb2cdc6bc034b49b89848a81b180369..da5576cb495cef6c10a3d17d1b7ee60cab653f17 100644 (file)
@@ -90,13 +90,11 @@ class MenuItem extends DatabaseObject {
        /**
         * Returns the page that is linked by this menu item.
         * 
-        * @return      Page
+        * @return      Page|null
         */
        public function getPage() {
-               if ($this->page === null) {
-                       if ($this->pageID) {
-                               $this->page = new Page($this->pageID);
-                       }
+               if ($this->page === null && $this->pageID) {
+                       $this->page = new Page($this->pageID);
                }
                
                return $this->page;
@@ -108,6 +106,10 @@ class MenuItem extends DatabaseObject {
         * @return      boolean
         */
        public function isVisible() {
+               if ($this->getPage() !== null && !$this->getPage()->isVisible()) {
+                       return false;
+               }
+               
                if ($this->getMenuPageHandler() !== null) {
                        return $this->getMenuPageHandler()->isVisible($this->pageObjectID ?: null);
                }
@@ -129,7 +131,7 @@ class MenuItem extends DatabaseObject {
        }
        
        /**
-        * @return      IMenuPageHandler
+        * @return      IMenuPageHandler|null
         */
        protected function getMenuPageHandler() {
                $page = $this->getPage();
index a96a02c1641f4d517afc1078798fed7ab9e0e762..c0c69811becd715abc2c5b96e74e791936a0aedc 100644 (file)
@@ -37,6 +37,12 @@ class MenuItemNodeTree {
         */
        public $node;
        
+       /**
+        * number of visible items
+        * @var integer
+        */
+       protected $visibleItemCount = 0;
+       
        /**
         * Creates a new MenuItemNodeTree object.
         * 
@@ -54,6 +60,7 @@ class MenuItemNodeTree {
                        $menuItemList->readObjects();
                }
                
+               // build menu structure
                foreach ($menuItemList as $menuItem) {
                        $this->menuItems[$menuItem->itemID] = $menuItem;
                                
@@ -63,25 +70,13 @@ class MenuItemNodeTree {
                        $this->menuItemStructure[$menuItem->parentItemID][] = $menuItem->itemID;
                }
                
-               // filter items by visibility
-               foreach ($this->menuItems as $menuItemID => $menuItem) {
-                       if (!$menuItem->isVisible()) {
-                               unset($this->menuItems[$menuItemID]);
-                               unset($this->menuItemStructure[$menuItemID]);
-                               
-                               // remove item from parent item structure
-                               $key = array_search($menuItemID, $this->menuItemStructure[$menuItem->parentItemID]);
-                               array_splice($this->menuItemStructure[$menuItem->parentItemID], $key, 1);
-                       }
-               }
-               
                // generate node tree
                $this->node = new MenuItemNode();
                $this->node->setChildren($this->generateNodeTree(null, $this->node));
        }
        
        /**
-        * Generates the node tree recursively
+        * Generates the node tree recursively.
         * 
         * @param       integer                 $parentID       parent menu item id
         * @param       MenuItemNode            $parentNode     parent menu item object
@@ -93,11 +88,15 @@ class MenuItemNodeTree {
                $itemIDs = (isset($this->menuItemStructure[$parentID]) ? $this->menuItemStructure[$parentID] : []);
                foreach ($itemIDs as $itemID) {
                        $menuItem = $this->menuItems[$itemID];
+                       if (!$menuItem->isVisible()) continue;
                        $node = new MenuItemNode($parentNode, $menuItem, ($parentNode !== null ? ($parentNode->getDepth() + 1) : 0));
                        $nodes[] = $node;
                                
                        // get children
                        $node->setChildren($this->generateNodeTree($itemID, $node));
+                       
+                       // increase item counter
+                       $this->visibleItemCount++;
                }
                
                return $nodes;
@@ -113,11 +112,20 @@ class MenuItemNodeTree {
        }
        
        /**
-        * Returns the iteratable node list
+        * Returns the iteratable node list.
         *
         * @return      \RecursiveIteratorIterator
         */
        public function getNodeList() {
                return new \RecursiveIteratorIterator($this->node, \RecursiveIteratorIterator::SELF_FIRST);
        }
+       
+       /**
+        * Returns the number of visible items.
+        * 
+        * @return      integer
+        */
+       public function getVisibleItemCount() {
+               return $this->visibleItemCount;
+       }
 }
index 23d9135a7846a983cff20e404130b39350666be2..5bb8d49206968d633e9462034901be0eea92a2b0 100644 (file)
@@ -163,6 +163,44 @@ class Page extends DatabaseObject {
                return $this->pageHandler;
        }
        
+       /**
+        * Returns false if this page should be hidden from menus, but does not control the accessibility
+        * of the page itself.
+        *
+        * @return      boolean         false if the page should be hidden from menus
+        */
+       public function isVisible() {
+               // check the options of this page
+               $hasEnabledOption = true;
+               if ($this->options) {
+                       $hasEnabledOption = false;
+                       $options = explode(',', strtoupper($this->options));
+                       foreach ($options as $option) {
+                               if (defined($option) && constant($option)) {
+                                       $hasEnabledOption = true;
+                                       break;
+                               }
+                       }
+               }
+               if (!$hasEnabledOption) return false;
+               
+               // check the permission of this page for the active user
+               $hasPermission = true;
+               if ($this->permissions) {
+                       $hasPermission = false;
+                       $permissions = explode(',', $this->permissions);
+                       foreach ($permissions as $permission) {
+                               if (WCF::getSession()->getPermission($permission)) {
+                                       $hasPermission = true;
+                                       break;
+                               }
+                       }
+               }
+               if (!$hasPermission) return false;
+               
+               return true;
+       }
+       
        /**
         * Returns the page's internal name.
         *
index 1eef245549e4c077dba4f5243a8d1732f7068fb8..48f7b5f3cb5e4729439bfd10ca9f3e9861a2fa15 100644 (file)
@@ -155,7 +155,9 @@ class PagePackageInstallationPlugin extends AbstractXMLPackageInstallationPlugin
                        'name' => $name,
                        'originIsSystem' => 1,
                        'parentPageID' => $parentPageID,
-                       'requireObjectID' => (!empty($data['elements']['requireObjectID'])) ? 1 : 0
+                       'requireObjectID' => (!empty($data['elements']['requireObjectID'])) ? 1 : 0,
+                       'options' => (isset($data['elements']['options'])) ? $data['elements']['options'] : '',
+                       'permissions' => (isset($data['elements']['permissions'])) ? $data['elements']['permissions'] : ''
                ];
        }
        
index 6967524587b07a04b1b2a0edc02f736a3db38b35..9e8412db33c041a95f2e2db6653af2f059d0619a 100644 (file)
@@ -915,7 +915,9 @@ CREATE TABLE wcf1_page (
        handler VARCHAR(255) NOT NULL DEFAULT '',
        controllerCustomURL VARCHAR(255) NOT NULL DEFAULT '',
        requireObjectID TINYINT(1) NOT NULL DEFAULT 0,
-       lastUpdateTime INT(10) NOT NULL DEFAULT 0
+       lastUpdateTime INT(10) NOT NULL DEFAULT 0,
+       permissions TEXT NULL,
+       options TEXT NULL
 );
 
 DROP TABLE IF EXISTS wcf1_page_content;