@@ -123,7 +123,7 @@ |
||
| 123 | 123 | } |
| 124 | 124 | // Custom fields |
| 125 | 125 | if($content && strpos($content, '#') !== 0) |
| 126 | - { |
|
| 126 | + { |
|
| 127 | 127 | // Expand link-to custom fields |
| 128 | 128 | $this->cf_link_to_expand($file, $content, $info); |
| 129 | 129 | |
@@ -1909,7 +1909,7 @@ |
||
| 1909 | 1909 | WHERE cal_id='.(int)$row['cal_id'].' AND cal_start='.(int)$row['cal_start'],__LINE__,__FILE__); |
| 1910 | 1910 | } |
| 1911 | 1911 | |
| 1912 | - $GLOBALS['egw_setup']->db->query('UPDATE egw_cal_repeats SET recur_interval=1 |
|
| 1912 | + $GLOBALS['egw_setup']->db->query('UPDATE egw_cal_repeats SET recur_interval=1 |
|
| 1913 | 1913 | WHERE recur_interval=0',__LINE__,__FILE__); |
| 1914 | 1914 | |
| 1915 | 1915 | return $GLOBALS['setup_info']['calendar']['currentver'] = '1.7.007'; |
@@ -32,8 +32,8 @@ |
||
| 32 | 32 | protected static $conditions = array('exists'); |
| 33 | 33 | |
| 34 | 34 | /** |
| 35 | - * For figuring out if an entry has changed |
|
| 36 | - */ |
|
| 35 | + * For figuring out if an entry has changed |
|
| 36 | + */ |
|
| 37 | 37 | protected $tracking; |
| 38 | 38 | |
| 39 | 39 | /** |
@@ -177,7 +177,7 @@ |
||
| 177 | 177 | * @param int $cutoffdate =null |
| 178 | 178 | * @param array $not_uids =null uids NOT to return for meeting requests |
| 179 | 179 | * @return array |
| 180 | - */ |
|
| 180 | + */ |
|
| 181 | 181 | function GetMessageList($id, $cutoffdate=NULL, array $not_uids=null) |
| 182 | 182 | { |
| 183 | 183 | if (!isset($this->calendar)) $this->calendar = new calendar_boupdate(); |
@@ -387,11 +387,11 @@ |
||
| 387 | 387 | } |
| 388 | 388 | |
| 389 | 389 | /** |
| 390 | - * gets the icons displayed for a given event |
|
| 391 | - * |
|
| 392 | - * @param array $event |
|
| 393 | - * @return array of 'img' / 'title' pairs |
|
| 394 | - */ |
|
| 390 | + * gets the icons displayed for a given event |
|
| 391 | + * |
|
| 392 | + * @param array $event |
|
| 393 | + * @return array of 'img' / 'title' pairs |
|
| 394 | + */ |
|
| 395 | 395 | function event_icons($event) |
| 396 | 396 | { |
| 397 | 397 | $is_private = !$event['public'] && !$this->bo->check_perms(Acl::READ,$event); |
@@ -2415,14 +2415,14 @@ discard block |
||
| 2415 | 2415 | } |
| 2416 | 2416 | |
| 2417 | 2417 | /** |
| 2418 | - * Export events as vCalendar version 2.0 files (iCal) |
|
| 2419 | - * |
|
| 2420 | - * @param int|array $content numeric cal_id or submitted content from etempalte::exec |
|
| 2421 | - * @param boolean $return_error should an error-msg be returned or a regular page with it generated (default) |
|
| 2422 | - * @return string error-msg if $return_error |
|
| 2423 | - */ |
|
| 2424 | - function export($content=0,$return_error=false) |
|
| 2425 | - { |
|
| 2418 | + * Export events as vCalendar version 2.0 files (iCal) |
|
| 2419 | + * |
|
| 2420 | + * @param int|array $content numeric cal_id or submitted content from etempalte::exec |
|
| 2421 | + * @param boolean $return_error should an error-msg be returned or a regular page with it generated (default) |
|
| 2422 | + * @return string error-msg if $return_error |
|
| 2423 | + */ |
|
| 2424 | + function export($content=0,$return_error=false) |
|
| 2425 | + { |
|
| 2426 | 2426 | $boical = new calendar_ical(); |
| 2427 | 2427 | #error_log(__METHOD__.print_r($content,true)); |
| 2428 | 2428 | if (is_numeric($cal_id = $content ? $content : $_REQUEST['cal_id'])) |
@@ -2476,7 +2476,7 @@ discard block |
||
| 2476 | 2476 | $GLOBALS['egw_info']['flags']['app_header'] = lang('calendar') . ' - ' . lang('iCal Export'); |
| 2477 | 2477 | $etpl = new etemplate_new('calendar.export'); |
| 2478 | 2478 | $etpl->exec('calendar.calendar_uiforms.export',$content); |
| 2479 | - } |
|
| 2479 | + } |
|
| 2480 | 2480 | |
| 2481 | 2481 | /** |
| 2482 | 2482 | * Edit category ACL (admin only) |
@@ -2548,8 +2548,8 @@ discard block |
||
| 2548 | 2548 | } |
| 2549 | 2549 | |
| 2550 | 2550 | /** |
| 2551 | - * Set up the required fields to get the history tab |
|
| 2552 | - */ |
|
| 2551 | + * Set up the required fields to get the history tab |
|
| 2552 | + */ |
|
| 2553 | 2553 | public function setup_history(&$content, &$sel_options) |
| 2554 | 2554 | { |
| 2555 | 2555 | $status = 'history_status'; |
@@ -598,220 +598,220 @@ discard block |
||
| 598 | 598 | |
| 599 | 599 | switch((string)$button) |
| 600 | 600 | { |
| 601 | - case 'exception': // create an exception in a recuring event |
|
| 602 | - $msg = $this->_create_exception($event,$preserv); |
|
| 603 | - break; |
|
| 601 | + case 'exception': // create an exception in a recuring event |
|
| 602 | + $msg = $this->_create_exception($event,$preserv); |
|
| 603 | + break; |
|
| 604 | 604 | |
| 605 | - case 'copy': // create new event with copied content, some content need to be unset to make a "new" event |
|
| 606 | - unset($event['id']); |
|
| 607 | - unset($event['uid']); |
|
| 608 | - unset($event['reference']); |
|
| 609 | - unset($preserv['reference']); |
|
| 610 | - unset($event['recurrence']); |
|
| 611 | - unset($preserv['recurrence']); |
|
| 612 | - unset($event['recur_exception']); |
|
| 613 | - unset($event['edit_single']); // in case it has been set |
|
| 614 | - unset($event['modified']); |
|
| 615 | - unset($event['modifier']); |
|
| 616 | - unset($event['caldav_name']); |
|
| 617 | - $event['owner'] = !(int)$event['owner'] || !$this->bo->check_perms(Acl::ADD,0,$event['owner']) ? $this->user : $event['owner']; |
|
| 605 | + case 'copy': // create new event with copied content, some content need to be unset to make a "new" event |
|
| 606 | + unset($event['id']); |
|
| 607 | + unset($event['uid']); |
|
| 608 | + unset($event['reference']); |
|
| 609 | + unset($preserv['reference']); |
|
| 610 | + unset($event['recurrence']); |
|
| 611 | + unset($preserv['recurrence']); |
|
| 612 | + unset($event['recur_exception']); |
|
| 613 | + unset($event['edit_single']); // in case it has been set |
|
| 614 | + unset($event['modified']); |
|
| 615 | + unset($event['modifier']); |
|
| 616 | + unset($event['caldav_name']); |
|
| 617 | + $event['owner'] = !(int)$event['owner'] || !$this->bo->check_perms(Acl::ADD,0,$event['owner']) ? $this->user : $event['owner']; |
|
| 618 | + |
|
| 619 | + // Clear participant stati |
|
| 620 | + foreach($event['participant_types'] as $type => &$participants) |
|
| 621 | + { |
|
| 622 | + foreach($participants as $id => &$p_response) |
|
| 623 | + { |
|
| 624 | + if($type == 'u' && $id == $event['owner']) continue; |
|
| 625 | + calendar_so::split_status($p_response, $quantity, $role); |
|
| 626 | + // if resource defines callback for status of new status (eg. Resources app acknowledges direct booking acl), call it |
|
| 627 | + $status = isset($this->bo->resources[$type]['new_status']) ? ExecMethod($this->bo->resources[$type]['new_status'],$id) : 'U'; |
|
| 628 | + $p_response = calendar_so::combine_status($status,$quantity,$role); |
|
| 629 | + } |
|
| 630 | + } |
|
| 618 | 631 | |
| 619 | - // Clear participant stati |
|
| 620 | - foreach($event['participant_types'] as $type => &$participants) |
|
| 621 | - { |
|
| 622 | - foreach($participants as $id => &$p_response) |
|
| 632 | + // Copy alarms |
|
| 633 | + if (is_array($event['alarm'])) |
|
| 623 | 634 | { |
| 624 | - if($type == 'u' && $id == $event['owner']) continue; |
|
| 625 | - calendar_so::split_status($p_response, $quantity, $role); |
|
| 626 | - // if resource defines callback for status of new status (eg. Resources app acknowledges direct booking acl), call it |
|
| 627 | - $status = isset($this->bo->resources[$type]['new_status']) ? ExecMethod($this->bo->resources[$type]['new_status'],$id) : 'U'; |
|
| 628 | - $p_response = calendar_so::combine_status($status,$quantity,$role); |
|
| 635 | + foreach($event['alarm'] as $n => &$alarm) |
|
| 636 | + { |
|
| 637 | + unset($alarm['id']); |
|
| 638 | + unset($alarm['cal_id']); |
|
| 639 | + } |
|
| 629 | 640 | } |
| 630 | - } |
|
| 631 | 641 | |
| 632 | - // Copy alarms |
|
| 633 | - if (is_array($event['alarm'])) |
|
| 634 | - { |
|
| 635 | - foreach($event['alarm'] as $n => &$alarm) |
|
| 642 | + // Get links to be copied |
|
| 643 | + // With no ID, $content['link_to']['to_id'] is used |
|
| 644 | + $content['link_to']['to_id'] = array('to_app' => 'calendar', 'to_id' => 0); |
|
| 645 | + foreach(Link::get_links('calendar', $content['id']) as $link) |
|
| 636 | 646 | { |
| 637 | - unset($alarm['id']); |
|
| 638 | - unset($alarm['cal_id']); |
|
| 647 | + if ($link['app'] != Link::VFS_APPNAME) |
|
| 648 | + { |
|
| 649 | + Link::link('calendar', $content['link_to']['to_id'], $link['app'], $link['id'], $link['remark']); |
|
| 650 | + } |
|
| 651 | + elseif ($link['app'] == Link::VFS_APPNAME) |
|
| 652 | + { |
|
| 653 | + Link::link('calendar', $content['link_to']['to_id'], Link::VFS_APPNAME, array( |
|
| 654 | + 'tmp_name' => Link::vfs_path($link['app2'], $link['id2']).'/'.$link['id'], |
|
| 655 | + 'name' => $link['id'], |
|
| 656 | + ), $link['remark']); |
|
| 657 | + } |
|
| 639 | 658 | } |
| 640 | - } |
|
| 659 | + unset($link); |
|
| 660 | + $preserv['view'] = $preserv['edit_single'] = false; |
|
| 661 | + $msg = lang('%1 copied - the copy can now be edited', lang(Link::get_registry('calendar','entry'))); |
|
| 662 | + $event['title'] = lang('Copy of:').' '.$event['title']; |
|
| 663 | + break; |
|
| 641 | 664 | |
| 642 | - // Get links to be copied |
|
| 643 | - // With no ID, $content['link_to']['to_id'] is used |
|
| 644 | - $content['link_to']['to_id'] = array('to_app' => 'calendar', 'to_id' => 0); |
|
| 645 | - foreach(Link::get_links('calendar', $content['id']) as $link) |
|
| 646 | - { |
|
| 647 | - if ($link['app'] != Link::VFS_APPNAME) |
|
| 665 | + case 'mail': |
|
| 666 | + case 'sendrequest': |
|
| 667 | + case 'save': |
|
| 668 | + case 'print': |
|
| 669 | + case 'apply': |
|
| 670 | + case 'infolog': |
|
| 671 | + if ($event['id'] && !$this->bo->check_perms(Acl::EDIT,$event)) |
|
| 648 | 672 | { |
| 649 | - Link::link('calendar', $content['link_to']['to_id'], $link['app'], $link['id'], $link['remark']); |
|
| 673 | + $msg = lang('Permission denied'); |
|
| 674 | + $button = ''; |
|
| 675 | + break; |
|
| 650 | 676 | } |
| 651 | - elseif ($link['app'] == Link::VFS_APPNAME) |
|
| 677 | + if ($event['start'] > $event['end']) |
|
| 652 | 678 | { |
| 653 | - Link::link('calendar', $content['link_to']['to_id'], Link::VFS_APPNAME, array( |
|
| 654 | - 'tmp_name' => Link::vfs_path($link['app2'], $link['id2']).'/'.$link['id'], |
|
| 655 | - 'name' => $link['id'], |
|
| 656 | - ), $link['remark']); |
|
| 679 | + $msg = lang('Error: Starttime has to be before the endtime !!!'); |
|
| 680 | + $button = ''; |
|
| 681 | + break; |
|
| 657 | 682 | } |
| 658 | - } |
|
| 659 | - unset($link); |
|
| 660 | - $preserv['view'] = $preserv['edit_single'] = false; |
|
| 661 | - $msg = lang('%1 copied - the copy can now be edited', lang(Link::get_registry('calendar','entry'))); |
|
| 662 | - $event['title'] = lang('Copy of:').' '.$event['title']; |
|
| 663 | - break; |
|
| 664 | - |
|
| 665 | - case 'mail': |
|
| 666 | - case 'sendrequest': |
|
| 667 | - case 'save': |
|
| 668 | - case 'print': |
|
| 669 | - case 'apply': |
|
| 670 | - case 'infolog': |
|
| 671 | - if ($event['id'] && !$this->bo->check_perms(Acl::EDIT,$event)) |
|
| 672 | - { |
|
| 673 | - $msg = lang('Permission denied'); |
|
| 674 | - $button = ''; |
|
| 675 | - break; |
|
| 676 | - } |
|
| 677 | - if ($event['start'] > $event['end']) |
|
| 678 | - { |
|
| 679 | - $msg = lang('Error: Starttime has to be before the endtime !!!'); |
|
| 680 | - $button = ''; |
|
| 681 | - break; |
|
| 682 | - } |
|
| 683 | - if ($event['recur_type'] != MCAL_RECUR_NONE && $event['recur_enddate'] && $event['start'] > $event['recur_enddate']) |
|
| 684 | - { |
|
| 685 | - $msg = lang('repetition').': '.lang('Error: Starttime has to be before the endtime !!!'); |
|
| 686 | - $button = ''; |
|
| 687 | - break; |
|
| 688 | - } |
|
| 689 | - if ($event['recur_type'] != MCAL_RECUR_NONE && $event['end']-$event['start'] > calendar_rrule::recurrence_interval($event['recur_type'], $event['recur_interval'])) |
|
| 690 | - { |
|
| 691 | - $msg = lang('Error: Duration of event longer then recurrence interval!'); |
|
| 692 | - $button = ''; |
|
| 693 | - break; |
|
| 694 | - } |
|
| 695 | - if (!$event['participants']) |
|
| 696 | - { |
|
| 697 | - $msg = lang('Error: no participants selected !!!'); |
|
| 698 | - $button = ''; |
|
| 699 | - break; |
|
| 700 | - } |
|
| 701 | - // if private event with ressource reservation is forbidden |
|
| 702 | - if (!$event['public'] && $GLOBALS['egw_info']['server']['no_ressources_private']) |
|
| 703 | - { |
|
| 704 | - foreach (array_keys($event['participants']) as $uid) |
|
| 683 | + if ($event['recur_type'] != MCAL_RECUR_NONE && $event['recur_enddate'] && $event['start'] > $event['recur_enddate']) |
|
| 684 | + { |
|
| 685 | + $msg = lang('repetition').': '.lang('Error: Starttime has to be before the endtime !!!'); |
|
| 686 | + $button = ''; |
|
| 687 | + break; |
|
| 688 | + } |
|
| 689 | + if ($event['recur_type'] != MCAL_RECUR_NONE && $event['end']-$event['start'] > calendar_rrule::recurrence_interval($event['recur_type'], $event['recur_interval'])) |
|
| 690 | + { |
|
| 691 | + $msg = lang('Error: Duration of event longer then recurrence interval!'); |
|
| 692 | + $button = ''; |
|
| 693 | + break; |
|
| 694 | + } |
|
| 695 | + if (!$event['participants']) |
|
| 705 | 696 | { |
| 706 | - if ($uid[0] == 'r') //ressource detection |
|
| 697 | + $msg = lang('Error: no participants selected !!!'); |
|
| 698 | + $button = ''; |
|
| 699 | + break; |
|
| 700 | + } |
|
| 701 | + // if private event with ressource reservation is forbidden |
|
| 702 | + if (!$event['public'] && $GLOBALS['egw_info']['server']['no_ressources_private']) |
|
| 703 | + { |
|
| 704 | + foreach (array_keys($event['participants']) as $uid) |
|
| 707 | 705 | { |
| 708 | - $msg = lang('Error: ressources reservation in private events is not allowed!!!'); |
|
| 709 | - $button = ''; |
|
| 710 | - break 2; //break foreach and case |
|
| 706 | + if ($uid[0] == 'r') //ressource detection |
|
| 707 | + { |
|
| 708 | + $msg = lang('Error: ressources reservation in private events is not allowed!!!'); |
|
| 709 | + $button = ''; |
|
| 710 | + break 2; //break foreach and case |
|
| 711 | + } |
|
| 711 | 712 | } |
| 712 | 713 | } |
| 713 | - } |
|
| 714 | - if ($content['edit_single']) // we edited a single event from a series |
|
| 715 | - { |
|
| 716 | - $event['reference'] = $event['id']; |
|
| 717 | - $event['recurrence'] = $content['edit_single']; |
|
| 718 | - unset($event['id']); |
|
| 719 | - $conflicts = $this->bo->update($event,$ignore_conflicts,true,false,true,$messages,$content['no_notifications']); |
|
| 720 | - if (!is_array($conflicts) && $conflicts) |
|
| 714 | + if ($content['edit_single']) // we edited a single event from a series |
|
| 721 | 715 | { |
| 722 | - // now we need to add the original start as recur-execption to the series |
|
| 723 | - $recur_event = $this->bo->read($event['reference']); |
|
| 724 | - $recur_event['recur_exception'][] = $content['edit_single']; |
|
| 725 | - // check if we need to move the alarms, because they are next on that exception |
|
| 726 | - foreach($recur_event['alarm'] as $id => $alarm) |
|
| 716 | + $event['reference'] = $event['id']; |
|
| 717 | + $event['recurrence'] = $content['edit_single']; |
|
| 718 | + unset($event['id']); |
|
| 719 | + $conflicts = $this->bo->update($event,$ignore_conflicts,true,false,true,$messages,$content['no_notifications']); |
|
| 720 | + if (!is_array($conflicts) && $conflicts) |
|
| 727 | 721 | { |
| 728 | - if ($alarm['time'] == $content['edit_single'] - $alarm['offset']) |
|
| 722 | + // now we need to add the original start as recur-execption to the series |
|
| 723 | + $recur_event = $this->bo->read($event['reference']); |
|
| 724 | + $recur_event['recur_exception'][] = $content['edit_single']; |
|
| 725 | + // check if we need to move the alarms, because they are next on that exception |
|
| 726 | + foreach($recur_event['alarm'] as $id => $alarm) |
|
| 729 | 727 | { |
| 730 | - $rrule = calendar_rrule::event2rrule($recur_event, true); |
|
| 731 | - foreach ($rrule as $time) |
|
| 728 | + if ($alarm['time'] == $content['edit_single'] - $alarm['offset']) |
|
| 732 | 729 | { |
| 733 | - if ($content['edit_single'] < $time->format('ts')) |
|
| 730 | + $rrule = calendar_rrule::event2rrule($recur_event, true); |
|
| 731 | + foreach ($rrule as $time) |
|
| 734 | 732 | { |
| 735 | - $alarm['time'] = $time->format('ts') - $alarm['offset']; |
|
| 736 | - $this->bo->save_alarm($event['reference'], $alarm); |
|
| 737 | - break; |
|
| 733 | + if ($content['edit_single'] < $time->format('ts')) |
|
| 734 | + { |
|
| 735 | + $alarm['time'] = $time->format('ts') - $alarm['offset']; |
|
| 736 | + $this->bo->save_alarm($event['reference'], $alarm); |
|
| 737 | + break; |
|
| 738 | + } |
|
| 738 | 739 | } |
| 739 | 740 | } |
| 740 | 741 | } |
| 741 | - } |
|
| 742 | - unset($recur_event['start']); unset($recur_event['end']); // no update necessary |
|
| 743 | - unset($recur_event['alarm']); // unsetting alarms too, as they cant be updated without start! |
|
| 744 | - $this->bo->update($recur_event,true); // no conflict check here |
|
| 742 | + unset($recur_event['start']); unset($recur_event['end']); // no update necessary |
|
| 743 | + unset($recur_event['alarm']); // unsetting alarms too, as they cant be updated without start! |
|
| 744 | + $this->bo->update($recur_event,true); // no conflict check here |
|
| 745 | 745 | |
| 746 | - // Save links |
|
| 747 | - if($content['links']) |
|
| 748 | - { |
|
| 749 | - Link::link('calendar', $event['id'], $content['links']['to_id']); |
|
| 750 | - } |
|
| 746 | + // Save links |
|
| 747 | + if($content['links']) |
|
| 748 | + { |
|
| 749 | + Link::link('calendar', $event['id'], $content['links']['to_id']); |
|
| 750 | + } |
|
| 751 | 751 | |
| 752 | - if(Api\Json\Response::isJSONResponse()) |
|
| 752 | + if(Api\Json\Response::isJSONResponse()) |
|
| 753 | + { |
|
| 754 | + // Sending null will trigger a removal of the original |
|
| 755 | + // for that date |
|
| 756 | + Api\Json\Response::get()->generic('data', array('uid' => 'calendar::'.$content['reference'].':'.$content['actual_date'], 'data' => null)); |
|
| 757 | + } |
|
| 758 | + |
|
| 759 | + unset($recur_event); |
|
| 760 | + unset($event['edit_single']); // if we further edit it, it's just a single event |
|
| 761 | + unset($preserv['edit_single']); |
|
| 762 | + } |
|
| 763 | + else // conflict or error, we need to reset everything to the state befor we tried to save it |
|
| 753 | 764 | { |
| 754 | - // Sending null will trigger a removal of the original |
|
| 755 | - // for that date |
|
| 756 | - Api\Json\Response::get()->generic('data', array('uid' => 'calendar::'.$content['reference'].':'.$content['actual_date'], 'data' => null)); |
|
| 765 | + $event['id'] = $event['reference']; |
|
| 766 | + $event['reference'] = $event['recurrence'] = 0; |
|
| 767 | + $event['uid'] = $content['uid']; |
|
| 757 | 768 | } |
| 758 | - |
|
| 759 | - unset($recur_event); |
|
| 760 | - unset($event['edit_single']); // if we further edit it, it's just a single event |
|
| 761 | - unset($preserv['edit_single']); |
|
| 769 | + $update_type = 'edit'; |
|
| 762 | 770 | } |
| 763 | - else // conflict or error, we need to reset everything to the state befor we tried to save it |
|
| 771 | + else // we edited a non-reccuring event or the whole series |
|
| 764 | 772 | { |
| 765 | - $event['id'] = $event['reference']; |
|
| 766 | - $event['reference'] = $event['recurrence'] = 0; |
|
| 767 | - $event['uid'] = $content['uid']; |
|
| 768 | - } |
|
| 769 | - $update_type = 'edit'; |
|
| 770 | - } |
|
| 771 | - else // we edited a non-reccuring event or the whole series |
|
| 772 | - { |
|
| 773 | - if (($old_event = $this->bo->read($event['id']))) |
|
| 774 | - { |
|
| 775 | - if ($event['recur_type'] != MCAL_RECUR_NONE) |
|
| 773 | + if (($old_event = $this->bo->read($event['id']))) |
|
| 776 | 774 | { |
| 777 | - $update_type = 'edit'; |
|
| 778 | - |
|
| 779 | - // we edit a existing series event |
|
| 780 | - if ($event['start'] != $old_event['start'] || |
|
| 781 | - $event['whole_day'] != $old_event['whole_day'] || |
|
| 782 | - $event['end'] != $old_event['end']) |
|
| 775 | + if ($event['recur_type'] != MCAL_RECUR_NONE) |
|
| 783 | 776 | { |
| 784 | - // calculate offset against old series start or clicked recurrance, |
|
| 785 | - // depending on which is smaller |
|
| 786 | - $offset = $event['start'] - $old_event['start']; |
|
| 787 | - if (abs($offset) > abs($off2 = $event['start'] - $event['actual_date'])) |
|
| 788 | - { |
|
| 789 | - $offset = $off2; |
|
| 790 | - } |
|
| 791 | - $msg = $this->_break_recurring($event, $old_event, $event['actual_date'] + $offset,$content['no_notifications']); |
|
| 792 | - if($msg) |
|
| 777 | + $update_type = 'edit'; |
|
| 778 | + |
|
| 779 | + // we edit a existing series event |
|
| 780 | + if ($event['start'] != $old_event['start'] || |
|
| 781 | + $event['whole_day'] != $old_event['whole_day'] || |
|
| 782 | + $event['end'] != $old_event['end']) |
|
| 793 | 783 | { |
| 794 | - $noerror = false; |
|
| 784 | + // calculate offset against old series start or clicked recurrance, |
|
| 785 | + // depending on which is smaller |
|
| 786 | + $offset = $event['start'] - $old_event['start']; |
|
| 787 | + if (abs($offset) > abs($off2 = $event['start'] - $event['actual_date'])) |
|
| 788 | + { |
|
| 789 | + $offset = $off2; |
|
| 790 | + } |
|
| 791 | + $msg = $this->_break_recurring($event, $old_event, $event['actual_date'] + $offset,$content['no_notifications']); |
|
| 792 | + if($msg) |
|
| 793 | + { |
|
| 794 | + $noerror = false; |
|
| 795 | + } |
|
| 795 | 796 | } |
| 796 | 797 | } |
| 797 | - } |
|
| 798 | - else |
|
| 799 | - { |
|
| 800 | - if ($old_event['start'] != $event['start'] || |
|
| 801 | - $old_event['end'] != $event['end'] || |
|
| 802 | - $event['whole_day'] != $old_event['whole_day']) |
|
| 798 | + else |
|
| 803 | 799 | { |
| 804 | - $sameday = (date('Ymd', $old_event['start']) == date('Ymd', $event['start'])); |
|
| 805 | - foreach((array)$event['participants'] as $uid => $status) |
|
| 800 | + if ($old_event['start'] != $event['start'] || |
|
| 801 | + $old_event['end'] != $event['end'] || |
|
| 802 | + $event['whole_day'] != $old_event['whole_day']) |
|
| 806 | 803 | { |
| 807 | - $q = $r = null; |
|
| 808 | - calendar_so::split_status($status,$q,$r); |
|
| 809 | - if ($uid[0] != 'c' && $uid[0] != 'e' && $uid != $this->bo->user && $status != 'U') |
|
| 804 | + $sameday = (date('Ymd', $old_event['start']) == date('Ymd', $event['start'])); |
|
| 805 | + foreach((array)$event['participants'] as $uid => $status) |
|
| 810 | 806 | { |
| 811 | - $preferences = new Api\Preferences($uid); |
|
| 812 | - $part_prefs = $preferences->read_repository(); |
|
| 813 | - switch ($part_prefs['calendar']['reset_stati']) |
|
| 807 | + $q = $r = null; |
|
| 808 | + calendar_so::split_status($status,$q,$r); |
|
| 809 | + if ($uid[0] != 'c' && $uid[0] != 'e' && $uid != $this->bo->user && $status != 'U') |
|
| 814 | 810 | { |
| 811 | + $preferences = new Api\Preferences($uid); |
|
| 812 | + $part_prefs = $preferences->read_repository(); |
|
| 813 | + switch ($part_prefs['calendar']['reset_stati']) |
|
| 814 | + { |
|
| 815 | 815 | case 'no': |
| 816 | 816 | break; |
| 817 | 817 | case 'startday': |
@@ -820,7 +820,7 @@ discard block |
||
| 820 | 820 | $status_reset_to_unknown = true; |
| 821 | 821 | $event['participants'][$uid] = calendar_so::combine_status('U',$q,$r); |
| 822 | 822 | // todo: report reset status to user |
| 823 | - } |
|
| 823 | + } |
|
| 824 | 824 | } |
| 825 | 825 | } |
| 826 | 826 | // check if we need to move the alarms, because they are relative |
@@ -962,83 +962,83 @@ discard block |
||
| 962 | 962 | } |
| 963 | 963 | break; |
| 964 | 964 | |
| 965 | - case 'cancel': |
|
| 966 | - if($content['cancel_needs_refresh']) |
|
| 967 | - { |
|
| 968 | - Framework::refresh_opener($msg, 'calendar'); |
|
| 969 | - } |
|
| 970 | - break; |
|
| 971 | - |
|
| 972 | - case 'delete': // delete of event (regular or series) |
|
| 973 | - $exceptions_kept = null; |
|
| 974 | - if ($this->bo->delete($event['id'], (int)$content['edit_single'], false, $event['no_notifications'], |
|
| 975 | - $content['delete_exceptions'] == 'true', $exceptions_kept)) |
|
| 976 | - { |
|
| 977 | - if ($event['recur_type'] != MCAL_RECUR_NONE && $content['reference'] == 0 && !$content['edit_single']) |
|
| 965 | + case 'cancel': |
|
| 966 | + if($content['cancel_needs_refresh']) |
|
| 978 | 967 | { |
| 979 | - $msg = lang('Series deleted'); |
|
| 980 | - if ($exceptions_kept) $msg .= lang(', exceptions preserved'); |
|
| 968 | + Framework::refresh_opener($msg, 'calendar'); |
|
| 981 | 969 | } |
| 982 | - else |
|
| 970 | + break; |
|
| 971 | + |
|
| 972 | + case 'delete': // delete of event (regular or series) |
|
| 973 | + $exceptions_kept = null; |
|
| 974 | + if ($this->bo->delete($event['id'], (int)$content['edit_single'], false, $event['no_notifications'], |
|
| 975 | + $content['delete_exceptions'] == 'true', $exceptions_kept)) |
|
| 983 | 976 | { |
| 984 | - $msg = lang('Event deleted'); |
|
| 985 | - } |
|
| 977 | + if ($event['recur_type'] != MCAL_RECUR_NONE && $content['reference'] == 0 && !$content['edit_single']) |
|
| 978 | + { |
|
| 979 | + $msg = lang('Series deleted'); |
|
| 980 | + if ($exceptions_kept) $msg .= lang(', exceptions preserved'); |
|
| 981 | + } |
|
| 982 | + else |
|
| 983 | + { |
|
| 984 | + $msg = lang('Event deleted'); |
|
| 985 | + } |
|
| 986 | 986 | |
| 987 | - } |
|
| 988 | - break; |
|
| 987 | + } |
|
| 988 | + break; |
|
| 989 | 989 | |
| 990 | - case 'freetime': |
|
| 991 | - // the "click" has to be in onload, to make sure the button is already created |
|
| 992 | - $event['button_was'] = $button; |
|
| 993 | - break; |
|
| 990 | + case 'freetime': |
|
| 991 | + // the "click" has to be in onload, to make sure the button is already created |
|
| 992 | + $event['button_was'] = $button; |
|
| 993 | + break; |
|
| 994 | 994 | |
| 995 | - case 'add_alarm': |
|
| 996 | - $time = $content['start']; |
|
| 997 | - $offset = $time - $content['new_alarm']['date']; |
|
| 998 | - if ($event['recur_type'] != MCAL_RECUR_NONE && |
|
| 999 | - ($next_occurrence = $this->bo->read($event['id'], $this->bo->now_su + $offset, true)) && |
|
| 1000 | - $time < $next_occurrence['start']) |
|
| 1001 | - { |
|
| 1002 | - $content['new_alarm']['date'] = $next_occurrence['start'] - $offset; |
|
| 1003 | - } |
|
| 1004 | - if ($this->bo->check_perms(Acl::EDIT,!$content['new_alarm']['owner'] ? $event : 0,$content['new_alarm']['owner'])) |
|
| 1005 | - { |
|
| 1006 | - $alarm = array( |
|
| 1007 | - 'offset' => $offset, |
|
| 1008 | - 'time' => $content['new_alarm']['date'], |
|
| 1009 | - 'all' => !$content['new_alarm']['owner'], |
|
| 1010 | - 'owner' => $content['new_alarm']['owner'] ? $content['new_alarm']['owner'] : $this->user, |
|
| 1011 | - ); |
|
| 1012 | - if ($alarm['time'] < $this->bo->now_su) |
|
| 995 | + case 'add_alarm': |
|
| 996 | + $time = $content['start']; |
|
| 997 | + $offset = $time - $content['new_alarm']['date']; |
|
| 998 | + if ($event['recur_type'] != MCAL_RECUR_NONE && |
|
| 999 | + ($next_occurrence = $this->bo->read($event['id'], $this->bo->now_su + $offset, true)) && |
|
| 1000 | + $time < $next_occurrence['start']) |
|
| 1013 | 1001 | { |
| 1014 | - $msg = lang("Can't add alarms in the past !!!"); |
|
| 1002 | + $content['new_alarm']['date'] = $next_occurrence['start'] - $offset; |
|
| 1015 | 1003 | } |
| 1016 | - elseif ($event['id']) // save the alarm immediatly |
|
| 1004 | + if ($this->bo->check_perms(Acl::EDIT,!$content['new_alarm']['owner'] ? $event : 0,$content['new_alarm']['owner'])) |
|
| 1017 | 1005 | { |
| 1018 | - if (($alarm_id = $this->bo->save_alarm($event['id'],$alarm))) |
|
| 1006 | + $alarm = array( |
|
| 1007 | + 'offset' => $offset, |
|
| 1008 | + 'time' => $content['new_alarm']['date'], |
|
| 1009 | + 'all' => !$content['new_alarm']['owner'], |
|
| 1010 | + 'owner' => $content['new_alarm']['owner'] ? $content['new_alarm']['owner'] : $this->user, |
|
| 1011 | + ); |
|
| 1012 | + if ($alarm['time'] < $this->bo->now_su) |
|
| 1013 | + { |
|
| 1014 | + $msg = lang("Can't add alarms in the past !!!"); |
|
| 1015 | + } |
|
| 1016 | + elseif ($event['id']) // save the alarm immediatly |
|
| 1019 | 1017 | { |
| 1020 | - $alarm['id'] = $alarm_id; |
|
| 1021 | - $event['alarm'][$alarm_id] = $alarm; |
|
| 1018 | + if (($alarm_id = $this->bo->save_alarm($event['id'],$alarm))) |
|
| 1019 | + { |
|
| 1020 | + $alarm['id'] = $alarm_id; |
|
| 1021 | + $event['alarm'][$alarm_id] = $alarm; |
|
| 1022 | 1022 | |
| 1023 | - $msg = lang('Alarm added'); |
|
| 1024 | - Framework::refresh_opener($msg,'calendar', $event['id'], 'update'); |
|
| 1023 | + $msg = lang('Alarm added'); |
|
| 1024 | + Framework::refresh_opener($msg,'calendar', $event['id'], 'update'); |
|
| 1025 | + } |
|
| 1026 | + else |
|
| 1027 | + { |
|
| 1028 | + $msg = lang('Error adding the alarm'); |
|
| 1029 | + } |
|
| 1025 | 1030 | } |
| 1026 | 1031 | else |
| 1027 | 1032 | { |
| 1028 | - $msg = lang('Error adding the alarm'); |
|
| 1033 | + for($alarm['id']=1; isset($event['alarm'][$alarm['id']]); $alarm['id']++) {} // get a temporary non-conflicting, numeric id |
|
| 1034 | + $event['alarm'][$alarm['id']] = $alarm; |
|
| 1029 | 1035 | } |
| 1030 | 1036 | } |
| 1031 | 1037 | else |
| 1032 | 1038 | { |
| 1033 | - for($alarm['id']=1; isset($event['alarm'][$alarm['id']]); $alarm['id']++) {} // get a temporary non-conflicting, numeric id |
|
| 1034 | - $event['alarm'][$alarm['id']] = $alarm; |
|
| 1039 | + $msg = lang('Permission denied'); |
|
| 1035 | 1040 | } |
| 1036 | - } |
|
| 1037 | - else |
|
| 1038 | - { |
|
| 1039 | - $msg = lang('Permission denied'); |
|
| 1040 | - } |
|
| 1041 | - break; |
|
| 1041 | + break; |
|
| 1042 | 1042 | } |
| 1043 | 1043 | // add notification-errors, if we have some |
| 1044 | 1044 | if (($notification_errors = notifications::errors(true))) |
@@ -1490,13 +1490,13 @@ discard block |
||
| 1490 | 1490 | } |
| 1491 | 1491 | |
| 1492 | 1492 | /** |
| 1493 | - * Converts a participant into a (readable) user- or resource-name |
|
| 1494 | - * |
|
| 1495 | - * @param string|int $id id of user or resource |
|
| 1496 | - * @param string|boolean $use_type =false type-letter or false |
|
| 1497 | - * @param boolean $append_email =false append email (Name <email>) |
|
| 1498 | - * @return string with name |
|
| 1499 | - */ |
|
| 1493 | + * Converts a participant into a (readable) user- or resource-name |
|
| 1494 | + * |
|
| 1495 | + * @param string|int $id id of user or resource |
|
| 1496 | + * @param string|boolean $use_type =false type-letter or false |
|
| 1497 | + * @param boolean $append_email =false append email (Name <email>) |
|
| 1498 | + * @return string with name |
|
| 1499 | + */ |
|
| 1500 | 1500 | function participant_name($id,$use_type=false, $append_email=false) |
| 1501 | 1501 | { |
| 1502 | 1502 | static $id2lid = array(); |
@@ -1525,13 +1525,13 @@ discard block |
||
| 1525 | 1525 | } |
| 1526 | 1526 | |
| 1527 | 1527 | /** |
| 1528 | - * Converts participants array of an event into array of (readable) participant-names with status |
|
| 1529 | - * |
|
| 1530 | - * @param array $event event-data |
|
| 1531 | - * @param boolean $long_status =false should the long/verbose status or an icon be use |
|
| 1532 | - * @param boolean $show_group_invitation =false show group-invitations (status == 'G') or not (default) |
|
| 1533 | - * @return array with id / names with status pairs |
|
| 1534 | - */ |
|
| 1528 | + * Converts participants array of an event into array of (readable) participant-names with status |
|
| 1529 | + * |
|
| 1530 | + * @param array $event event-data |
|
| 1531 | + * @param boolean $long_status =false should the long/verbose status or an icon be use |
|
| 1532 | + * @param boolean $show_group_invitation =false show group-invitations (status == 'G') or not (default) |
|
| 1533 | + * @return array with id / names with status pairs |
|
| 1534 | + */ |
|
| 1535 | 1535 | function participants($event,$long_status=false,$show_group_invitation=false) |
| 1536 | 1536 | { |
| 1537 | 1537 | //error_log(__METHOD__.__LINE__.array2string($event['participants'])); |
@@ -1601,12 +1601,12 @@ discard block |
||
| 1601 | 1601 | } |
| 1602 | 1602 | |
| 1603 | 1603 | /** |
| 1604 | - * Converts category string of an event into array of (readable) category-names |
|
| 1605 | - * |
|
| 1606 | - * @param string $category cat-id (multiple id's commaseparated) |
|
| 1607 | - * @param int $color color of the category, if multiple cats, the color of the last one with color is returned |
|
| 1608 | - * @return array with id / names |
|
| 1609 | - */ |
|
| 1604 | + * Converts category string of an event into array of (readable) category-names |
|
| 1605 | + * |
|
| 1606 | + * @param string $category cat-id (multiple id's commaseparated) |
|
| 1607 | + * @param int $color color of the category, if multiple cats, the color of the last one with color is returned |
|
| 1608 | + * @return array with id / names |
|
| 1609 | + */ |
|
| 1610 | 1610 | function categories($category,&$color) |
| 1611 | 1611 | { |
| 1612 | 1612 | static $id2cat = array(); |
@@ -1504,22 +1504,22 @@ discard block |
||
| 1504 | 1504 | // check the old list against the new list |
| 1505 | 1505 | foreach ($old_event['participants'] as $userid => $status) |
| 1506 | 1506 | { |
| 1507 | - if (!isset($new_event['participants'][$userid])){ |
|
| 1508 | - // Attendee will be deleted this way |
|
| 1509 | - $new_event['participants'][$userid] = 'G'; |
|
| 1510 | - } |
|
| 1511 | - elseif ($new_event['participants'][$userid] == $status) |
|
| 1512 | - { |
|
| 1513 | - // Same status -- nothing to do. |
|
| 1514 | - unset($new_event['participants'][$userid]); |
|
| 1515 | - } |
|
| 1507 | + if (!isset($new_event['participants'][$userid])){ |
|
| 1508 | + // Attendee will be deleted this way |
|
| 1509 | + $new_event['participants'][$userid] = 'G'; |
|
| 1510 | + } |
|
| 1511 | + elseif ($new_event['participants'][$userid] == $status) |
|
| 1512 | + { |
|
| 1513 | + // Same status -- nothing to do. |
|
| 1514 | + unset($new_event['participants'][$userid]); |
|
| 1515 | + } |
|
| 1516 | 1516 | } |
| 1517 | 1517 | // write the changes |
| 1518 | 1518 | foreach ($new_event['participants'] as $userid => $status) |
| 1519 | 1519 | { |
| 1520 | 1520 | $this->set_status($old_event, $userid, $status, $recur_date, true, false,$skip_notification); |
| 1521 | 1521 | } |
| 1522 | - } |
|
| 1522 | + } |
|
| 1523 | 1523 | |
| 1524 | 1524 | /** |
| 1525 | 1525 | * deletes an event |
@@ -2493,24 +2493,24 @@ discard block |
||
| 2493 | 2493 | /** |
| 2494 | 2494 | * classifies an incoming event from the eGW point-of-view |
| 2495 | 2495 | * |
| 2496 | - * exceptions: unlike other calendar apps eGW does not create an event exception |
|
| 2497 | - * if just the participant state changes - therefore we have to distinguish between |
|
| 2498 | - * real exceptions and status only exceptions |
|
| 2499 | - * |
|
| 2500 | - * @param array $event the event to check |
|
| 2501 | - * |
|
| 2502 | - * @return array |
|
| 2503 | - * type => |
|
| 2504 | - * SINGLE a single event |
|
| 2505 | - * SERIES-MASTER the series master |
|
| 2506 | - * SERIES-EXCEPTION event is a real exception |
|
| 2507 | - * SERIES-PSEUDO-EXCEPTION event is a status only exception |
|
| 2508 | - * SERIES-EXCEPTION-PROPAGATE event was a status only exception in the past and is now a real exception |
|
| 2509 | - * stored_event => if event already exists in the database array with event data or false |
|
| 2510 | - * master_event => for event type SERIES-EXCEPTION, SERIES-PSEUDO-EXCEPTION or SERIES-EXCEPTION-PROPAGATE |
|
| 2511 | - * the corresponding series master event array |
|
| 2512 | - * NOTE: this param is false if event is of type SERIES-MASTER |
|
| 2513 | - */ |
|
| 2496 | + * exceptions: unlike other calendar apps eGW does not create an event exception |
|
| 2497 | + * if just the participant state changes - therefore we have to distinguish between |
|
| 2498 | + * real exceptions and status only exceptions |
|
| 2499 | + * |
|
| 2500 | + * @param array $event the event to check |
|
| 2501 | + * |
|
| 2502 | + * @return array |
|
| 2503 | + * type => |
|
| 2504 | + * SINGLE a single event |
|
| 2505 | + * SERIES-MASTER the series master |
|
| 2506 | + * SERIES-EXCEPTION event is a real exception |
|
| 2507 | + * SERIES-PSEUDO-EXCEPTION event is a status only exception |
|
| 2508 | + * SERIES-EXCEPTION-PROPAGATE event was a status only exception in the past and is now a real exception |
|
| 2509 | + * stored_event => if event already exists in the database array with event data or false |
|
| 2510 | + * master_event => for event type SERIES-EXCEPTION, SERIES-PSEUDO-EXCEPTION or SERIES-EXCEPTION-PROPAGATE |
|
| 2511 | + * the corresponding series master event array |
|
| 2512 | + * NOTE: this param is false if event is of type SERIES-MASTER |
|
| 2513 | + */ |
|
| 2514 | 2514 | function get_event_info($event) |
| 2515 | 2515 | { |
| 2516 | 2516 | $type = 'SINGLE'; // default |
@@ -2681,16 +2681,16 @@ discard block |
||
| 2681 | 2681 | 'stored_event' => $stored_event, |
| 2682 | 2682 | 'master_event' => $master_event, |
| 2683 | 2683 | ); |
| 2684 | - } |
|
| 2685 | - |
|
| 2686 | - /** |
|
| 2687 | - * Translates all timestamps for a given event from server-time to user-time. |
|
| 2688 | - * The update() and save() methods expect timestamps in user-time. |
|
| 2689 | - * @param &$event the event we are working on |
|
| 2690 | - * |
|
| 2691 | - */ |
|
| 2692 | - function server2usertime (&$event) |
|
| 2693 | - { |
|
| 2684 | + } |
|
| 2685 | + |
|
| 2686 | + /** |
|
| 2687 | + * Translates all timestamps for a given event from server-time to user-time. |
|
| 2688 | + * The update() and save() methods expect timestamps in user-time. |
|
| 2689 | + * @param &$event the event we are working on |
|
| 2690 | + * |
|
| 2691 | + */ |
|
| 2692 | + function server2usertime (&$event) |
|
| 2693 | + { |
|
| 2694 | 2694 | // we run all dates through date2usertime, to adjust to user-time |
| 2695 | 2695 | foreach(array('start','end','recur_enddate','recurrence') as $ts) |
| 2696 | 2696 | { |
@@ -2713,7 +2713,7 @@ discard block |
||
| 2713 | 2713 | $event['alarm'][$id]['time'] = $this->date2usertime($alarm['time']); |
| 2714 | 2714 | } |
| 2715 | 2715 | } |
| 2716 | - } |
|
| 2716 | + } |
|
| 2717 | 2717 | /** |
| 2718 | 2718 | * Delete events that are more than $age years old |
| 2719 | 2719 | * |
@@ -1,11 +1,11 @@ discard block |
||
| 1 | 1 | <?php |
| 2 | 2 | /** |
| 3 | - * Egroupware |
|
| 4 | - * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License |
|
| 5 | - * @link http://www.egroupware.org |
|
| 6 | - * @author Nathan Gray |
|
| 7 | - * @version $Id$ |
|
| 8 | - */ |
|
| 3 | + * Egroupware |
|
| 4 | + * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License |
|
| 5 | + * @link http://www.egroupware.org |
|
| 6 | + * @author Nathan Gray |
|
| 7 | + * @version $Id$ |
|
| 8 | + */ |
|
| 9 | 9 | |
| 10 | 10 | use EGroupware\Api; |
| 11 | 11 | use EGroupware\Api\Etemplate; |
@@ -22,13 +22,13 @@ discard block |
||
| 22 | 22 | { |
| 23 | 23 | |
| 24 | 24 | /** |
| 25 | - * Set up what we know on the server side. |
|
| 26 | - * |
|
| 27 | - * Sending a first chunk of rows |
|
| 28 | - * |
|
| 29 | - * @param string $cname |
|
| 30 | - * @param array $expand values for keys 'c', 'row', 'c_', 'row_', 'cont' |
|
| 31 | - */ |
|
| 25 | + * Set up what we know on the server side. |
|
| 26 | + * |
|
| 27 | + * Sending a first chunk of rows |
|
| 28 | + * |
|
| 29 | + * @param string $cname |
|
| 30 | + * @param array $expand values for keys 'c', 'row', 'c_', 'row_', 'cont' |
|
| 31 | + */ |
|
| 32 | 32 | public function beforeSendToClient($cname, array $expand=null) |
| 33 | 33 | { |
| 34 | 34 | $form_name = self::form_name($cname, $this->id, $expand); |