From 145cf9ce685794e2380b6e1613387a508c7ad87a Mon Sep 17 00:00:00 2001 From: Ralf Becker Date: Fri, 27 May 2011 20:32:46 +0000 Subject: [PATCH] New method to display meeting-requests for fmail and allow to (tentativ) accept or reject them --- calendar/inc/class.calendar_bo.inc.php | 8 +- calendar/inc/class.calendar_boupdate.inc.php | 71 ++++++----- calendar/inc/class.calendar_uiforms.inc.php | 117 +++++++++++++++++++ calendar/lang/egw_de.lang | 7 ++ calendar/lang/egw_en.lang | 7 ++ calendar/setup/etemplates.inc.php | 31 ++++- 6 files changed, 211 insertions(+), 30 deletions(-) diff --git a/calendar/inc/class.calendar_bo.inc.php b/calendar/inc/class.calendar_bo.inc.php index 71e2dc5e2c..cd38c61b93 100644 --- a/calendar/inc/class.calendar_bo.inc.php +++ b/calendar/inc/class.calendar_bo.inc.php @@ -1417,11 +1417,13 @@ class calendar_bo * * @param string|int $id id of user or resource * @param string|boolean $use_type=false type-letter or false + * @param boolean $append_email=false append email (Name ) * @return string with name */ - function participant_name($id,$use_type=false) + function participant_name($id,$use_type=false, $append_email=false) { static $id2lid = array(); + static $id2email = array(); if ($use_type && $use_type != 'u') $id = $use_type.$id; @@ -1433,14 +1435,16 @@ class calendar_bo if (($info = $this->resource_info($id))) { $id2lid[$id] = $info['name'] ? $info['name'] : $info['email']; + if ($info['name']) $id2email[$id] = $info['email']; } } else { $id2lid[$id] = common::grab_owner_name($id); + $id2email[$id] = $GLOBALS['egw']->accounts->id2name($id,'account_email'); } } - return $id2lid[$id]; + return $id2lid[$id].($append_email && $id2email[$id] ? ' <'.$id2email[$id].'>' : ''); } /** diff --git a/calendar/inc/class.calendar_boupdate.inc.php b/calendar/inc/class.calendar_boupdate.inc.php index 0eecc2ba6b..d983108223 100644 --- a/calendar/inc/class.calendar_boupdate.inc.php +++ b/calendar/inc/class.calendar_boupdate.inc.php @@ -683,8 +683,15 @@ class calendar_boupdate extends calendar_bo if ($old_event != False) $olddate = new egw_time($old_event['start']); foreach($to_notify as $userid => $statusid) { - if ($this->debug > 0) error_log(__METHOD__." trying to notify $userid, with $statusid"); - if (!is_numeric($userid)) + calendar_so::split_status($statusid, $quantity, $role); + if ($this->debug > 0) error_log(__METHOD__." trying to notify $userid, with $statusid ($role)"); + + if (!is_numeric($userid) && $userid[0] == 'e') + { + if ($role != 'CHAIR' || $msg_type == MSG_ALARM) continue; // only notify "external" chairs, but not for alarms + $userid = substr($userid,1); + } + elseif (!is_numeric($userid)) { $res_info = $this->resource_info($userid); $userid = $res_info['responsible']; @@ -701,16 +708,24 @@ class calendar_boupdate extends calendar_bo $user_prefs['calendar']['receive_own_updates']==1) || $msg_type == MSG_ALARM) { - $preferences = CreateObject('phpgwapi.preferences',$userid); - $part_prefs = $preferences->read_repository(); - - if (!$this->update_requested($userid,$part_prefs,$msg_type,$old_event,$new_event)) + if (is_numeric($userid)) { - continue; - } - $GLOBALS['egw']->accounts->get_account_name($userid,$lid,$details['to-firstname'],$details['to-lastname']); - $details['to-fullname'] = $GLOBALS['egw']->common->display_fullname('',$details['to-firstname'],$details['to-lastname']); + $preferences = CreateObject('phpgwapi.preferences',$userid); + $part_prefs = $preferences->read_repository(); + if (!$this->update_requested($userid,$part_prefs,$msg_type,$old_event,$new_event)) + { + continue; + } + $GLOBALS['egw']->accounts->get_account_name($userid,$lid,$details['to-firstname'],$details['to-lastname']); + $details['to-fullname'] = common::display_fullname('',$details['to-firstname'],$details['to-lastname']); + } + else // external email address: use current users preferences, plus some hardcoded settings (eg. ical notification) + { + $details['to-fullname'] = $userid; + $part_prefs = $GLOBALS['egw_info']['user']['preferences']; + $part_prefs['calendar']['update_format'] = 'ical'; // use ical format + } // event is in user-time of current user, now we need to calculate the tz-difference to the notified user and take it into account if (!isset($part_prefs['common']['tz'])) $part_prefs['common']['tz'] = $GLOBALS['egw_info']['server']['server_timezone']; $timezone = new DateTimeZone($part_prefs['common']['tz']); @@ -746,27 +761,26 @@ class calendar_boupdate extends calendar_bo switch($part_prefs['calendar']['update_format']) { case 'ical': - if ($method == 'REQUEST') + if (is_null($ics)) { - if (is_null($ics)) - { - $calendar_ical = new calendar_ical(); - $calendar_ical->setSupportedFields('full'); // full iCal fields+event TZ - $ics = $calendar_ical->exportVCal($event['id'],'2.0',$method); - unset($calendar_ical); - } - $attachment = array( 'string' => $ics, - 'filename' => 'cal.ics', - 'encoding' => '8bit', - 'type' => 'text/calendar; method='.$method, - ); + $calendar_ical = new calendar_ical(); + $calendar_ical->setSupportedFields('full'); // full iCal fields+event TZ + $ics = $calendar_ical->exportVCal(array($event),'2.0',$method); + unset($calendar_ical); } + $attachment = array( + 'string' => $ics, + 'filename' => 'cal.ics', + 'encoding' => '8bit', + 'type' => 'text/calendar; method='.$method, + ); // fall through case 'extended': $body .= "\n\n".lang('Event Details follow').":\n"; foreach($event_arr as $key => $val) { - if(strlen($details[$key])) { + if(!empty($details[$key])) + { switch($key){ case 'access': case 'priority': @@ -781,7 +795,8 @@ class calendar_boupdate extends calendar_bo break; } // send via notification_app - if($GLOBALS['egw_info']['apps']['notifications']['enabled']) { + if($GLOBALS['egw_info']['apps']['notifications']['enabled']) + { try { $notification = new notifications(); $notification->set_receivers(array($userid)); @@ -796,7 +811,9 @@ class calendar_boupdate extends calendar_bo error_log(__METHOD__.' error while notifying user '.$userid.':'.$exception->getMessage()); continue; } - } else { + } + else + { error_log(__METHOD__.' cannot send any notifications because notifications is not installed'); } } @@ -1482,7 +1499,7 @@ class calendar_boupdate extends calendar_bo echo "

error opening '$this->log_file' !!!

\n"; return false; } - fwrite($f,$type.': '.$GLOBALS['egw']->common->grab_owner_name($this->user).': '.date('r')."\n"); + fwrite($f,$type.': '.common::grab_owner_name($this->user).': '.date('r')."\n"); fwrite($f,"Time: time to save / saved time read back / old time before save\n"); foreach(array('start','end') as $name) { diff --git a/calendar/inc/class.calendar_uiforms.inc.php b/calendar/inc/class.calendar_uiforms.inc.php index 1082309d77..fae9c559a1 100644 --- a/calendar/inc/class.calendar_uiforms.inc.php +++ b/calendar/inc/class.calendar_uiforms.inc.php @@ -31,6 +31,7 @@ class calendar_uiforms extends calendar_ui 'export' => true, 'import' => true, 'cat_acl' => true, + 'meeting' => true, ); /** @@ -1569,6 +1570,122 @@ function replace_eTemplate_onsubmit() return $response->getXML(); } + /** + * Display a meeting request (iCal) for FMail and allow to accept, tentative or reject it + * + * @todo Handle situation when user is NOT invited, but eg. can view that mail ... + * @param array $event=null + * @param string $msg='' + */ + function meeting(array $event=null, $msg='') + { + $user = $GLOBALS['egw_info']['user']['account_id']; + + if (!is_array($event)) + { + $ical_string = $_GET['ical'] == 'session' ? egw_cache::getSession('calendar', 'ical') : $_GET['ical']; + $ical = new calendar_ical(); + if (!($events = $ical->icaltoegw($ical_string, '', 'utf-8')) || count($events) != 1) + { + error_log(__METHOD__."('$_GET[ical]') error parsing iCal!"); + $GLOBALS['egw']->framework->render(html::fieldset('
'.htmlspecialchars($ical_string).'
', + lang('Error: importing the iCal'))); + return; + } + $event = array_shift($events); + if (($existing_event = $this->bo->read($event['uid'])) && !$existing_event['deleted']) + { + $event = $existing_event; + foreach((array)$event['participants'] as $uid => $status) + { + calendar_so::split_status($status, $quantity, $role); + if ($role == 'CHAIR') + { + $event['organizer'] = $this->bo->participant_name($uid,false,true); + break; + } + } + if (empty($event['organizer'])) + { + $event['organizer'] = $this->bo->participant_name($event['owner'],false,true); + } + $msg = lang('Using already existing event on server.'); + } + else + { + $event['participant_types'] = array(); + foreach($event['participants'] as $uid => $status) + { + calendar_so::split_user($uid, $user_type, $user_id); + $event['participant_types'][$user_type][$user_id] = $status; + } + } + //error_log(__METHOD__."(...) parsed as ".array2string($event)); + $event['recure'] = $this->bo->recure2string($event); + $event['all_participants'] = implode(",\n",$this->bo->participants($event, true)); + + if (!isset($event['participants'][$user])) + { + $msg .= ($msg ? "\n" : '').lang('You are not invited to that event!'); + if ($event['id']) + { + $readonlys['button[accept]'] = $readonlys['button[tentativ]'] = $readonlys['button[reject]'] = true; + } + } + // ignore events in the past + if ($this->bo->date2ts($event['start']) < $this->bo->now_su) + { + $msg = lang('Requested meeting is in the past!'); + $readonlys['button[accept]'] = $readonlys['button[tentativ]'] = $readonlys['button[reject]'] = true; + } + } + else + { + //_debug_array($event); + list($button) = each($event['button']); + unset($event['button']); + + switch($button) + { + case 'reject': + if (!$event['id']) + { + // send reply to organizer + $this->bo->send_update(MSG_REJECTED,array('e'.$event['organizer'] => 'DCHAIR'),$event); + break; // no need to store rejected event + } + // fall-through + case 'accept': + case 'tentativ': + $status = strtoupper($button[0]); // A, R or T + if (!$event['id']) + { + // store event without notifications! + if (($event['id'] = $this->bo->update($event, $ignore_conflicts=true, true, false, true, $msg, true))) + { + $msg = lang('Event saved'); + } + else + { + $msg = lang('Error: saving the event !!!'); + break; + } + } + // set status and send notification / meeting response + if ($this->bo->set_status($event, $user, $status)) + { + if (!$msg) $msg = lang('Status changed'); + } + break; + } + } + $event['msg'] = $msg; + $readonlys['button[edit]'] = !$event['id']; + + $tpl = new etemplate('calendar.meeting'); + $tpl->exec('calendar.calendar_uiforms.meeting', $event, $sel_options, $readonlys, $event, 2); + } + /** * displays a sheduling conflict * diff --git a/calendar/lang/egw_de.lang b/calendar/lang/egw_de.lang index afde294a77..2567b68e72 100644 --- a/calendar/lang/egw_de.lang +++ b/calendar/lang/egw_de.lang @@ -10,6 +10,7 @@ , stati of participants reset calendar de , Status der Teilnehmer zurückgesetzt please note: the calendar use the holidays of your country, which is set to %1. you can change it in your %2.
holidays are %3 automatic installed from %4. you can changed it in %5. calendar de Bitte beachten: Der Kalender verwendet die Feiertages des Landes, welches auf %1 eingestellt ist. Das können Sie in Ihren %2 ändern.
Feiertage werden %3 automatisch von %4 installiert, was in %5 änderbar ist. a non blocking event will not conflict with other events calendar de Ein nicht blockierender Termin ergibt keine Konflikt mit anderen Terminen +accept calendar de Zusagen accept or reject an invitation calendar de Einladung zu- oder absagen accepted calendar de Zugesagt access denied to the calendar of %1 !!! calendar de Zugriff zum Kalender von %1 verweigert !!! @@ -290,6 +291,7 @@ make freebusy information available to not loged in persons? calendar de Die Bel manage mapping calendar de Feldzuordnung bearbeiten max. number of entries to show (leave empty for no restriction) calendar de Max. Anzahl von Einträgen die angezeigt werden sollen (Kein Eintrag = Keine Beschränkung) maximum available quantity of %1 exceeded! calendar de Maximale Anzahl von %1 erreicht! +meeting request calendar de Termineinladung merge document... calendar de Dokument einfügen... minutes calendar de Minuten modified calendar de Geändert @@ -369,6 +371,7 @@ recover calendar de Wiederherstellen recovered calendar de wieder hergestellt recurrence calendar de Wiederholung recurring event calendar de Wiederholender Termin +reject calendar de Absagen rejected calendar de Abgesagt repeat days calendar de Wiederholungstage repeat the event until which date (empty means unlimited) calendar de Bis zu welchen Datum soll der Termin wiederholt werden (leer bedeutet unbegrenzt) @@ -379,6 +382,7 @@ repetition calendar de Wiederholung repetitiondetails (or empty) calendar de Details der Wiederholung (oder leer) replacements for inserting events into documents calendar de Platzhalter für das Einfügen von Terminen in Dokumente requested calendar de Erforderlich +requested meeting is in the past! calendar de Termin, zu dem eingeladen wird, ist in der Vergangenheit! require an acl grant to invite other users and groups admin de Freigabe um andere Benutzer oder Gruppen einzuladen erforderlich reset calendar de Zurücksetzen reset participant stati on event shifts calendar de Rücksetzen des Teilnehmerstatus beim Verschieben von Terminen @@ -466,6 +470,7 @@ this entry is currently opened by %1! calendar de Dieser Termin ist im Moment vo this entry is opened by user: calendar de Dieser Eintrag ist von einem anderen Benutzer innerhalb des konfigurierten Zeitintervalls geöffnet worden: this event is part of a series calendar de Dieser Termin ist Teil einer Serie this group that is preselected when you enter the planner. you can change it in the planner anytime you want. calendar de Diese Gruppe wird als Vorauswahl ausgewählt wenn Sie den Planer öffnen. Sie können die Gruppe jederzeit wechseln wenn Sie möchten. +this mail contains a meeting request calendar de Diese Nachricht enthält eine Termineinladung this message is sent for canceled or deleted events. calendar de Diese Benachrichtigung wird für stornierte oder gelöschte Termine versendet. this message is sent for modified or moved events. calendar de Diese Benachrichtigung wird für geänderte Termine versendet. this message is sent to disinvited participants. calendar de Diese Nachricht wird ausgeladenen Teilnehmern gesendet. @@ -509,6 +514,7 @@ use weekday start calendar de Benutzer Start der Arbeitswoche user or group calendar de Benutzer oder Gruppe user selectable css file for the calendar setup calendar de Benutzer können ausgwählte CSS Dateien aus dem Kalender Setup benutzen users + groups: inviting both allways requires an invite grant admin de Benutzer + Gruppen: Einladungen beider brauchen eine Freigabe +using already existing event on server. calendar de Benutze bereits existierenden Termin auf dem Server. view exception calendar de Ausnahme anzeigen view series calendar de Terminserie anzeigen view this event calendar de Diesen Termin anzeigen @@ -542,6 +548,7 @@ yearview calendar de Jahresansicht yes, only admins can purge deleted items admin de Ja, nur Administratoren können gelöschte Einträge bereinigen yes, users can purge their deleted items admin de Ja, Benutzer können gelöschte Einträge selbst bereinigen you are not allowed to book the resource selected: calendar de Sie sind nicht berechtigt die ausgewählte Ressource zu buchen. +you are not invited to that event! calendar de Sie sind zu diesem Termin nicht eingeladen! you can either set a year or a occurence, not both !!! calendar de Sie können nur entweder das Jahr oder die Wiederholung angeben, nicht beides! you can only set a year or a occurence !!! calendar de Sie können nur ein Jahr oder eine Wiederholung angeben ! you do not have permission to read this record! calendar de Sie haben keine Berechtigung diesen Eintrag zu lesen! diff --git a/calendar/lang/egw_en.lang b/calendar/lang/egw_en.lang index 7fe1924678..519b723259 100644 --- a/calendar/lang/egw_en.lang +++ b/calendar/lang/egw_en.lang @@ -10,6 +10,7 @@ , stati of participants reset calendar en , status of participants reset please note: the calendar use the holidays of your country, which is set to %1. you can change it in your %2.
holidays are %3 automatic installed from %4. you can changed it in %5. calendar en Please note: The calendar use the holidays of your country, which is set to %1. You can change it in your %2.
Holidays are %3 automatic installed from %4. You can change it in %5. a non blocking event will not conflict with other events calendar en A non blocking event will not conflict with other events +accept calendar en Accept accept or reject an invitation calendar en Accept or reject an invitation accepted calendar en Accepted access denied to the calendar of %1 !!! calendar en Access denied to the calendar of %1 !!! @@ -290,6 +291,7 @@ make freebusy information available to not loged in persons? calendar en Make Fr manage mapping calendar en Manage mapping max. number of entries to show (leave empty for no restriction) calendar en Max. Number of entries to show (leave empty for no restriction) maximum available quantity of %1 exceeded! calendar en Maximum available quantity of %1 exceeded! +meeting request calendar en Meeting request merge document... calendar en merge document... minutes calendar en Minutes modified calendar en Modified @@ -369,6 +371,7 @@ recover calendar en Recover recovered calendar en recovered recurrence calendar en Recurrence recurring event calendar en Recurring event +reject calendar en Reject rejected calendar en Rejected repeat days calendar en Repeat days repeat the event until which date (empty means unlimited) calendar en Repeat the event until which date (empty means unlimited) @@ -379,6 +382,7 @@ repetition calendar en Repetition repetitiondetails (or empty) calendar en Repetition details (or empty) replacements for inserting events into documents calendar en Replacements for inserting events into documents requested calendar en Requested +requested meeting is in the past! calendar en Requested meeting is in the past! require an acl grant to invite other users and groups admin en Require an ACL grant to invite other users and groups reset calendar en Reset reset participant stati on event shifts calendar en Reset participant status on event shifts @@ -466,6 +470,7 @@ this entry is currently opened by %1! calendar en This entry is currently opened this entry is opened by user: calendar en This entry was opened within the configured time interval by user: this event is part of a series calendar en This event is part of a series this group that is preselected when you enter the planner. you can change it in the planner anytime you want. calendar en This group that is preselected when you enter the planner. You can change it in the planner anytime you want. +this mail contains a meeting request calendar en This mail contains a meeting request this message is sent for canceled or deleted events. calendar en This message is sent for canceled or deleted events. this message is sent for modified or moved events. calendar en This message is sent for modified or moved events. this message is sent to disinvited participants. calendar en This message is sent to disinvited participants. @@ -509,6 +514,7 @@ use weekday start calendar en Use weekday start user or group calendar en User or group user selectable css file for the calendar setup calendar en User selectable CSS file for the calendar setup users + groups: inviting both allways requires an invite grant admin en Users + groups: inviting both always requires an invite grant +using already existing event on server. calendar en Using already existing event on server. view exception calendar en View exception view series calendar en View series view this event calendar en View this event @@ -542,6 +548,7 @@ yearview calendar en Year view yes, only admins can purge deleted items admin en Yes, only admins can purge deleted items yes, users can purge their deleted items admin en Yes, users can purge their deleted items you are not allowed to book the resource selected: calendar en You are not allowed to book the resource selected: +you are not invited to that event! calendar en You are not invited to that event! you can either set a year or a occurence, not both !!! calendar en You can either set a Year or a Occurrence, not both !!! you can only set a year or a occurence !!! calendar en You can only set a year or a occurrence !!! you do not have permission to read this record! calendar en You do not have permission to read this record! diff --git a/calendar/setup/etemplates.inc.php b/calendar/setup/etemplates.inc.php index c2a8492d30..b5a9a3778f 100644 --- a/calendar/setup/etemplates.inc.php +++ b/calendar/setup/etemplates.inc.php @@ -2,7 +2,7 @@ /** * EGroupware - eTemplates for Application calendar * http://www.egroupware.org - * generated by soetemplate::dump4setup() 2011-05-24 13:56 + * generated by soetemplate::dump4setup() 2011-05-27 22:30 * * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License * @package calendar @@ -69,9 +69,38 @@ $templ_data[] = array('name' => 'calendar.list.dates','template' => '','lang' => $templ_data[] = array('name' => 'calendar.list.rows','template' => '','lang' => '','group' => '0','version' => '1.9.004','data' => 'a:1:{i:0;a:6:{s:4:"type";s:4:"grid";s:4:"data";a:3:{i:0;a:3:{s:1:"B";s:3:"40%";s:2:"c1";s:2:"th";s:2:"c2";s:40:"$row_cont[category] $row_cont[class],top";}i:1;a:13:{s:1:"A";a:4:{s:4:"type";s:4:"vbox";s:4:"size";s:1:"2";i:1;a:3:{s:5:"label";s:5:"Start";s:4:"name";s:9:"cal_start";s:4:"type";s:20:"nextmatch-sortheader";}i:2;a:3:{s:5:"label";s:3:"End";s:4:"name";s:7:"cal_end";s:4:"type";s:20:"nextmatch-sortheader";}}s:1:"B";a:4:{s:4:"type";s:4:"vbox";s:4:"size";s:1:"2";i:1;a:3:{s:5:"label";s:5:"Title";s:4:"name";s:9:"cal_title";s:4:"type";s:20:"nextmatch-sortheader";}i:2;a:3:{s:5:"label";s:11:"Description";s:4:"name";s:15:"cal_description";s:4:"type";s:20:"nextmatch-sortheader";}}s:1:"C";a:3:{s:5:"label";s:5:"Title";s:4:"name";s:9:"cal_title";s:4:"type";s:20:"nextmatch-sortheader";}s:1:"D";a:3:{s:5:"label";s:11:"Description";s:4:"name";s:15:"cal_description";s:4:"type";s:20:"nextmatch-sortheader";}s:1:"E";a:3:{s:5:"label";s:10:"Recurrence";s:4:"name";s:6:"recure";s:4:"type";s:20:"nextmatch-sortheader";}s:1:"F";a:3:{s:5:"label";s:8:"Category";s:4:"name";s:6:"cat_id";s:4:"type";s:16:"nextmatch-header";}s:1:"G";a:4:{s:4:"type";s:4:"vbox";s:4:"size";s:1:"2";i:1;a:4:{s:5:"label";s:5:"Owner";s:8:"readonly";s:4:"true";s:4:"name";s:9:"cal_owner";s:4:"type";s:20:"nextmatch-sortheader";}i:2;a:3:{s:5:"label";s:8:"Location";s:4:"name";s:12:"cal_location";s:4:"type";s:20:"nextmatch-sortheader";}}s:1:"H";a:4:{s:5:"label";s:5:"Owner";s:8:"readonly";s:4:"true";s:4:"name";s:9:"cal_owner";s:4:"type";s:20:"nextmatch-sortheader";}s:1:"I";a:3:{s:5:"label";s:8:"Location";s:4:"name";s:12:"cal_location";s:4:"type";s:20:"nextmatch-sortheader";}s:1:"J";a:4:{s:5:"label";s:12:"Participants";s:4:"name";s:11:"participant";s:4:"size";s:3:"All";s:4:"type";s:23:"nextmatch-accountfilter";}s:1:"K";a:5:{s:4:"type";s:4:"vbox";s:4:"size";s:1:"3";i:1;a:3:{s:4:"type";s:20:"nextmatch-sortheader";s:5:"label";s:7:"Created";s:4:"name";s:11:"cal_created";}i:2;a:4:{s:4:"type";s:16:"nextmatch-header";s:4:"name";s:11:"cal_creator";s:4:"size";s:7:"Creator";s:5:"label";s:7:"Creator";}i:3;a:2:{s:4:"type";s:5:"label";s:5:"label";s:12:"Last changed";}}s:1:"L";a:4:{s:5:"label";s:13:"Custom fields";s:8:"readonly";s:4:"true";s:4:"name";s:3:"cfs";s:4:"type";s:22:"nextmatch-customfields";}s:1:"M";a:7:{s:5:"label";s:7:"Actions";s:5:"class";s:7:"noPrint";s:4:"type";s:4:"hbox";s:4:"size";s:1:"2";i:1;a:5:{s:4:"type";s:16:"nextmatch-header";s:5:"label";s:7:"Actions";s:4:"help";s:9:"Check all";s:4:"span";s:8:",noPrint";s:4:"name";s:14:"legacy_actions";}i:2;a:8:{s:5:"label";s:9:"Check all";s:7:"onclick";s:52:"egw_objectManager.toggleAllSelected(); return false;";s:6:"needed";s:1:"1";s:5:"align";s:5:"right";s:4:"name";s:9:"check_all";s:4:"type";s:6:"button";s:4:"size";s:5:"check";s:4:"help";s:9:"Check all";}s:4:"span";s:8:",noPrint";}}i:2;a:13:{s:1:"A";a:5:{s:4:"name";s:5:"start";s:4:"type";s:4:"vbox";s:4:"size";s:1:"2";i:1;a:5:{s:8:"readonly";s:4:"true";s:4:"name";s:13:"${row}[start]";s:4:"size";s:14:",$cont[format]";s:4:"type";s:9:"date-time";s:4:"span";s:7:",noWrap";}i:2;a:5:{s:8:"readonly";s:4:"true";s:4:"name";s:11:"${row}[end]";s:4:"size";s:14:",$cont[format]";s:4:"type";s:9:"date-time";s:4:"span";s:7:",noWrap";}}s:1:"B";a:6:{s:4:"type";s:4:"vbox";s:4:"size";s:1:"3";i:1;a:6:{s:8:"readonly";s:1:"1";s:7:"no_lang";s:1:"1";s:4:"size";s:1:"2";s:4:"type";s:4:"hbox";i:1;a:5:{s:8:"readonly";s:1:"1";s:7:"no_lang";s:1:"1";s:4:"name";s:13:"${row}[title]";s:4:"size";s:1:"b";s:4:"type";s:5:"label";}i:2;a:5:{s:4:"type";s:5:"label";s:5:"label";s:3:"#%s";s:4:"name";s:10:"${row}[id]";s:4:"size";s:1:"b";s:5:"align";s:5:"right";}}i:2;a:5:{s:7:"no_lang";s:1:"1";s:4:"type";s:3:"box";s:4:"size";s:1:"1";i:1;a:3:{s:7:"no_lang";s:1:"1";s:4:"name";s:19:"${row}[description]";s:4:"type";s:5:"label";}s:4:"span";s:16:",listDescription";}i:3;a:3:{s:7:"no_lang";s:1:"1";s:4:"name";s:14:"${row}[recure]";s:4:"type";s:5:"label";}s:4:"span";s:9:",listVbox";}s:1:"C";a:4:{s:4:"type";s:4:"hbox";s:4:"size";s:1:"2";i:1;a:2:{s:4:"name";s:13:"${row}[title]";s:4:"type";s:5:"label";}i:2;a:5:{s:4:"type";s:5:"label";s:5:"label";s:3:"#%s";s:4:"name";s:10:"${row}[id]";s:4:"size";s:1:"b";s:5:"align";s:5:"right";}}s:1:"D";a:3:{s:7:"no_lang";s:1:"1";s:4:"name";s:19:"${row}[description]";s:4:"type";s:5:"label";}s:1:"E";a:2:{s:4:"name";s:14:"${row}[recure]";s:4:"type";s:5:"label";}s:1:"F";a:3:{s:4:"type";s:10:"select-cat";s:8:"readonly";s:1:"1";s:4:"name";s:16:"${row}[category]";}s:1:"G";a:4:{s:4:"type";s:4:"vbox";s:4:"size";s:1:"2";i:1;a:4:{s:4:"type";s:14:"select-account";s:5:"class";s:6:"noWrap";s:8:"readonly";s:4:"true";s:4:"name";s:13:"${row}[owner]";}i:2;a:3:{s:7:"no_lang";s:1:"1";s:4:"name";s:16:"${row}[location]";s:4:"type";s:5:"label";}}s:1:"H";a:4:{s:4:"type";s:14:"select-account";s:5:"class";s:6:"noWrap";s:8:"readonly";s:4:"true";s:4:"name";s:13:"${row}[owner]";}s:1:"I";a:3:{s:7:"no_lang";s:1:"1";s:4:"name";s:16:"${row}[location]";s:4:"type";s:5:"label";}s:1:"J";a:4:{s:8:"readonly";s:4:"true";s:7:"no_lang";s:1:"1";s:4:"name";s:13:"${row}[parts]";s:4:"type";s:4:"html";}s:1:"K";a:5:{s:4:"type";s:4:"vbox";s:4:"size";s:1:"3";i:1;a:3:{s:4:"type";s:9:"date-time";s:4:"name";s:15:"${row}[created]";s:8:"readonly";s:1:"1";}i:2;a:3:{s:4:"type";s:14:"select-account";s:4:"name";s:15:"${row}[creator]";s:8:"readonly";s:1:"1";}i:3;a:3:{s:4:"type";s:9:"date-time";s:4:"name";s:16:"${row}[modified]";s:8:"readonly";s:1:"1";}}s:1:"L";a:2:{s:4:"name";s:4:"$row";s:4:"type";s:17:"customfields-list";}s:1:"M";a:5:{s:4:"size";s:6:"2,,0,0";s:4:"type";s:4:"vbox";i:1;a:7:{s:5:"class";s:7:"noPrint";s:4:"type";s:4:"hbox";s:4:"size";s:1:"4";i:1;a:6:{s:5:"label";s:4:"View";s:7:"onclick";s:206:"window.open(egw::link(\'/index.php\',\'menuaction=calendar.calendar_uiforms.edit&cal_id=$row_cont[id]&date=$row_cont[date]\'),\'425\',\'dependent=yes,width=750,height=450,scrollbars=yes,status=yes\'); return false;";s:4:"name";s:19:"view[$row_cont[id]]";s:4:"type";s:6:"button";s:4:"size";s:4:"view";s:4:"help";s:15:"View this event";}i:2;a:6:{s:5:"label";s:4:"Edit";s:7:"onclick";s:20:"$row_cont[edit_link]";s:4:"name";s:19:"edit[$row_cont[id]]";s:4:"type";s:6:"button";s:4:"size";s:4:"edit";s:4:"help";s:15:"Edit this event";}i:3;a:6:{s:5:"label";s:6:"Delete";s:7:"onclick";s:36:"return confirm(\'Delete this event\');";s:4:"name";s:21:"delete[$row_cont[id]]";s:4:"type";s:6:"button";s:4:"size";s:6:"delete";s:4:"help";s:17:"Delete this event";}i:4;a:5:{s:5:"align";s:5:"right";s:4:"name";s:9:"checked[]";s:4:"size";s:35:"$row_cont[id]:$row_cont[recur_date]";s:4:"type";s:8:"checkbox";s:4:"help";s:45:"Select multiple contacts for a further action";}}i:2;a:5:{s:4:"size";s:6:"3,,0,0";s:4:"type";s:4:"hbox";i:1;a:4:{s:4:"type";s:6:"button";s:4:"size";s:15:"etemplate/merge";s:5:"label";s:5:"merge";s:4:"name";s:45:"document[$row_cont[id]:$row_cont[recur_date]]";}i:2;a:6:{s:5:"label";s:11:"Filemanager";s:4:"size";s:18:"filemanager/navbar";s:4:"type";s:6:"button";s:4:"name";s:26:"filemanager[$row_cont[id]]";s:4:"span";s:8:",image16";s:7:"onclick";s:139:"window.location.href=egw::link(\'/index.php\',\'menuaction=filemanager.filemanager_ui.index&path=/apps/calendar/$row_cont[id]\'); return false;";}i:3;a:5:{s:4:"type";s:6:"button";s:4:"size";s:9:"timesheet";s:5:"label";s:19:"Add timesheet entry";s:4:"name";s:29:"timesheet[$row_cont[info_id]]";s:7:"onclick";s:267:"window.open(egw::link(\'/index.php\',\'menuaction=timesheet.timesheet_ui.edit&link_app[]=$row_cont[app]&cat_id=$row_cont[category]&link_id[]=$row_cont[app_id]$row_cont[extra_links]\'),\'_blank\',\'dependent=yes,width=600,height=400,scrollbars=yes,status=yes\'); return false;";}}s:4:"span";s:8:",noPrint";}}}s:4:"cols";i:13;s:4:"rows";i:2;s:4:"size";s:4:"100%";s:7:"options";a:1:{i:0;s:4:"100%";}}}','size' => '100%','style' => '','modified' => '1298450177',); +$templ_data[] = array('name' => 'calendar.meeting','template' => '','lang' => '','group' => '0','version' => '1.9.001','data' => 'a:4:{i:0;a:3:{s:4:"type";s:5:"label";s:4:"name";s:3:"msg";s:4:"span";s:19:",redItalic leftPad5";}i:1;a:7:{s:4:"type";s:4:"hbox";s:4:"size";s:1:"5";i:1;a:3:{s:4:"type";s:5:"label";s:4:"span";s:22:",meetingRequestMessage";s:5:"label";s:36:"This mail contains a meeting request";}i:2;a:5:{s:4:"type";s:6:"button";s:5:"label";s:6:"Accept";s:4:"name";s:14:"button[accept]";i:1;a:1:{s:4:"type";s:4:"hbox";}s:4:"span";s:9:",leftPad5";}i:3;a:4:{s:4:"type";s:6:"button";s:4:"name";s:16:"button[tentativ]";s:5:"label";s:9:"Tentative";s:4:"span";s:9:",leftPad5";}i:4;a:4:{s:4:"type";s:6:"button";s:4:"name";s:14:"button[reject]";s:5:"label";s:6:"Reject";s:4:"span";s:9:",leftPad5";}i:5;a:6:{s:4:"type";s:10:"buttononly";s:4:"name";s:12:"button[edit]";s:5:"label";s:4:"Edit";s:4:"help";s:22:"Edit event in calendar";s:7:"onclick";s:184:"window.open(egw::link(\'/index.php\',\'menuaction=calendar.calendar_uiforms.edit&cal_id=$cont[id]\'),\'_blank\',\'dependent=yes,width=750,height=410,scrollbars=yes,status=yes\'); return false;";s:4:"span";s:9:",leftPad5";}}i:2;a:1:{s:4:"type";s:5:"label";}i:3;a:6:{s:4:"type";s:4:"grid";s:4:"data";a:9:{i:0;a:10:{s:2:"c1";s:2:"th";s:1:"A";s:3:"100";s:2:"c2";s:3:"row";s:2:"c4";s:3:"row";s:2:"c3";s:3:"row";s:2:"c6";s:3:"row";s:2:"c7";s:7:"row,top";s:2:"c5";s:3:"row";s:2:"c8";s:7:"row,top";s:2:"h5";s:9:",!@recure";}i:1;a:2:{s:1:"A";a:3:{s:4:"type";s:5:"label";s:4:"span";s:3:"all";s:5:"label";s:15:"Meeting request";}s:1:"B";a:1:{s:4:"type";s:5:"label";}}i:2;a:2:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:5:"Title";}s:1:"B";a:3:{s:4:"type";s:5:"label";s:7:"no_lang";s:1:"1";s:4:"name";s:5:"title";}}i:3;a:2:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:8:"Location";}s:1:"B";a:3:{s:4:"type";s:5:"label";s:7:"no_lang";s:1:"1";s:4:"name";s:8:"location";}}i:4;a:2:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:4:"Date";}s:1:"B";a:4:{s:4:"type";s:4:"hbox";s:4:"size";s:6:"2,,0,0";i:1;a:3:{s:4:"type";s:9:"date-time";s:4:"name";s:5:"start";s:8:"readonly";s:1:"1";}i:2;a:5:{s:4:"type";s:9:"date-time";s:4:"name";s:3:"end";s:8:"readonly";s:1:"1";s:4:"span";s:9:",leftPad5";s:5:"label";s:1:"-";}}}i:5;a:2:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:10:"Recurrence";}s:1:"B";a:3:{s:4:"type";s:5:"label";s:7:"no_lang";s:1:"1";s:4:"name";s:6:"recure";}}i:6;a:2:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:9:"Organizer";}s:1:"B";a:3:{s:4:"type";s:9:"url-email";s:4:"name";s:9:"organizer";s:8:"readonly";s:1:"1";}}i:7;a:2:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:11:"Description";}s:1:"B";a:3:{s:4:"type";s:5:"label";s:7:"no_lang";s:1:"1";s:4:"name";s:11:"description";}}i:8;a:2:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:12:"Participants";}s:1:"B";a:2:{s:4:"type";s:5:"label";s:4:"name";s:16:"all_participants";}}}s:4:"rows";i:8;s:4:"cols";i:2;s:4:"size";s:21:"100%,,,meetingRequest";s:7:"options";a:2:{i:3;s:14:"meetingRequest";i:0;s:4:"100%";}}}','size' => '100%,,,meetingRequest','style' => '#popupMainDiv { + border: none; + margin: 0; +} + +.meetingRequestMessage { + font-size: 120%; +} + +table.meetingRequest { + border: 2px solid black; +} +.meetingRequest tr.th { + background-color: #4040FF; +} +.meetingRequest tr.th td { + font-weight: bold; + font-size: 120%; + color: white; +} +.meetingRequest td { + padding: 3px; +} + + +','modified' => '1306495022',); + $templ_data[] = array('name' => 'calendar.print','template' => '','lang' => '','group' => '0','version' => '1.6.001','data' => 'a:1:{i:0;a:3:{s:4:"size";s:6:"1,,0,0";s:4:"type";s:4:"hbox";i:1;a:5:{s:4:"type";s:4:"grid";s:4:"data";a:15:{i:0;a:13:{s:1:"A";s:2:"95";s:2:"c2";s:2:"th";s:2:"c5";s:3:"row";s:2:"c6";s:7:"row_off";s:2:"c7";s:3:"row";s:2:"c3";s:3:"row";s:2:"c4";s:3:"row";s:2:"c8";s:3:"row";s:2:"c9";s:3:"row";s:2:"h2";s:2:"28";s:2:"c1";s:2:"th";s:3:"c10";s:4:",top";s:3:"c11";s:2:"th";}i:1;a:2:{s:1:"A";a:3:{s:4:"type";s:5:"image";s:4:"name";s:5:"print";s:7:"onclick";s:15:"window.print();";}s:1:"B";a:4:{s:4:"type";s:5:"label";s:4:"span";s:5:",bold";s:5:"label";s:8:"Calendar";s:4:"size";s:4:"bold";}}i:2;a:2:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:5:"Title";}s:1:"B";a:5:{s:4:"type";s:4:"text";s:4:"name";s:5:"title";s:4:"size";s:6:"80,255";s:8:"readonly";s:1:"1";s:4:"span";s:3:"all";}}i:3;a:2:{s:1:"A";a:4:{s:5:"width";s:2:"95";s:4:"size";s:8:",,,start";s:4:"type";s:5:"label";s:5:"label";s:5:"Start";}s:1:"B";a:4:{s:4:"type";s:4:"hbox";s:4:"size";s:6:"2,,0,0";i:1;a:3:{s:4:"name";s:5:"start";s:4:"type";s:9:"date-time";s:8:"readonly";s:1:"1";}i:2;a:7:{s:5:"label";s:9:"whole day";s:4:"name";s:9:"whole_day";s:4:"size";s:11:",, ,disable";s:4:"type";s:8:"checkbox";s:4:"help";s:31:"Event will occupy the whole day";s:5:"align";s:6:"center";s:8:"readonly";s:1:"1";}}}i:4;a:2:{s:1:"A";a:4:{s:5:"width";s:1:"0";s:4:"size";s:11:",,,duration";s:4:"type";s:5:"label";s:5:"label";s:8:"Duration";}s:1:"B";a:4:{s:4:"size";s:6:"2,,0,0";s:4:"type";s:4:"hbox";i:1;a:7:{s:7:"no_lang";s:1:"1";s:8:"onchange";s:227:"set_style_by_class(\'table\',\'end_hide\',\'visibility\',this.value == \'\' ? \'visible\' : \'hidden\'); if (this.value == \'\') document.getElementById(form::name(\'end[str]\')).value = document.getElementById(form::name(\'start[str]\')).value;";s:4:"name";s:8:"duration";s:4:"size";s:12:"Use end date";s:4:"type";s:6:"select";s:4:"help";s:23:"Duration of the meeting";s:8:"readonly";s:1:"1";}i:2;a:4:{s:4:"name";s:3:"end";s:4:"type";s:9:"date-time";s:4:"span";s:9:",end_hide";s:8:"readonly";s:1:"1";}}}i:5;a:2:{s:1:"A";a:4:{s:4:"size";s:11:",,,location";s:4:"type";s:5:"label";s:5:"label";s:8:"Location";s:5:"width";s:1:"0";}s:1:"B";a:5:{s:4:"size";s:4:",255";s:4:"name";s:8:"location";s:4:"type";s:4:"text";s:4:"span";s:15:",inputFullWidth";s:8:"readonly";s:1:"1";}}i:6;a:2:{s:1:"A";a:4:{s:4:"size";s:11:",,,priority";s:4:"type";s:5:"label";s:5:"label";s:8:"Priority";s:5:"width";s:1:"0";}s:1:"B";a:3:{s:4:"type";s:15:"select-priority";s:4:"name";s:8:"priority";s:8:"readonly";s:1:"1";}}i:7;a:2:{s:1:"A";a:3:{s:4:"type";s:5:"label";s:5:"label";s:7:"Options";s:5:"width";s:1:"0";}s:1:"B";a:6:{s:4:"name";s:12:"non_blocking";s:4:"size";s:11:",, ,disable";s:4:"type";s:8:"checkbox";s:4:"help";s:56:"A non blocking event will not conflict with other events";s:5:"label";s:12:"non blocking";s:8:"readonly";s:1:"1";}}i:8;a:2:{s:1:"A";a:1:{s:4:"type";s:5:"label";}s:1:"B";a:5:{s:4:"name";s:6:"public";s:4:"size";s:3:"0,1";s:4:"type";s:8:"checkbox";s:5:"label";s:7:"Private";s:8:"readonly";s:1:"1";}}i:9;a:2:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:10:"Categories";}s:1:"B";a:3:{s:4:"type";s:10:"select-cat";s:4:"name";s:8:"category";s:8:"readonly";s:1:"1";}}i:10;a:2:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:11:"Description";}s:1:"B";a:3:{s:4:"type";s:8:"textarea";s:4:"name";s:11:"description";s:8:"readonly";s:1:"1";}}i:11;a:2:{s:1:"A";a:3:{s:4:"type";s:5:"label";s:5:"label";s:13:"custom fields";s:4:"span";s:3:"all";}s:1:"B";a:1:{s:4:"type";s:5:"label";}}i:12;a:2:{s:1:"A";a:3:{s:4:"type";s:12:"customfields";s:4:"span";s:3:"all";s:8:"readonly";s:1:"1";}s:1:"B";a:1:{s:4:"type";s:5:"label";}}i:13;a:2:{s:1:"A";a:3:{s:4:"type";s:8:"template";s:4:"name";s:27:"calendar.print.participants";s:4:"span";s:3:"all";}s:1:"B";a:1:{s:4:"type";s:5:"label";}}i:14;a:2:{s:1:"A";a:3:{s:4:"type";s:8:"template";s:4:"span";s:3:"all";s:4:"name";s:20:"calendar.print.links";}s:1:"B";a:1:{s:4:"type";s:5:"label";}}}s:4:"cols";i:2;s:4:"rows";i:14;s:4:"size";s:8:"100%,200";}}}','size' => '','style' => '','modified' => '1229596125',); $templ_data[] = array('name' => 'calendar.print.links','template' => '','lang' => '','group' => '0','version' => '1.6.001','data' => 'a:1:{i:0;a:5:{s:4:"type";s:4:"grid";s:4:"data";a:3:{i:0;a:3:{s:1:"A";s:2:"95";s:2:"c1";s:2:"th";s:2:"c2";s:11:"row_off,top";}i:1;a:2:{s:1:"A";a:3:{s:4:"span";s:3:"all";s:4:"type";s:5:"label";s:5:"label";s:14:"Existing links";}s:1:"B";a:1:{s:4:"type";s:5:"label";}}i:2;a:2:{s:1:"A";a:3:{s:4:"span";s:3:"all";s:4:"name";s:7:"link_to";s:4:"type";s:9:"link-list";}s:1:"B";a:1:{s:4:"type";s:5:"label";}}}s:4:"cols";i:2;s:4:"rows";i:2;s:4:"size";s:17:"100%,200,,,,,auto";}}','size' => '100%,200,,,,,auto','style' => '','modified' => '1231922363',); $templ_data[] = array('name' => 'calendar.print.participants','template' => '','lang' => '','group' => '0','version' => '1.6.001','data' => 'a:1:{i:0;a:7:{s:4:"type";s:4:"grid";s:4:"data";a:4:{i:0;a:3:{s:2:"c3";s:4:",top";s:1:"D";s:24:",@hide_status_recurrence";s:2:"c2";s:2:"th";}i:1;a:5:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:4:"span";s:3:"all";}s:1:"B";a:4:{s:4:"type";s:4:"vbox";s:4:"size";s:6:"2,,0,0";i:1;a:1:{s:4:"type";s:5:"label";}i:2;a:1:{s:4:"type";s:5:"label";}}s:1:"C";a:3:{s:4:"type";s:5:"label";s:4:"size";s:4:"1,,3";s:4:"name";s:8:"quantity";}s:1:"D";a:1:{s:4:"type";s:5:"label";}s:1:"E";a:1:{s:4:"type";s:5:"label";}}i:2;a:5:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:4:"Type";}s:1:"B";a:2:{s:4:"type";s:5:"label";s:5:"label";s:12:"Participants";}s:1:"C";a:2:{s:4:"type";s:5:"label";s:5:"label";s:8:"Quantity";}s:1:"D";a:2:{s:4:"type";s:5:"label";s:5:"label";s:10:"All future";}s:1:"E";a:2:{s:4:"type";s:5:"label";s:5:"label";s:6:"Status";}}i:3;a:5:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:4:"name";s:11:"${row}[app]";}s:1:"B";a:6:{s:4:"type";s:5:"label";s:4:"data";a:2:{i:0;a:0:{}i:1;a:2:{s:1:"A";a:3:{s:4:"type";s:14:"select-account";s:4:"name";s:6:"${row}";s:8:"readonly";s:1:"1";}s:1:"B";a:5:{s:4:"type";s:6:"select";s:4:"name";s:26:"accounts_status[$row_cont]";s:8:"onchange";s:1:"1";s:4:"help";s:30:"Accept or reject an invitation";s:7:"no_lang";s:1:"1";}}}s:4:"rows";i:1;s:4:"cols";i:2;s:4:"name";s:13:"${row}[title]";s:7:"no_lang";s:1:"1";}s:1:"C";a:4:{s:4:"type";s:3:"int";s:4:"name";s:16:"${row}[quantity]";s:4:"size";s:4:"1,,3";s:8:"readonly";s:1:"1";}s:1:"D";a:4:{s:4:"type";s:8:"checkbox";s:4:"name";s:25:"${row}[status_recurrence]";s:5:"align";s:6:"center";s:8:"readonly";s:1:"1";}s:1:"E";a:4:{s:4:"type";s:6:"select";s:4:"name";s:14:"${row}[status]";s:7:"no_lang";s:1:"1";s:8:"onchange";i:1;}}}s:4:"rows";i:3;s:4:"cols";i:5;s:4:"size";s:14:"100%,,,,,,auto";s:4:"name";s:12:"participants";s:7:"options";a:2:{i:0;s:4:"100%";i:6;s:4:"auto";}}}','size' => '100%,,,,,,auto','style' => '','modified' => '1229357325',); +$templ_data[] = array('name' => 'calendar.test','template' => '','lang' => '','group' => '0','version' => '','data' => 'a:1:{i:0;a:4:{s:4:"type";s:4:"grid";s:4:"data";a:3:{i:0;a:0:{}i:1;a:1:{s:1:"A";a:3:{s:4:"type";s:12:"customfields";s:4:"name";s:8:"#project";s:6:"needed";s:1:"1";}}i:2;a:1:{s:1:"A";a:4:{s:4:"type";s:10:"link-entry";s:4:"name";s:4:"test";s:6:"needed";s:1:"1";s:4:"size";s:14:"projectmanager";}}}s:4:"rows";i:2;s:4:"cols";i:1;}}','size' => '','style' => '','modified' => '1305704690',); +