argument to check if the node's author is the logged in user

stijnparidaens - March 14, 2009 - 05:01

I'm looking for a way to overwrite this:

if (user_access('edit own availability calendars')) {
$output .= ' '. l('edit', 'availability-calendars/'. $node->nid .'/'. date('Y/m', mktime(0, 0, 0, $month, 1, $year)) .'/edit',
array('query' => 'destination=node/'. $node->nid));
}

It doesn't work now and can't find support at the module page. Since every user has the same role they can all access and edit each others calendars so it gives a major security risk. I can't seem to find the right argument to replace "if (user_access('edit own availability calendars'))"
It should be that it checks if the node's author = the logged in user. If that's true, it may give the output, otherwise not.

Does anybody know what argument to put there ?

THANKS !

have you tried

Aurian Noreinor - March 20, 2009 - 19:00

have you tried this?

<?php
function module_access($op, $node, $account)) {

  switch(
$op) {
    case
'update':
      return
user_access('edit all characters', $account) || (user_access('edit own character', $account) && ($node->uid == $account->uid)) ? TRUE : NULL;
  }
}
?>

I can't seem to implement this in the module

stijnparidaens - April 3, 2009 - 08:53

Thanks for the reply but I can't seem to get this implemented in the module
this is the full function

function theme_availability_calendars_month($node, $year, $month, $startofweek, $booked) {
 
  $month_meta = availability_calendars_month_meta($year, $month, $startofweek);
 
  for ($j=0;$j<$month_meta['weeksinmonth'];$j++) {
    for ($i=0;$i<7;$i++) {
      $counter++;
      $week[$j][$i] = $counter;
      // offset the days
      $week[$j][$i] -= $month_meta['firstday'];
      if (($week[$j][$i] < 1) || ($week[$j][$i] > $month_meta['daysinmonth'])) {   
        $week[$j][$i] = "";
      }
    }
  }
 
  $output  = "<table class='cal'>\n";
  $output .= "<tr class='calmonth'>\n";
  $output .= "<th colspan='8'>". t("@date", array('@date' => format_date(mktime(12, 0, 0, $month, 1, $year), 'custom', 'F Y')));
  if ($user->uid != $node->uid && $user->uid != 1) {
    $output .= ' '. l('edit', 'availability-calendars/'. $node->nid .'/'. date('Y/m', mktime(0, 0, 0, $month, 1, $year)) .'/edit',
                      array('query' => 'destination=node/'. $node->nid));
  }
  $output .= "</th>\n";
  $output .= "</tr>\n";

but this has a security risk because this argument let's all users of the same role edit each others calendars and that's not good.
Can you tell me where and how I implement your code ?
Thanks !

"...but this has a security

mm167 - April 3, 2009 - 09:14

"...but this has a security risk because this argument let's all users of the same role edit each others calendars and that's not good.."

why there's still security risk mentioned above if u are using the following code?

"if ($user->uid != $node->uid && $user->uid != 1) {"

...but..looks u have forgotten to add "global $user;" in your function.....

We go the drupal way. How about you?
http://www.drupalway.com

I"m trying to rewrite

stijnparidaens - April 3, 2009 - 18:26

I'm trying to rewrite the availbility calendar module because there is no maintenance for the moment and I need the module.

If you use the module now you can only assign roles to edit the calendars and since alle users on my site that can edit the calendars have the same roles, everyone can now edit each others calenders :(
I was hoping it would be easy to rewrite it so that only the calendars owner could edit it but i'm stuck.

Addin global $user; doesn't seem to do the trick :(
Thanks for the tip dough

Any other suggestions ?
I was thinking to solve the problem by creating a block to say "edit my calendar" that would only appear when an argument checks if the logged in user is also the nodes author but I can't seem the right code

I'm still learning php so it's often to tricky

can u tell what is missing

mm167 - April 4, 2009 - 06:15

can u tell what is missing (or what is wrong) in the module?

that may help us to modify the module for u...

We go the drupal way. How about you?
http://www.drupalway.com

I think there is something wrong with the user access

stijnparidaens - April 5, 2009 - 07:37

I think there is something wrong with the user access of "edit own availability calendars"
When you grant a role user access "edit own availability calendars" they can not only edit their own calendars but every users calendar and I would like to change that. Users should only be permitted to edit calendars on nodes that they created.

the full code is this

<?php
// $Id: availability_calendars.module,v 1.1.4.4 2009/01/11 15:59:45 geodan Exp $

/**
* Availability Calendars Module
*
* @file
* Allows for availability information to be displayed using calendars on specified content types. Originally based on the Availability Module.
* @author Dan Karran (geodaniel) <dan at karran dot net>
*/

/**
* A callback function to see if allowed to edit the calendar.
*/
function availability_can_edit() {

  return user_access('edit availability calendars') || user_access('edit own availability calendars');

}

/**
* Implementation of hook_menu().
*/
function availability_calendars_menu() {
  $items = array();

  $items['admin/settings/availability-calendars'] = array(
    'title' => 'Availability Calendars',
    'description' => 'Configure global settings for availability calendars module.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('availability_calendars_admin_settings'),
    'access arguments' => array('edit availability calendars')
  );

  $items['availability-calendars'] = array(
    'title' => 'Availability calendar',
    'page callback' => 'availability_calendars_page',
    'access callback' => 'availability_can_edit',
    'type' => MENU_CALLBACK,
  );

  return $items;
}

/**
* Implementation of hook_perm().
*/
function availability_calendars_perm() {
  return array('edit own availability calendars', 'edit availability calendars');
}

/**
* Settings page callback.
*/
function availability_calendars_admin_settings() {
  $form = array();

  $form['display'] = array(
    '#type' => 'fieldset',
    '#title' => t('View settings'),
    '#description' => t('Check where you want availability calendars to be displayed. If you choose none of the suggested places below you will need to output it manually using %func function.', array('%func' => 'theme_availability_calendars_node()'))
  );
  $form['display']['availability_calendars_display_nodeview'] = array(
    '#type' => 'checkbox',
    '#title' => t('Node view page'),
    '#default_value' => variable_get('availability_calendars_display_nodeview', TRUE)
  );
  $form['display']['availability_calendars_display_monthcount'] = array(
    '#type' => 'textfield',
    '#title' => t('Number of months to display'),
    '#default_value' => variable_get('availability_calendars_display_monthcount', 12),
    '#description' => t("Your calendars will show this number of months to all users except those with the 'edit own availability calendars' or 'edit availability calendars' who will always see 3 extra months on the calendars they can edit. This is to allow them to enter information into future calendars before it is made publicly available.")
  );

  //TODO: add status codes and css classes in here

  return system_settings_form($form);
}

/**
* Create tab to show node availability
*/
function availability_calendars_menu_callback() {
  $node = menu_get_object();

  if (availability_calendars_enabled($node->type)) {
    return theme('availability_calendars_node', $node);
  }
  else {
    return FALSE;
  }
}

/**
* Availability calendars page
*/
function availability_calendars_page($nid = NULL, $year = NULL, $month = NULL, $edit = FALSE) {
  if (is_numeric($nid)) {
    $node = node_load($nid);
    drupal_set_title(t('Availability for %name', array('%name' => $node->title)));

    if (is_numeric($year) && is_numeric($month)) {
      drupal_set_title(t('Availability for %name in %date', array('%name' => $node->title, '%date' => date('M Y', strtotime("$year-$month-01")))));
      if ($edit == 'edit') {
        // Display the edit form for the availability calendar on the node
        return availability_calendars_node_edit($node, $year, $month);
      }
      else {
        // Display availability calendar for single month
        $monthstodisplay = 1;
        return theme('availability_calendars_node', $node, $year, $month, $monthstodisplay);
      }
    }
    elseif (is_numeric($year)) {
      // Display availability calendar for a whole year
      $month = 1;
      $monthstodisplay = 12;
      return theme('availability_calendars_node', $node, $year, $month, $monthstodisplay);
    }
    else {
      // Display rolling availability calendar from this point onwards
      $year = date('Y');
      $month = date('m');
      $monthstodisplay = variable_get('availability_display_monthcount', 12);
      return theme('availability_calendars_node', $node, $year, $month, $monthstodisplay);
    }
  }
  else {
    print drupal_not_found();
  }
}

function availability_calendars_node_edit() {
  return drupal_get_form('availability_calendars_node_edit_form');
}

function availability_calendars_node_edit_form() {
  $nid = check_plain(arg(1));
  $year = check_plain(arg(2));
  $month = check_plain(arg(3));
  $form['nid'] = array(
    '#type' => 'hidden',
    '#default_value' => $nid,
  );
  $form['year'] = array(
    '#type' => 'hidden',
    '#default_value' => $year,
  );
  $form['month'] = array(
    '#type' => 'hidden',
    '#default_value' => $month,
  );

  $startofweek = variable_get('availability_calendars_'. $nid .'_startofweek', 1);
  $month_meta = availability_calendars_month_meta($year, $month, $startofweek);

  // find all entries in database for this month ($availability, $notes) and pre-populate
  $notes_result = db_query('SELECT week, note FROM {availability_calendars_week} WHERE nid = %d AND year = %d and month = %d', $nid, $year, $month);
  while ($note = db_fetch_array($notes_result)) {
    $notes[$note['week']] = $note['note'];
  }

  $status_result = db_query('SELECT day, status FROM {availability_calendars_day} WHERE nid = %d AND year = %d AND month = %d', $nid, $year, $month);
  while ($status = db_fetch_array($status_result)) {
    $day_status[$status['day']] = $status['status'];
  }

  $day = 1;
  for ($week = 1; $week <= $month_meta['weeksinmonth']; $week++) {
    $form['week-'. $week] = array(
      '#type' => 'fieldset',
      '#title' => 'Week '. $week,
    );
    $form['week-'. $week]['note-'. $week] = array(
      '#type' => 'textfield',
      '#title' => 'Note',
      '#default_value' => $notes[$week],
      '#description' => 'This will be displayed beside the week in the calendar. It could include, for example, a weekly price.',
    );
    if ($week == 1) {
      $daysinweekremaining = 7 - $month_meta['firstday'];
    }
    else {
      $daysinweekremaining = 7;
    }
    while ($daysinweekremaining > 0 && $day <= $month_meta['daysinmonth']) {
      $form['week-'. $week]['day-'. $day] = array(
        '#type' => 'select',
        '#title' => date('l d F', strtotime("$year-$month-$day")),
        '#options' => availability_calendars_options(),
        '#default_value' => $day_status[$day]
      );
      $day++;
      $daysinweekremaining--;
    }
  }

  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Submit'),
  );

  return $form;
}

function availability_calendars_node_edit_form_submit($form, &$form_state) {
  $nid = check_plain($form_state['values']['nid']);
  $year = check_plain($form_state['values']['year']);
  $month = check_plain($form_state['values']['month']);

  // save weekly notes
  $week = 1;
  $nomoreweeks = FALSE;
  while (!$nomoreweeks) {
    if (isset($form_state['values']['note-'. $week])) {
      $notes[$week] = check_plain($form_state['values']['note-'. $week]);
      $week++;
    }
    else {
      $nomoreweeks = TRUE;
    }
  }

  // save $days
  $day = 1;
  $nomoredays = FALSE;
  while (!$nomoredays) {
    if (isset($form_state['values']['day-'. $day])) {
      $days[$day] = $form_state['values']['day-'. $day];
      $day++;
    }
    else {
      $nomoredays = TRUE;
    }
  }

  db_query('DELETE FROM {availability_calendars_week} WHERE nid = %d AND year = %d AND month = %d', $nid, $year, $month);
  foreach ($notes as $week => $note) {
    db_query('INSERT INTO {availability_calendars_week} (nid, year, month, week, note) VALUES (%d, %d, %d, %d, "%s")', $nid, $year, $month, $week, $note);
  }

  db_query('DELETE FROM {availability_calendars_day} WHERE nid = %d AND year = %d AND month = %d', $nid, $year, $month);
  foreach ($days as $day => $status) {
    db_query('INSERT INTO {availability_calendars_day} (nid, year, month, day, status) VALUES (%d, %d, %d, %d, %d)', $nid, $year, $month, $day, $status);
  }

  drupal_set_message('Availability information saved.');
}

/**
* Implementation of hook_theme().
*/
function availability_calendars_theme() {

  return array('availability_calendars_node' => array(
                 'arguments' => array('node' => NULL, 'year' => 2008, 'month' => 01, 'monthstodisplay' => 12)
       ),
       'availability_calendars_month' => array(
                 'arguments' => array('node' => NULL, 'year' => 2008, 'month' => 01, 'startofweek' => NULL, 'booked' => NULL)
       )
);

}
//function theme_availability_calendars_month($node, $year, $month, $startofweek, $booked) {

/**
* Themed output to display a lits of node dates.
*
* @param $node
* @return HTML output.
*/
function theme_availability_calendars_node($node, $year = 2008, $month = 01, $monthstodisplay = 12) {

  drupal_add_css(drupal_get_path('module', 'availability_calendars') .'/availability_calendars.css');
  $rows = array();

  // Fill availability array
  /* foreach ($node->availability_dates as $k => $v) {
    foreach ($v as $i) {
      $booked[date("Y", $i['date'])][date("m", $i['date'])][date("d", $i['date'])] = 1;
    }
  } */



  // Calendar code based on example at http://evolt.org/node/60673 :
  $day = 1;

  $startofweek = variable_get('availability_calendars_'. $node->nid .'_startofweek', 1);

  $monthsremaining = $monthstodisplay;
  while ($monthsremaining > 0) {
    $output .= theme('availability_calendars_month', $node, $year, $month, $startofweek, $booked);
    $monthsremaining--;
    $month++;
    if ($month > 12) {
      $month = 1;
      $year++;
    }
  }

  // add an extra three months for editors only
  if (user_access('edit availability calendars')) {
    $monthsremaining = 1;
    while ($monthsremaining > 0) {
      $output .= theme('availability_calendars_month', $node, $year, $month, $startofweek, $booked);
      $monthsremaining--;
      $month++;
      if ($month > 12) {
        $month = 1;
        $year++;
      }
    }
  }

  return $output;
 
}

function availability_calendars_month_meta($year, $month, $startofweek) {
  $month_meta['daysinmonth'] = date("t", mktime(0, 0, 0, $month, 1, $year));
  $month_meta['firstday'] = date("w", mktime(0, 0, 0, $month, 1, $year)) + $startofweek;
  $tempDays = $month_meta['firstday'] + $month_meta['daysinmonth']; // padding
  $month_meta['weeksinmonth'] = ceil($tempDays / 7);

  // Stop empty weeks occuring at start of month
  if ($month_meta['firstday'] > 6) {
    $month_meta['firstday'] = $month_meta['firstday'] - 7;
    $month_meta['weeksinmonth'] --; 
  }
  return $month_meta;
}

function theme_availability_calendars_month($node, $year, $month, $startofweek, $booked) {
global $user;
 
  $month_meta = availability_calendars_month_meta($year, $month, $startofweek);
 
  for ($j=0;$j<$month_meta['weeksinmonth'];$j++) {
    for ($i=0;$i<7;$i++) {
      $counter++;
      $week[$j][$i] = $counter;
      // offset the days
      $week[$j][$i] -= $month_meta['firstday'];
      if (($week[$j][$i] < 1) || ($week[$j][$i] > $month_meta['daysinmonth'])) {   
        $week[$j][$i] = "";
      }
    }
  }
 
  $output  = "<table class='cal'>\n";
  $output .= "<tr class='calmonth'>\n";
  $output .= "<th colspan='8'>". t("@date", array('@date' => format_date(mktime(12, 0, 0, $month, 1, $year), 'custom', 'F Y')));
  if ($user->uid != $node->uid && $user->uid != 1) {
    $output .= ' '. l('edit', 'availability-calendars/'. $node->nid .'/'. date('Y/m', mktime(0, 0, 0, $month, 1, $year)) .'/edit',
                      array('query' => 'destination=node/'. $node->nid));
  }
  $output .= "</th>\n";
  $output .= "</tr>\n";


 
/*  $days = array(
      6 => array("M", "Mon", "Monday"),
      5 => array("T", "Tue", "Tuesday"),
      4 => array("W", "Wed", "Wednesday"),
      3 => array("T", "Thu", "Thursday"),
      2 => array("F", "Fri", "Friday"),
      1 => array("S", "Sat", "Saturday"),
      0 => array("S", "Sun", "Sunday"),
    );

// Figure out how to generate the header - see archive.module in 4.7
  $output .= "<tr class='caldays'>\n";
  $output .= "<th></th>\n";
  $output .= "<th>S</th>\n";
  $output .= "<th>S</th>\n";
  $output .= "<th>M</th>\n";
  $output .= "<th>T</th>\n";
  $output .= "<th>W</th>\n";
  $output .= "<th>T</th>\n";
  $output .= "<th>F</th>\n";
  $output .= "</tr>\n";
*/

  // find all entries in database for this month ($availability, $notes) and pre-populate
  $notes_result = db_query('SELECT week, note FROM {availability_calendars_week} WHERE nid = %d AND year = %d AND month = %d', $node->nid, $year, $month);
  while ($note = db_fetch_array($notes_result)) {
    $notes[$note['week']] = $note['note'];
  }

  $status_result = db_query('SELECT day, status FROM {availability_calendars_day} WHERE nid = %d AND year = %d AND month = %d', $node->nid, $year, $month);
  while ($status = db_fetch_array($status_result)) {
    $day_status[$status['day']] = $status['status'];
  }

  $availability_calendars_options = availability_calendars_options();

  foreach ($week as $key => $val) {
    $weeknumber = $key + 1;

    $output .= "<tr class='calweek'>\n";
    $output .= "<td class='calnote'>". $notes[$weeknumber] ."</td>\n";
    for ($i=0; $i<7; $i++) {

      // if there's a date, it's part of this month
      if ($week[$key][$i]) {
        if ($day_status[$week[$key][$i]] == 1) {
        // booked
          $output .= " <td class='calnotavailable'>". $week[$key][$i] ."</td>\n";
        }
        elseif ($day_status[$week[$key][$i]] == 2) {
          // provisionally booked
          $output .= " <td class='calnotavailableprov'>". $week[$key][$i] ."</td>\n";
        }
        else {
          // available
          $output .= " <td class='calavailable'>". $week[$key][$i] ."</td>\n";
        }
      }
      else {
        $output .= " <td class='calothermonth'>". $number ."</td>\n";
      }
    }

  $output .= "</tr>\n";

  }

  if ($weeknumber == 5) {
    $output .= "<tr>\n";
    $output .= "<td colspan='8'>&nbsp;</td>\n";
    $output .= "</tr>\n";
  }

  $output .= "</table>";

  return $output;
}

function availability_calendars_options() {
  // TODO: make these configurable
  return array(
    0 => t('Available'),
    1 => t('Fully booked'),
    2 => t('Provisionally booked')
  );
}

/**
* Implementation of hook_form_alter();
*/
function availability_calendars_form_alter(&$form, &$form_state, $form_id) {
  global $user;

  // Alter node type form to allow availability support to be enabled/disabled
  if ($form_id == 'node_type_form') {
    $form['availability_calendars'] = array(
      '#type' => 'fieldset',
      '#title' => t('Availability calendars'),
      '#collapsible' => TRUE,
      '#collapsed' => !variable_get('availability_calendars_'. $form['#node_type']->type, 0),
    );
    $form['availability_calendars']['availability_calendars'] = array(
      '#type' => 'radios',
      '#title' => t('Availability calendar support'),
      '#default_value' => variable_get('availability_calendars_'. $form['#node_type']->type, 0),
      '#options' => array(
        0 => t('Disabled'),
        1 => t('Enabled')
      ),
      '#description' => t('Enable or disable availability support for this content type. If enabled, node owner will be able to specify node availability.'),
    );
  }

  // Alter node edit form if availability support is enabled for that content type
  elseif (isset($form['type']) && $form['type']['#value'] .'_node_form' == $form_id &&
      availability_calendars_enabled($form['type']['#value'])) {

    $form['availability_calendars'] = array(
      '#type' => 'fieldset',
      '#title' => t('Availability calendar settings'),
    );
    $form['availability_calendars']['startofweek'] = array(
      '#type' => 'select',
      '#title' => t('First day of week'),
      '#default_value' => variable_get('availability_calendars_'. $form['nid']['#value'] .'_startofweek', 1),
      '#options' => array(
        6 => t('Monday'),
        5 => t('Tuesday'),
        4 => t('Wednesday'),
        3 => t('Thursday'),
        2 => t('Friday'),
        1 => t('Saturday'),
        0 => t('Sunday'),
      ),
    );

  }
}

/**
* Implementation hook node_nodeapi();
*/
function availability_calendars_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
  global $user;

  if (!availability_calendars_enabled($node->type)) return;

  switch ($op) {
    case 'view':
      if (variable_get('availability_calendars_display_nodeview', TRUE)) {
        $year = date('Y');
        $month = date('m');
        $monthstodisplay = variable_get('availability_calendars_display_monthcount', 12);
        $calendar_node = $node;
        if ($node->tnid) {
          // if Content Translation module is enabled and this is a translated node, use calendar of original node
          if ($node->tnid != $node->nid) {
            $calendar_node = node_load($node->tnid);
          }
        }
        $node->content['availability_calendars'] = array(
          '#value' => theme('availability_calendars_node', $calendar_node, $year, $month, $monthstodisplay),
          '#weight' => 10,
        );
      }
      break;
    case 'insert':
    case 'update':
      availability_calendars_save($node);
      break;
    case 'delete':
      break;
  }
}

/**
* Saves a set of dates associated with the node after editing it.
*
* @param object $node Node information to save into the database.
*/
function availability_calendars_save(&$node) {
  variable_set('availability_calendars_'. $node->nid .'_startofweek', $node->startofweek);
}

/**
* Checks if availability is enabled for specified content type.
*
* @param string $node_type
*/
function availability_calendars_enabled($node_type) {
  return variable_get('availability_calendars_'. $node_type, 0);
}

If someone could fix this problem you'd be doing me a huge favour
thanks

*** I have no time to do a

mm167 - April 5, 2009 - 10:09

*** I have no time to do a full test, so,....At Your Own Risk. ***

in availability_calendars.module, theme function ...

1. add global $user

function theme_availability_calendars_month($node, $year, $month, $startofweek, $booked) {
  global $user; 

2. replace the user access checking as follows:

//  if (user_access('edit availability calendars')) {
  if (user_access('edit own availability calendars') && ($user->uid == $node->uid)) {

We go the drupal way. How about you?
http://www.drupalway.com

That's it !

stijnparidaens - April 6, 2009 - 12:11

That's it ! thanks mm167 !

When you now grant everyone permission edit calendars AND edit own calendars the logged in user can only edit his own calendar.

Thanks, you're a lifesaver !

 
 

Drupal is a registered trademark of Dries Buytaert.