<?php 
/** 
 * IcalExport, Mantis calendar Export Plugin 
 * 
 * Adapted for iCalcreator >= 6.27.16 
 * 
 * @package    MantisPlugin 
 * @subpackage IcalExport 
 * @copyright  Copyright (C) 2013-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved. 
 * @link       http://kigkonsult.se/IcalExport 
 * @license    Subject matter of licence is the software IcalExport. 
 *             The above copyright, link, package and version notices, 
 *             this licence notice shall be included in all copies or 
 *             substantial portions of the IcalExport. 
 * 
 *             IcalExport is free software: you can redistribute it and/or modify 
 *             it under the terms of the GNU Lesser General Public License as published 
 *             by the Free Software Foundation, either version 3 of the License, 
 *             or (at your option) any later version. 
 * 
 *             IcalExport is distributed in the hope that it will be useful, 
 *             but WITHOUT ANY WARRANTY; without even the implied warranty of 
 *             MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
 *             GNU Lesser General Public License for more details. 
 * 
 *             You should have received a copy of the GNU Lesser General Public License 
 *             along with iCalcreator. If not, see <https://www.gnu.org/licenses/>. 
 * @author     Kjell-Inge Gustafsson, kigkonsult <[email protected]> 
 * @version    2.0 
 * @since      2.0 - 2019-03-25 
 * 
 * This file is a part of IcalExport. 
 */ 
/* 
 * MantisBT Core API's 
 */ 
require_once( 'core.php' ); 
require_api( 'user_api.php' ); 
require_api( 'bug_api.php' ); 
require_api( 'bugnote_api.php' ); 
require_api( 'file_api.php' ); 
require_api( 'gpc_api.php' ); 
require_api( 'relationship_api.php' ); 
require_api( 'tag_api.php' ); 
auth_ensure_user_authenticated(); 
helper_begin_long_process(); 
ob_clean(); 
 
/* 
 * get the user currently logged in 
 */ 
$t_user_id    = auth_get_current_user_id(); 
$t_user_name  = user_get_name( $t_user_id ); 
$t_user_email = user_get_email( $t_user_id ); 
$t_show_tags  = access_has_global_level( config_get( 'tag_view_threshold' )); 
 
/* 
 * get some config values 
 */ 
// $t_parsed_url = parse_url( $t_url );  // TODO, find site/system unique id??!! 
// $t_unique_id  = $t_parsed_url['host']; 
$t_unique_id          = config_get( 'hostname' ); 
$t_url                = config_get( 'path' ); 
$t_normal_date_format = config_get( 'normal_date_format' ); 
 
/* 
 * get bug id(s) 
 */ 
$f_bug_id  = gpc_get_int( 'id', 0 ); 
$t_cnt     = 0; 
if( empty( $f_bug_id )) { 
    /* 
     * Get bug rows according to the current filter 
     */ 
    require_api( 'filter_api.php' ); 
    $t_page_number  = 1; 
    $t_per_page     = -1; 
    $t_page_count   = null; 
    $t_bug_count    = null; 
    $t_result = filter_get_bug_rows( 
        $t_page_number, 
        $t_per_page, 
        $t_page_count, 
        $t_bug_count 
    ); 
    $t_cnt          = count( $t_result ); 
    $t_calname      = plugin_lang_get( 'x_wr_calname2' ); 
    $t_caldesc      = plugin_lang_get( 'x_wr_caldesc2' ); 
    $t_redirect_url = 'view_all_bug_page.php'; 
} 
else { 
    /* 
     * Get bug row according to parameter id 
     */ 
    bug_ensure_exists( $f_bug_id ); 
    $t_result = bug_get( $f_bug_id, true ); 
    if( ! empty( $t_result )) { 
        $t_cnt    = 1; 
        $t_result = [ $t_result ]; 
    } 
    $t_calname      = plugin_lang_get( 'x_wr_calname1' ) . $f_bug_id; 
    $t_caldesc      = plugin_lang_get( 'x_wr_caldesc1' ) . $f_bug_id; 
    $t_redirect_url = 'view.php?id=' . $f_bug_id; 
} 
/* 
 * If no found, return 
 */ 
if( empty( $t_cnt )) { 
    require_api( 'print_api.php' ); 
    print_header_redirect( $t_redirect_url ); 
} 
 
/* 
 * properties that we want to export are 'protected' 
 */ 
$t_columns = array_keys( getClassProperties( 'BugData', 'protected' )); 
/* 
 * Ignored fields, these will be skipped 
 */ 
$t_ignore = [ '_stats', 'bug_text_id', ]; 
 
/* 
 * iCalcreator loader setup 
 */ 
require_once( 'CalendarLoader.php' ); 
$t_calendarLoader = new CalendarLoader( $t_unique_id, $t_normal_date_format, $t_user_name, $t_calname, $t_caldesc ); 
 
/* 
 * export each bug/row into an Vcalendar vtodo object instance 
 */ 
$t_cnt = 0; 
foreach( $t_result as $t_ix => $t_bug ) { 
    if( ! isset( $t_bug->id )) { 
        continue; 
    } 
    $t_cnt += 1; 
 
    /* 
     * Initiate a new Vtodo with 
     * SEQUENCE property set from number of rows in table bug_history (+1) 
     */ 
    $t_last_updated = $t_eta = $t_due = null; 
    $t_created = ( isset( $t_bug->date_submitted )) ? $t_bug->date_submitted : time(); 
    $t_calendarLoader->initNewVtodo( 
        $t_created, 
        $t_url, 
        $t_bug->id, 
        get_bug_history_count( $t_bug->id ), 
        $t_user_email 
    ); 
 
    foreach( $t_columns as $t_ix2 => $t_element ) { 
        if( in_array( $t_element, $t_ignore )) { 
            continue; 
        } 
        $t_value = $t_bug->{$t_element}; 
        /* 
         * Ignore empty values 
         */ 
        if( empty( $t_value )) { 
            continue; 
        } 
        switch( $t_element ) { 
            case 'id': 
                $t_calendarLoader->updateDescriptions( $t_element, $t_value ); 
                break; 
            case 'project_id': 
                $t_calendarLoader->updateDescriptions( 'project', project_get_name( $t_value )); 
                break; 
            /* 
             * Set iCal component ATTENDEE property 
             */ 
            case 'reporter_id': 
                $t_value2 = user_get_email( $t_value ); 
                $t_calendarLoader->updateAttendee( 
                    $t_value2, 
                    user_get_name( $t_value ), 
                    [ 'DELEGATED-FROM' => true ] 
                ); 
                $t_calendarLoader->updateDescriptions( 'reporter', $t_value2 ); 
                break; 
            /* 
             * Set iCal component ORGANIZER/ATTENDEE/DTSTART property 
             */ 
            case 'handler_id': 
                $t_calendarLoader->updateAttendee( 
                    user_get_email( $t_value ), 
                    user_get_name( $t_value ), 
                    [ 'ROLE' => 'CHAIR' ] 
                ); 
                $t_dtstart = get_assignment_start_date( $t_bug->id, $t_value ); 
                if( empty( $t_dtstart )) { 
                    $t_dtstart = $t_bug->date_submitted; 
                } 
                $t_calendarLoader->setDtstart( $t_dtstart ); 
                break; 
            /* 
             * Set iCal component CATEGORIES property 
             */ 
            case 'category_id': 
                $t_category_name = category_get_name( $t_value ); 
                $t_calendarLoader->setCategories( [ $t_category_name ] ); 
                $t_calendarLoader->updateDescriptions( 'category', $t_category_name ); 
                break; 
            /* 
             * already fixed 
             */ 
            case 'date_submitted': 
                break; 
            /* 
             * Save for later use 
             */ 
            case 'last_updated': 
                $t_last_updated = $t_value; 
                break; 
            /* 
             * Save for later use 
             */ 
            case 'eta': 
                $t_eta = $t_value; 
                $t_calendarLoader->updateDescriptions( $t_element, get_enum_element( $t_element, $t_value )); 
                break; 
            /* 
             * Set iCal component DUE property 
             */ 
            case 'due_date': 
                if( ! date_is_null( $t_value )) { 
                    $t_due = $t_value; 
                    $t_calendarLoader->setDue( $t_value ); 
                } 
                break; 
            /* 
             * Set iCal component PRIORITY property 
             */ 
            case 'priority': 
                $t_calendarLoader->setPriority( $t_value, get_enum_element( $t_element, $t_value )); 
                break; 
            /* 
             * Set iCal component STATUS property parameter 
             */ 
            case 'resolution': 
                $t_calendarLoader->setResolution( $t_element, get_enum_element( $t_element, $t_value )); 
                break; 
            /* 
             * Set iCal component CLASS property 
             */ 
            case 'view_state': 
                $t_calendarLoader->setClass( $t_value ); 
                break; 
            /* 
             * Used as iCal component STATUS property parameter 
             */ 
            case 'severity': 
                $t_calendarLoader->setSeverity( $t_element, get_enum_element( $t_element, $t_value )); 
                break; 
            /* 
             * Used as iCal component PRIORITY property parameter 
             */ 
            case 'reproducibility': 
                $t_calendarLoader->setReproducibility( $t_element, get_enum_element( $t_element, $t_value )); 
                break; 
            /* 
             * Set as iCal component STATUS property parameter 
             */ 
            case 'status': 
                $t_calendarLoader->setStatus( $t_value, get_enum_element( $t_element, $t_value )); 
                break; 
            case 'projection': 
                $t_calendarLoader->updateDescriptions( $t_element, get_enum_element( $t_element, $t_value )); 
                break; 
            /* 
             * Set iCal component SUMMARY property 
             */ 
            case 'summary': 
                $t_calendarLoader->setSummary( $t_value ); 
                break; 
            default: 
                $t_calendarLoader->updateDescriptions( $t_element, $t_value ); 
                break; 
        } // end switch( $t_element ) 
    } // end foreach( $t_columns as $t_ix2 => $t_element ) 
 
 
 
    /* 
     * Set iCal component LAST-MODIFIED property 
     */ 
    if( ! empty( $t_last_updated ) && ( $t_last_updated > $t_created )) { 
        $t_calendarLoader->setLastmodified( $t_last_updated ); 
    } 
 
    /* 
     * Create an iCal DUE date property, based on created (above), 
     * only if mantis due is not set and eta is set, 
     */ 
    if( empty( $t_due ) && ! empty( $t_eta )) { 
        $t_calendarLoader->setDue( $t_created, $t_eta ); 
    } 
 
    /* 
     * Export each mantis bug report bugnote as an iCal COMMENT 
     */ 
    $t_bugnot_users = []; 
    foreach( 
        (array) bugnote_get_all_visible_bugnotes( 
            $t_bug->id, 
            current_user_get_pref( 'bugnote_order' ), 
            0, 
            $t_user_id 
        ) 
        as $t_bugnote ) { 
        if(( BUGNOTE    == $t_bugnote->note_type )&& 
           ( VS_PRIVATE != $t_bugnote->view_state )) { 
            $t_name     = user_get_name( $t_bugnote->reporter_id ); 
            $t_email    = user_get_email( $t_bugnote->reporter_id ); 
            $t_calendarLoader->setComment( 
                $t_bugnote->note, 
                [ 
                    'id'             => $t_bugnote->id, 
                    'type'           => 'bugnote', 
                    'date-submitted' => date( $t_normal_date_format, $t_bugnote->date_submitted ), 
                    'name'           => $t_name, 
                ] 
            ); 
            if( isset( $t_bugnot_users[$t_email] )) { 
                $t_bugnot_users[$t_email]['id'][] = $t_bugnote->id; 
            } 
            else { 
                $t_bugnot_users[$t_email] = ['name' => $t_name, 'id' => [$t_bugnote->id]]; 
            } 
        } 
    } // end foreach 
    foreach( $t_bugnot_users as $t_email => $t_data ) { 
        $t_calendarLoader->updateAttendee( 
            $t_email, 
            $t_data['name'], 
            [ 'x-bugnote' => implode( ',', $t_data['id'] ) ] 
        ); 
    } 
 
    /* 
     * Export each mantis bug monitors as iCal ATTENDEEs 
     */ 
    foreach( ( array) bug_get_monitors( $t_bug->id ) as $t_monitor_id ) { 
        $t_calendarLoader->updateAttendee( 
            user_get_email( $t_monitor_id ), 
            user_get_name( $t_monitor_id ), 
            [ 'x-role' => 'monitor' ] 
        ); 
    } 
 
    /* 
     * Export each mantis bug report relations as an iCal RELATED-TOs 
     */ 
    foreach( ( array) relationship_get_all( $t_bug->id, $t_is_different_projects ) as $t_relationship ) { 
        if( $t_bug->id == $t_relationship->src_bug_id ) { 
            $t_reltype    = 'PARENT'; 
            $t_rel_bug_id = $t_relationship->dest_bug_id; 
        } 
        else { 
            $t_reltype    = 'CHILD'; 
            $t_rel_bug_id = $t_relationship->src_bug_id; 
        } 
        $t_rel_bug      = bug_get( $t_rel_bug_id ); 
        $date_submitted = $t_rel_bug->date_submitted; 
        $t_calendarLoader->setRelatedto( 
            CalendarLoader::renderUID( $date_submitted, $t_rel_bug_id, $t_unique_id ), 
            [ 
                'RELTYPE'          => $t_reltype, 
                'x-type'           => relationship_get_name_for_api( $t_relationship->type ), 
                'x-id'             => $t_rel_bug_id, 
                'x-date-submitted' => 
                    CalendarLoader::renderDate( $date_submitted, null, $t_normal_date_format ), 
                'x-summary'        => $t_rel_bug->summary, 
                'x-url'            => CalendarLoader::renderURL( $t_url, $t_rel_bug_id ) 
            ] 
        ); 
    } 
 
    /* 
     * export each mantis bug report tag(s) as (additional) iCal CATEGORIES 
     */ 
    if( $t_show_tags ) { 
        foreach( (array) tag_bug_get_attached( $t_bug->id ) as $t_tag ) { 
            $t_calendarLoader->setCategories( 
                $t_tag['name'], 
                [ 
                    'date-submitted' => date( $t_normal_date_format, $t_tag['date_attached'] ), 
                    'name'           => user_get_name( $t_tag['user_attached'] ), 
                    'origin' => 'tags', 
                ] 
            ); 
        } 
    } 
 
    /* 
     * Export each mantis bug report attachments as iCal ATTACHs (link) 
     */ 
    $t_calendarLoader->setAttachments( 
        (array) file_get_visible_attachments( $t_bug->id ), 
        $t_url 
    ); 
 
    /* 
     * Close Vtodo 
     */ 
    $t_calendarLoader->closeVtodo(); 
 
} // end foreach( $t_result as $t_bug ) 
 
if( empty( $t_cnt )) { 
    require_api( 'print_api.php' ); 
    print_header_redirect( $t_redirect_url ); 
} 
$t_calendarLoader->returnCalendar(); 
exit(); 
 
/** 
 * Return (first) startdate for bug assignment from bug_history 
 * 
 * @param int $p_bug_id 
 * @param int $p_user_id 
 * @return int|bool  timestamp or false (not found) 
 */ 
function get_assignment_start_date( $p_bug_id, $p_user_id ) { 
    static $t_fmt_query = 
        'SELECT date_modified FROM {bug_history} WHERE bug_id=%s AND field_name=%s AND new_value=%s ORDER BY 1'; 
    static $t_fmt_handler_id = 'handler_id'; 
    $t_query  = sprintf( $t_fmt_query, db_param(), db_param(), db_param()); 
    $t_result = db_query( $t_query, [ $p_bug_id, $t_fmt_handler_id, $p_user_id ] ); 
    $t_rows   = db_num_rows( $t_result ); 
    return ( empty( $t_rows )) ? false : (int) db_result( $t_result ); 
} 
/** 
 * Return number of rows (+1) in database table bug_history for bug_id as sequence number 
 * 
 * @param int $p_bug_id 
 * @return int 
 */ 
function get_bug_history_count( $p_bug_id ) { 
    static $t_fmt_query = 'SELECT COUNT(*) AS %s FROM {bug_history} WHERE bug_id=%s'; 
    static $t_fmt_antal = 'antal'; 
    $t_query  = sprintf( $t_fmt_query, $t_fmt_antal, db_param()); 
    $t_result = db_query( $t_query, [ $p_bug_id ] ); 
    $t_rows   = db_num_rows( $t_result ); 
    if( empty( $t_rows )) { 
        $t_result = 1; 
    } 
    else { 
        $row = db_fetch_array( $t_result ); 
        $t_result = (int) $row[$t_fmt_antal] + 1; 
    } 
    return $t_result; 
} 
 
 |