Zarafa Alert Script : Recurrent Meeting

From Zarafa wiki

Revision as of 14:32, 27 October 2010 by Zkaat (Talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search
  1. !/usr/bin/php

<? /**

* This script can be used to fix all recurring items in Calendar which fall between 25oct to 31oct
* When calling from command line you have to pass usernames in space separated list to the script,
* if you want to fix recurring items for all users then pass "-a" as argument to the script
* 
* Usage:
* 		for selected users
* 				php fix_recurring_items.php -u <username1> <username2> ...
* 		for all users
* 				php fix_recurring_items.php -a
*/

// comment this line for debugging error_reporting(0);

// mapi include files include('/usr/share/php/mapi/mapi.util.php'); include('/usr/share/php/mapi/mapidefs.php'); include('/usr/share/php/mapi/mapicode.php'); include('/usr/share/php/mapi/mapitags.php'); include('/usr/share/php/mapi/mapiguid.php'); include('/usr/share/php/mapi/class.recurrence.php');

// config options $ADMINUSERNAME = "SYSTEM"; $ADMINPASSWORD = ""; $SERVER = "file:///var/run/zarafa"; $USAGEMESSAGE = "Usage:\n\tfor selected users \n\t\tphp fix_recurring_items.php -u <username1> <username2> ...\n\tfor all users \n\t\tphp fix_recurring_items.php -a\n";


// properties $proptags = Array(); $proptags["entryid"] = PR_ENTRYID; $proptags["subject"] = PR_SUBJECT; $proptags["meetingstatus"] = "PT_LONG:PSETID_Appointment:0x8217"; $proptags["commonstart"] = "PT_SYSTIME:PSETID_Common:0x8516"; $proptags["commonend"] = "PT_SYSTIME:PSETID_Common:0x8517"; $proptags["recurring"] = "PT_BOOLEAN:PSETID_Appointment:0x8223"; $proptags["timezone_data"] = "PT_BINARY:PSETID_Appointment:0x8233"; $proptags["clipstart"] = "PT_SYSTIME:PSETID_Appointment:0x8235"; $proptags["clipend"] = "PT_SYSTIME:PSETID_Appointment:0x8236"; $proptags["startrecurdate"] = "PT_LONG:PSETID_Meeting:0xD"; $proptags["startrecurtime"] = "PT_LONG:PSETID_Meeting:0xE"; $proptags["endrecurdate"] = "PT_LONG:PSETID_Meeting:0xF"; $proptags["endrecurtime"] = "PT_LONG:PSETID_Meeting:0x10";

if($argc < 2) { exit($USAGEMESSAGE); }

// use SYSTEM account for login $session = mapi_logon_zarafa($ADMINUSERNAME, $ADMINPASSWORD, $SERVER); if(!$session) { exit("Can't login into zarafa server\n"); }

// get all stores of SYSTEM account $msgStoresTable = mapi_getmsgstorestable($session); $msgStores = mapi_table_queryallrows($msgStoresTable, array(PR_DEFAULT_STORE, PR_ENTRYID));

// get default store foreach ($msgStores as $row) { if($row[PR_DEFAULT_STORE]) { $storeEntryid = $row[PR_ENTRYID]; } }

if(!$storeEntryid) { exit("Can't find default store\n"); }

// open default store $store = mapi_openmsgstore($session, $storeEntryid); if(!$store) { exit("Unable to open system store\n"); }

// set named properties $GLOBALS['proptags'] = getPropIdsFromStrings($store, $proptags);

if(strcasecmp($argv[1], "-a") == 0) { // get all zarafa users and remove property data $userList = array();

// for multi company setup $companyList = mapi_zarafa_getcompanylist($store); if(mapi_last_hresult() == NOERROR && is_array($companyList)) { // multi company setup, get all users from all companies foreach($companyList as $companyName => $companyData) { $userList = array_merge($userList, mapi_zarafa_getuserlist($store, $companyData["companyid"])); } } else { // single company setup, get list of all zarafa users $userList = mapi_zarafa_getuserlist($store); }

if(count($userList) <= 0) { exit("Unable to get user list\n"); }

foreach($userList as $userName => $userData) { // check for valid users if($userName == "SYSTEM") { continue; }

print "Searching recurring items for user - ". $userName . "\n\n";

$result = findRecurringItems($session, $store, $userName);

if($result) { print $result ." recurring item are fixed for user - " . $userName . "\n\n"; } else { print "No defective recurring items found for user - " . $userName . "\n\n"; } } } else if(strcasecmp($argv[1], "-u") == 0) { // only clear properties for selected users if($argc == 2) { exit("No user specified\n\n" . $USAGEMESSAGE); }

for($index = 2; $index < $argc; $index++) { // start with argv[2] print "Searching recurring items for user - ". $argv[$index] . "\n\n";

$result = findRecurringItems($session, $store, $argv[$index]); if($result) { print $result ." recurring item are fixed for user - " . $argv[$index] . "\n\n"; } else { print "No defective recurring items found for user - " . $argv[$index] . "\n\n"; } } } else { exit("Unknown option specified\n\n" . $USAGEMESSAGE); }


/**************** Internal Functions ******************/

/**

* findRecurringItems
*
* Finds recurring items between 25 Oct to 31 Oct for specified username and store
* @param session mapi session
* @param resource store mapi store of given username
* @param string userName username of user to search for.
* @returns boolean/number false if no recurring item is fixed else no. of recurring items fixed
*/

function findRecurringItems($session, $store, $userName) { $result = false; $itemCount = 0;

// create entryid of user's store $userStoreEntryId = mapi_msgstore_createentryid($store, $userName); if(!$userStoreEntryId) { print "\tError in creating entryid for user's store - " . $userName . "\n"; return false; }

// open user's store $userStore = mapi_openmsgstore($session, $userStoreEntryId); if(!$userStore) { print "\tError in opening user's store - " . $userName . "\n"; return false; }

// get user's root store $userRootStore = mapi_msgstore_openentry($userStore, null); $userRootStoreProps = mapi_getprops($userRootStore, array(PR_IPM_APPOINTMENT_ENTRYID));

// Open the user's calendar Folder $userCalendar = mapi_msgstore_openentry($userStore, $userRootStoreProps[PR_IPM_APPOINTMENT_ENTRYID]);

// get rows $calContentTable = mapi_folder_getcontentstable($userCalendar);

// Restriction to find all recurrings items $res = Array(RES_AND, Array( Array(RES_PROPERTY, Array(RELOP => RELOP_EQ, ULPROPTAG => $GLOBALS['proptags']['recurring'], VALUE => true // Item should be recurring ) ), Array(RES_PROPERTY, Array(RELOP => RELOP_GE, ULPROPTAG => $GLOBALS['proptags']['commonstart'], VALUE => gmmktime(0, 0, 0, 10, 25, 2010) ) ), Array(RES_PROPERTY, Array(RELOP => RELOP_LE, ULPROPTAG => $GLOBALS['proptags']['commonstart'], VALUE => gmmktime(0, 0, 0, 11, 1, 2010) ) ) ) );

$rows = mapi_table_queryallrows($calContentTable, $GLOBALS['proptags'], $res);

// Now loop through each recurring item and find which one is falling in 25 - 31 OCT daterange. foreach ($rows as $row) { $result = processRecurringItem($userStore, $row); if ($result) $itemCount++; }

return $itemCount ? $itemCount : $result; }


/**

* processRecurringItem
*
* Checks if given message is broken, if broken then fixes borken properties on message as well as in recurrence blob
* @param resource store mapi store of given username
* @param array itemProps message properties of recurring item
* @return boolean returns true if found broken and fixed else false.
*/

function processRecurringItem($userStore, $itemProps) { print "\tProcessing item - '". $itemProps[PR_SUBJECT] ."' \n"; // Open message $message = mapi_msgstore_openentry($userStore, $itemProps[PR_ENTRYID]);

$recurr = new Recurrence($userStore, $message); $tz = $recurr->parseTimezone($itemProps[$GLOBALS['proptags']['timezone_data']]);

// Calculate 'ClipStart' based on 'CommonStart' $localCommonStart = $recurr->fromGMT($tz, $itemProps[$GLOBALS['proptags']['commonstart']]); //Get commonStart in LOCAL time $clipStart = $recurr->dayStartOf($localCommonStart); //Get start of day of localtime $clipStart = $recurr->toGMT($tz, $clipStart); //Convert back to GMT time


if ($clipStart != $itemProps[$GLOBALS['proptags']['clipstart']]) { print "\t\tRecurring item - '". $itemProps[PR_SUBJECT] ."' found broken.\n\t\tFixing - '". $itemProps[PR_SUBJECT] ."'\n"; //This recurring item is broken

$props = Array(); $props[$GLOBALS['proptags']['clipstart']] = $clipStart;

// Calculate 'StartRecurDate' and 'StartRecurTime' $gmStartDate = $recurr->gmtime($localCommonStart); $props[$GLOBALS['proptags']['startrecurdate']] = ((intval($gmStartDate['tm_year'], 10)+1900) * 512) + ((intval($gmStartDate['tm_mon'], 10)+1) * 32) + intval($gmStartDate['tm_mday'], 10); $props[$GLOBALS['proptags']['startrecurtime']] = (intval($gmStartDate['tm_hour'], 10) * 4096) + (intval($gmStartDate['tm_min'], 10) * 64) + intval($gmStartDate['tm_sec'], 10);

// Calculate 'EndRecurDate' and 'EndRecurTime' $localCommonEnd = $recurr->fromGMT($tz, $itemProps[$GLOBALS['proptags']['commonend']]); $gmEndDate = $recurr->gmtime($localCommonEnd); $props[$GLOBALS['proptags']['endrecurdate']] = ((intval($gmEndDate['tm_year'], 10)+1900) * 512) + ((intval($gmEndDate['tm_mon'], 10)+1) * 32) + intval($gmEndDate['tm_mday'], 10); $props[$GLOBALS['proptags']['endrecurtime']] = (intval($gmEndDate['tm_hour'], 10) * 4096) + (intval($gmEndDate['tm_min'], 10) * 64) + intval($gmEndDate['tm_sec'], 10);

// Calculate Duration $duration = $localCommonEnd - $localCommonStart;

// Fix 'StartOcc' and 'EndOcc' in recurrence blob $recurr->recur['startocc'] = ($gmStartDate['tm_hour'] * 60) + ($gmStartDate['tm_min']); $recurr->recur['endocc'] = $recurr->recur['startocc'] + ($duration / 60);

// Save recurrence $recurr->saveRecurrence();

// Calculate 'ClipEnd' with the help of 'RecurEnd' and 'EndOcc' from recurr blob. if ($recurr->recur['term'] != 0x23) { // Do nothing if recurrence doesn' end $clipEnd = $recurr->recur['end'] + ($recurr->recur['endocc'] * 60); $clipEnd = $recurr->fromGMT($tz, $clipEnd); $clipEnd = $recurr->dayStartOf($clipEnd); $clipEnd = $recurr->toGMT($tz, $clipEnd);

$props[$GLOBALS['proptags']['clipend']] = $clipEnd; }

// Commit changes mapi_setprops($message, $props); mapi_savechanges($message);

print "\t\tRecurring item - '". $itemProps[PR_SUBJECT] ."' is now fixed.\n";

return true; }

print "\t\tRecurring item - '". $itemProps[PR_SUBJECT] ."' seems good do not need any processing.\n"; print "\n"; return false; } ?>

Personal tools