]> gitweb.fluxo.info Git - lorea/elgg.git/commitdiff
Fixes #4789: group_gatekeeper() and river hide closed/invisible group content more...
authorSteve Clay <steve@mrclay.org>
Fri, 7 Sep 2012 05:38:03 +0000 (01:38 -0400)
committerSteve Clay <steve@mrclay.org>
Fri, 7 Sep 2012 05:38:03 +0000 (01:38 -0400)
engine/classes/ElggGroupItemVisibility.php [new file with mode: 0644]
engine/lib/group.php
engine/lib/views.php
views/default/page/components/list.php

diff --git a/engine/classes/ElggGroupItemVisibility.php b/engine/classes/ElggGroupItemVisibility.php
new file mode 100644 (file)
index 0000000..2c7e2ab
--- /dev/null
@@ -0,0 +1,93 @@
+<?php
+
+/**
+ * Determines if otherwise visible items should be hidden from a user due to group
+ * policy or visibility.
+ *
+ * @class      ElggGroupItemVisibility
+ * @package    Elgg.Core
+ * @subpackage Groups
+ *
+ * @access private
+ */
+class ElggGroupItemVisibility {
+
+       const REASON_MEMBERSHIP = 'membershiprequired';
+       const REASON_LOGGEDOUT = 'loggedinrequired';
+       const REASON_NOACCESS = 'noaccess';
+
+       /**
+        * @var bool
+        */
+       public $shouldHideItems = false;
+
+       /**
+        * @var string
+        */
+       public $reasonHidden = '';
+
+       /**
+        * Determine visibility of items within a container for the current user
+        *
+        * @param int $container_guid GUID of a container (may/may not be a group)
+        *
+        * @return ElggGroupItemVisibility
+        *
+        * @todo Make this faster, considering it must run for every river item.
+        */
+       static public function factory($container_guid) {
+               // cache because this may be called repeatedly during river display, and
+               // due to need to check group visibility, cache will be disabled for some
+               // get_entity() calls
+               static $cache = array();
+
+               $ret = new ElggGroupItemVisibility();
+
+               if (!$container_guid) {
+                       return $ret;
+               }
+
+               $user = elgg_get_logged_in_user_entity();
+               $user_guid = $user ? $user->guid : 0;
+
+               $container_guid = (int) $container_guid;
+
+               $cache_key = "$container_guid|$user_guid";
+               if (empty($cache[$cache_key])) {
+                       // compute
+
+                       $container = get_entity($container_guid);
+                       $is_visible = (bool) $container;
+
+                       if (!$is_visible) {
+                               // see if it *really* exists...
+                               $prev_access = elgg_set_ignore_access();
+                               $container = get_entity($container_guid);
+                               elgg_set_ignore_access($prev_access);
+                       }
+
+                       if ($container && $container instanceof ElggGroup) {
+                               /* @var ElggGroup $container */
+
+                               if ($is_visible) {
+                                       if (!$container->isPublicMembership()) {
+                                               if ($user) {
+                                                       if (!$container->isMember($user) && !$user->isAdmin()) {
+                                                               $ret->shouldHideItems = true;
+                                                               $ret->reasonHidden = self::REASON_MEMBERSHIP;
+                                                       }
+                                               } else {
+                                                       $ret->shouldHideItems = true;
+                                                       $ret->reasonHidden = self::REASON_LOGGEDOUT;
+                                               }
+                                       }
+                               } else {
+                                       $ret->shouldHideItems = true;
+                                       $ret->reasonHidden = self::REASON_NOACCESS;
+                               }
+                       }
+                       $cache[$cache_key] = $ret;
+               }
+               return $cache[$cache_key];
+       }
+}
index feb1f1e7fb3af396dfbb81a021d3203f2b8c3031..b81146e6129484898c24854982ffef1a8bb74b67 100644 (file)
@@ -247,48 +247,42 @@ function get_users_membership($user_guid) {
 }
 
 /**
- * Checks access to a group.
+ * May the current user access item(s) on this page? If the page owner is a group,
+ * membership, visibility, and logged in status are taken into account.
  *
  * @param boolean $forward If set to true (default), will forward the page;
  *                         if set to false, will return true or false.
  *
- * @return true|false If $forward is set to false.
+ * @return bool If $forward is set to false.
  */
 function group_gatekeeper($forward = true) {
-       $allowed = true;
-       $url = '';
-
-       if ($group = elgg_get_page_owner_entity()) {
-               if ($group instanceof ElggGroup) {
-                       $url = $group->getURL();
-                       if (!$group->isPublicMembership()) {
-                               // closed group so must be member or an admin
-
-                               if (!elgg_is_logged_in()) {
-                                       $allowed = false;
-                                       if ($forward == true) {
-                                               $_SESSION['last_forward_from'] = current_page_url();
-                                               register_error(elgg_echo('loggedinrequired'));
-                                               forward('', 'login');
-                                       }
-                               } else if (!$group->isMember(elgg_get_logged_in_user_entity())) {
-                                       $allowed = false;
-                               }
 
-                               // Admin override
-                               if (elgg_is_admin_logged_in()) {
-                                       $allowed = true;
-                               }
-                       }
-               }
+       $page_owner_guid = elgg_get_page_owner_guid();
+       if (!$page_owner_guid) {
+               return true;
        }
+       $visibility = ElggGroupItemVisibility::factory($page_owner_guid);
 
-       if ($forward && $allowed == false) {
-               register_error(elgg_echo('membershiprequired'));
-               forward($url, 'member');
+       if (!$visibility->shouldHideItems) {
+               return true;
        }
+       if ($forward) {
+               // only forward to group if user can see it
+               $group = get_entity($page_owner_guid);
+               $forward_url = $group ? $group->getURL() : '';
+
+               if ($visibility->reasonHidden !== ElggGroupItemVisibility::REASON_MEMBERSHIP) {
+                       $_SESSION['last_forward_from'] = current_page_url();
+                       $forward_reason = 'login';
+               } else {
+                       $forward_reason = 'member';
+               }
 
-       return $allowed;
+               register_error(elgg_echo($visibility->reasonHidden));
+               forward($forward_url, $forward_reason);
+       }
+
+       return false;
 }
 
 /**
index b00334062990552e08f927e303f406b6215351be..90737c2604ff28e188b33bc7d6030d88a229b778 100644 (file)
@@ -1243,7 +1243,7 @@ function elgg_view_module($type, $title, $body, array $vars = array()) {
  * @param ElggRiverItem $item A river item object
  * @param array         $vars An array of variables for the view
  *
- * @return string|false Depending on success
+ * @return string
  */
 function elgg_view_river_item($item, array $vars = array()) {
        // checking default viewtype since some viewtypes do not have unique views per item (rss)
@@ -1256,6 +1256,12 @@ function elgg_view_river_item($item, array $vars = array()) {
        if (!$subject || !$object) {
                // subject is disabled or subject/object deleted
                return '';
+       } else {
+               // hide based on object's container
+               $visibility = ElggGroupItemVisibility::factory($object->container_guid);
+               if ($visibility->shouldHideItems) {
+                       return '';
+               }
        }
 
        $vars['item'] = $item;
index 0cf7d507caf97540cbcb9c68372702a61ac4f555..28ed58ddf8cc546070c230ee02c03a53327da0e8 100644 (file)
@@ -51,14 +51,15 @@ if ($pagination && $count) {
 if (is_array($items) && count($items) > 0) {
        $html .= "<ul class=\"$list_class\">";
        foreach ($items as $item) {
-               if (elgg_instanceof($item)) {
-                       $id = "elgg-{$item->getType()}-{$item->getGUID()}";
-               } else {
-                       $id = "item-{$item->getType()}-{$item->id}";
+               $li = elgg_view_list_item($item, $vars);
+               if ($li) {
+                       if (elgg_instanceof($item)) {
+                               $id = "elgg-{$item->getType()}-{$item->getGUID()}";
+                       } else {
+                               $id = "item-{$item->getType()}-{$item->id}";
+                       }
+                       $html .= "<li id=\"$id\" class=\"$item_class\">$li</li>";
                }
-               $html .= "<li id=\"$id\" class=\"$item_class\">";
-               $html .= elgg_view_list_item($item, $vars);
-               $html .= '</li>';
        }
        $html .= '</ul>';
 }