JEvents 1.4

TWEAK : User access level for JEvents

Postby original.sky » Mon May 12, 2008 3:14 pm

Hello,

First of all I would like to thank the developpers of this amazing tool, it saved me many many hours (or even days !) in coding. As a small contribution to the common work, I would like to present you a little tweak I have developped the last few days.


KEY IDEA : What do we want ? JEvents provides a shared calendar accessible for all registered users. But there isn't, so far, any way to control who can see or modify what. We will then allow Jevents to give or not access in read/write to the registered user, depending its settings. This won't need any hack of the Joomla DB.

HOW : We cannot know which category will the user pick before he chooses it in the Add Event page. So we cannot work with hiding/showing the "add event" link. The list of categories accessible to the registered user is built by the function buildCategorySelect in events.class.php. Depending on the user's defined event category, we will load or not the categories.

We could work with a new field, added to the jos_users table, but the params (plus all its associated functions in Joomla framework) offers enough for what we want to do.

We will work with :
jos_users (getting the current user id and assigned category)
jos_categories (getting the category details)

LOGIC : Each registered user has one more assigned category to its user account, called catid_ev. It's the id of any category from section com_events. If its catid_ev is set to 9999 (ALL) then he will be able to read and modify everywhere. Else, he will be able to modify/read the category equal to its own-defined catid_ev category. I worked with 9999 because it speaks much more to me, but you can of course create a category called ALL or ADMIN and use its given ID.

The catid_ev is stored within the params field of the jos_users table, then it avoids table modification. Joomla is provided with several ready-to-use functions to write and read these parameters. It will shorten our code.

Here are the modifications :

Step 1 : Alter the user account in creation/modification :

1.1 Add a new element type, called categoryEvents :

In www\libraries\joomla\html\parameter\element\, create a new categoryevents.php file, basically a copy of the category.php, with few changes : We will search all com_events categories, with a shortened SQL query.

Code: Select all
class JElementCategoryEvents extends JElement

[...]

var   $_name = 'CategoryEvents';

[...]

if (!isset ($section)) {
         // alias for section
         $section = $node->attributes('scope');
         if (!isset ($section)) {
            $section = 'com_events';
         }
      }

         $query = 'SELECT c.id, c.title' .
            ' FROM #__categories AS c' .
            ' WHERE c.section = '.$db->Quote($section).
            ' ORDER BY c.title';
[...]


You can note I do not do any check on the published state or not. That's because I set the ALL category as unpublished (then not visible in the front-end). But we still need the admins to see it (or any other special category)

1.2 Add the dropdown list of events categories in the user account details :

In administrator\components\com_users\models\___.xml (you can add this field to the 3 types of view :
Code: Select all
<param name="catid_ev" type="CategoryEvents" default="" label="Events Categories" description="Assigned access level to event categories" />


Step 2 : Create a new function within class mosEventsHTML to filter categories available to the user


This function works exactly like the standard buildCategorySelect, but add two controls :

in www\components\com_events\events.class.php :

Code: Select all
function buildCategorySelectWithRights( $catid, $args ){
        global $database, $gid, $option;

      global $catidList;

      // GETTING CURRENT USER ID AND MATCHING WITH DETAILS WITHIN USER PARAMETERS
      $user = & JFactory::getUser();
      $catid_ev = $user->getParam( 'catid_ev' );
      
           $catsql = "SELECT id as value, name as text"
           . "\n FROM #__categories"
          . "\n WHERE section='$option'"
          . "\n AND access<='$gid'"
          . "\n AND published='1'";

      // IF NOT IN 'ALL' GROUP, LOAD ONLY ONE CATEGORY
      if ($catid_ev <> 9999) {
      $catidList = $catid_ev;
      $catsql .=" AND id IN ($catidList)";
      }
      // ELSE LOAD ALL - except the hidden ALL category
      else{
      $catsql .=" AND id NOT IN ($catid_ev)";
      }
   
      $catsql .=" ORDER BY ordering";

        $categories[] = mosHTML::makeOption( '0', _CAL_LANG_EVENT_CHOOSE_CATEG, 'value', 'text');
        $database->setQuery($catsql);
        $categories = array_merge( $categories, $database->loadObjectList() );
        $clist = mosHTML::selectList( $categories, 'catid', $args, 'value', 'text', $catid );
        echo $clist;
      
    }


Step 3 : Assign the new function into the HTML template, in administrator\components\com_events\admin.events.html.php :

Code: Select all
mosEventsHTML::buildCategorySelectWithRights($row->catid, ....)


Step 4 : Add a access level check for viewing :

Into www\components\com_events\events.php, within the variables declaration/init :

Code: Select all
// CHECK THE USER'S RIGHTS. If ALL, load ALL (or keep link's variables. Else, load only user's group events

   $user = & JFactory::getUser();
   $catid_ev = $user->getParam( 'catid_ev' );
   if ($catid_ev == 9999) {
   $catid   = intval( mosGetParam( $_REQUEST,'catid', 0 ));
   $catidsIn = urldecode( mosGetParam( $_REQUEST, 'catids', 'NONE' ) );
   }
   else
   $catid = $catid_ev;


So far, it's working perfect for me. We could even add an additional level, as every category can be the child of another category, Maybe I will developp it if needed.
original.sky
 
Posts: 5
Joined: Mon May 12, 2008 2:35 pm

Postby averyml » Wed May 14, 2008 8:10 pm

This is exactly what I was looking for! I can't believe someone actually wrote directions on this just a couple days before I went to look for it. Thank you! A couple things I noticed though: With the dropdown box method of selecting categories, it would appear that each user can only be assigned one category at a time. I was able to manually edit the database and change catid_ev=1, for example, to catid_ev=1,3,4, which is sufficient, but I was curious if there was another way of doing this that I just didn't realize...

Also, you say in your directions "you can add this field to the 3 types of view," but, if my understanding is correct, doesn't doing this make it possible for users to change their own permissions, which kind of defeats the purpose?
averyml
 
Posts: 4
Joined: Wed May 14, 2008 7:10 pm

Postby original.sky » Thu May 15, 2008 11:55 am

Thanks for your comment, I was as well in a real need for this tool, but no time to wait :)

averyml wrote:Also, you say in your directions "you can add this field to the 3 types of view," but, if my understanding is correct, doesn't doing this make it possible for users to change their own permissions, which kind of defeats the purpose?


As the user.xml is used to build the parameters shown on the Front and Back-end as well, this is correct ... unless you choose to hide the parameters configuration to the user ! In Control Panel > Global Configuration > System > User Settings > Front-end User Parameters (HIDE).

Which seems more logical, as I prefer give the minimum rights to the users to change their profile (especially since they are also assigned different editors, Don't really want them to mess that ..).

averyml wrote:]A couple things I noticed though: With the dropdown box method of selecting categories, it would appear that each user can only be assigned one category at a time


I would say we can add a new dropdown list :
Code: Select all
<param name="catid_ev2" type="CategoryEvents" default="" label="Events Categories" description="Assigned access level to event categories" />

This would add a new line to the parameters and will be stored under "catid_ev2".

Of course, it means that we would not have to only check catid_ev, but also catid_ev2, 3 or 4 if needed (which is not a big deal, just a new loop for building an array of catid_ev :

I haven't done it, so I will do a quick overview of the main build function modifications :

Code: Select all
function buildCategorySelectWithRights( $catid, $args ){
        global $database, $gid, $option;

      global $catidList;

      // GETTING CURRENT USER ID AND MATCHING WITH DETAILS WITHIN USER PARAMETERS
      $user = & JFactory::getUser();
     
     > DECLARE A NEW ARRAY OF CATID_EV
     > For $i == 0 to x (number of cats we can configure) $catid_ev[i] = $user->getParam( 'catid_ev[$i]' );
     
           $catsql = "SELECT id as value, name as text"
           . "\n FROM #__categories"
          . "\n WHERE section='$option'"
          . "\n AND access<='$gid'"
          . "\n AND published='1'";
       
      $i = 0;
      $ALLMember = False;
      // IF FIND ALL GROUP, BREAK. ELSE, ASSIGN CATIDS
      While ($catid_ev[$i] <> 9999) and $i <> x (number of cats we can configure) {
           if ($catid_ev[$i] == 9999) {
                 $catsql .=" AND id NOT IN ($catid_ev[$i])";
                 $ALLMember = True;
           }
           else $catidList = ''$catidList + ',' + $catid_ev'';
       i++;
       }
       if ($ALLMember == False) $catsql .=" AND id IN ($catidList)";

      $catsql .=" ORDER BY ordering";

        $categories[] = mosHTML::makeOption( '0', _CAL_LANG_EVENT_CHOOSE_CATEG, 'value', 'text');
        $database->setQuery($catsql);
        $categories = array_merge( $categories, $database->loadObjectList() );
        $clist = mosHTML::selectList( $categories, 'catid', $args, 'value', 'text', $catid );
        echo $clist;
     
    }


This is more or less how I see it -not sure about all my php, it's just few weeks I am practicing-. With little time I could work with a true array then exploded, instead of adding ',' between each turn (then no need to remove the first ',' added at the first turn when the $catidList is empty.
original.sky
 
Posts: 5
Joined: Mon May 12, 2008 2:35 pm


Return to JEvents 1.4

  • Who is online
  • View new posts
  • View unanswered posts
  • In total there are 0 users online :: 0 registered and 0 hidden (based on users active over the past 5 minutes)
  • Most users ever online was 94 on Tue Sep 01, 2009 12:33 am
  • Users browsing this forum: No registered users