View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0010550 | mantisbt | feature | public | 2009-06-02 04:11 | 2009-06-26 12:02 |
Reporter | mravcek | Assigned To | siebrand | ||
Priority | normal | Severity | minor | Reproducibility | N/A |
Status | closed | Resolution | duplicate | ||
Summary | 0010550: Report issue via email | ||||
Description | Not sure but maybe somebody may be interested ... This is great tool - just forward your email to mantis account to add new issue. Issue will be created with attachments, project, category and filled custom fields How it works
| ||||
Tags | No tags attached. | ||||
Attached Files | add_new_issue_via_email_for_mantis.php (42,401 bytes)
<?php //This is great tool - just forward your email to mantis account to add new issue. Issue will be created with attachments, project, category and filled custom fields // This code is not perfect, but works ok if used properly. //How it works //1) Forward the email //To: your_imap_mantis_account@your_email_domain.com, assign_to_forename.surname1@your_email_domain.com, assign_to_forename.surname2@your_email_domain.com ... //CC: monitored_by_forename.surname@your_email_domain.com //2) Specify Project and Category //- emails with no project and category set will be placed in g_default_email_project_id with g_default_email_category //- The best way how to specify project and category is copy "Category" from existing emails received from mantis //Of course this works only in case you have enabled // # OFF, EMAIL_CATEGORY_PROJECT_CATEGORY (format: [Project] Category) // $g_email_set_category = ON; //- Or just set Category (In outlook go to Options->Categories) in format [Project] Category. //3) Add Custom fields // - Add text in your email body in folowwing format: //�<CustomFieldName: Value>� //For example: //Hello, //This project is for �<Customer: IBM>� and needs to be finished before �<Due Date: 16/05/2009>�. //Best regards, //ONLY String and Date (in format DD/MM/YYYY) are supported //4) Send the email //NOTE!! This works only in following conditions: //- user company emails are in format forename.surname@email_domain.com //- mantis users are in format ForenameSurename //- you have a imap account //- in imap account create following direcotries: ErrorMessages, Inbox, IssueCreatedAttachmentMissing, IssueOK, IssueWithWrongRequest //If you use different format of email <-> user name then you will need edit get_userID_from_email //Also, do not forget set all lines with EDIT_THIS_LINE // AND RUN THIS php FILE PERIODICALLY every 10 minutes :) $g_debug = 1; $g_accept_only_from = 'add_email_domain.com'; //EDIT_THIS_LINE: your email domain - only emails from this domain will be accepted $g_default_email_project_id = 1; //EDIT_THIS_LINE: all emials without specified project will be placed to this project $g_default_email_category = 'EMAILED'; //EDIT_THIS_LINE: This is default category //globals $htmlmsg = $plainmsg = $charset = ''; $attachments = array(); $g_project_id; $g_category; require_once( 'core.php' ); $t_core_path = config_get( 'core_path' ); require_once( $t_core_path.'bug_api.php' ); require_once( $t_core_path.'user_api.php' ); require_once( $t_core_path. 'email_api.php' ); require_once( $t_core_path. 'file_api.php' ); require_once( $t_core_path. 'custom_field_api.php' ); $g_t_bug_data = new BugData; echo "EMAIL receiver <br />"; //imap account settings $username = "your_imap_mantis_account"; //EDIT_THIS_LINE: imap account username (e.g mantis) - $password = "imap_password"; //EDIT_THIS_LINE: imap account password $mailserver = "XXX.XXX.XXX.XXX:XXX"; //EDIT_THIS_LINE: set imap server e.g 122.345.567.890:123 $mbox = imap_open("{XXX.XXX.XXX.XXX:XXX}", $username, $password); //EDIT_THIS_LINE: set imap server e.g 122.345.567.890:123 echo "Mailboxes<br />\n"; $folders = imap_listmailbox($mbox, "{XXX.XXX.XXX.XXX:XXX}", "*"); //EDIT_THIS_LINE: set imap server e.g 122.345.567.890:123 if ($folders == false) { echo "Call failed<br />\n"; } else { foreach ($folders as $val) { echo $val . "<br />\n"; } } //check if there are emails echo "Headers in INBOX<br />\n"; $headers = imap_headers($mbox); if ($headers == false) { echo "No emails found.<br />\n"; } else { foreach ($headers as $val) { echo $val . "<br />\n"; } } echo '<br>----------------------------------------------<br>'; echo 'Processing emails in INBOX<br>'; echo '----------------------------------------------<br>'; //specify what eamils need to be checked - curerntly ALL $m_search=imap_search ($mbox, 'ALL'); if ($m_search != null) { foreach ($m_search as $message_number) { //select header $header = imap_header($mbox, $message_number); //if email is ready to be deleted skip if ($header-> Deleted !='D') { //only new emails are inserted echo '<br>'.$message_number.' From: '; $from = $header->from; if ($from != null) { //go through field from: foreach ($from as $id => $object) { //there should be only one person in field FROM: $fromname = $object->personal; echo $fromname.' '; $fromaddress = $object->mailbox . "@" . $object->host; echo '('.$fromaddress.'), '; //from field is used to set reporter $g_p_bug_data->reporter_id = get_userID_from_email($object->mailbox); if ($g_p_bug_data->reporter_id == 0) { echo '<br>Error: Unknow user - '.$g_p_bug_data->reporter_id.'<br>'; break; } //set project and category based on header field called keywords if (get_project_id_and_category($mbox, $message_number,$g_p_bug_data->reporter_id) == false) {//will by copied to direcory with emails wrong requests if (!imap_mail_copy($mbox,$message_number,"IssueWithWrongRequest")) echo "<br>ERROR: Message '.$message_number.' can not be copied!<br>"; } $g_p_bug_data->project_id = $g_project_id; $g_p_bug_data->category = $g_category; //subject //subject needs to be cleaned from hidden characters before is inserted to database $g_p_bug_data->summary = clean_text($header->subject); //this will separate body from attachments - outputs are in plainmsg and attachments getmsg($mbox,$message_number); //body needs to be cleaned from hidden characters befor is inserted to database $g_p_bug_data->description = clean_text($plainmsg); } } //check if email has been sent from enabled domane and summary and desriptions are no empty then check other fields if (($object->host==$g_accept_only_from) AND ($g_p_bug_data->summary != null) AND ($g_p_bug_data->description != null)) { echo ' Assigned to: '; $from = $header->to; if ($from != null) { foreach ($from as $id => $object) { //start checking field To: if ($object->mailbox != $username) //skip tracker address { //this is username before @ echo $object->mailbox.', '; //set assigned to: but first get user id from realname $assigned_to = get_userID_from_email($object->mailbox); if ($assigned_to == false){ //check if user has been recognised echo '<br>ERROR: Unknown user for assigmned: '.$object->mailbox.'.<br>'; } else{ //username is valid - assigne the issue to the user $g_p_bug_data->handler_id = $assigned_to; //place the new bug $bug_id = insert_new_bug_to_db($mbox, $message_number); //set custom fields set_custom_fields_for_issue ($plainmsg,$bug_id); //check if there are people in CC: - these will monitor the isseu if (($bug_id != 0) AND ($header->cc != null)) {//if bug has been created and there are people in bcc echo 'Users monitoring this issue: '; $add_monitor_list = $header->cc; foreach ($add_monitor_list as $id1 => $add_monitor) { //for everybody from CC get user ID $monitoring_person = get_userID_from_email($add_monitor->mailbox); //check if user exists if ($monitoring_person == false){ echo '<br>ERROR: Unknown user added for monitoring: '.$add_monitor->mailbox.'.<br>'; } else{ //user exists - add him to monitor issue echo $add_monitor->mailbox.', '; add_person_monitor_issue ($bug_id,$monitoring_person); //add people from bcc to monitor the issue } } } } } } } } else { //email sent from not allowed domain, no subject or no body echo '<br>ERROR: Email with error moved to ErrorMessages folder.<br>'; if (!imap_mail_move($mbox,$message_number,"ErrorMessages")) echo "<br>ERROR: Message '.$message_number.' can not be moved!<br>"; } } } } else echo "No emails to process."; imap_expunge($mbox);//delete all messages marked for deletion imap_close($mbox); echo "<br />END"; /**********************************************************************************************************************/ /*****************************************FUNCTIONS*****************************************************************/ /**********************************************************************************************************************/ function set_custom_fields_for_issue($string,$bug_id) { $g_custom_fields_array = array(); //echo ' '.$string.' '; echo "<br>Looking for custom fields ... "; //find category - they are in header after: Keywords |<[^>]+>(.*)</[^>]+>|U $pattern = "|\"[^<]?<(.*)>[^\"]?\"|U"; preg_match_all($pattern, $string, $custom_fields,PREG_PATTERN_ORDER); foreach ($custom_fields[1] as $custom_field) { //check if the cusotm field is valid $custom_field_name = explode(":",$custom_field); echo ' <br> checking: '.$custom_field_name[0].'... '; $custom_field_id = custom_field_get_id_from_name($custom_field_name[0]); if ($custom_field_id) { echo 'valid. (ID = '.$custom_field_id.')'; $g_custom_fields_array[$custom_field_id] = trim ($custom_field_name[1]);//copy to array but remove before space from beginning and end } else echo 'invalid!'; } echo "<br>Adding custom fields: "; foreach ($g_custom_fields_array as $field_id => $field_data) { echo $field_id.'='.$field_data; switch (tmp_custom_field_type($field_id)) { case 8: //date $field_data = string_to_date($field_data); case 0: //text if (tmp_custom_field_set_value( $field_id, $bug_id, $field_data )==true) echo ' (Added OK); '; else echo ' (Error); '; break; default: //unsuported field type echo " (Unsupported field type); "; } } echo "<br><br>"; } //this converts any format of dd/mm/yyyy to timestamp function string_to_date($string) { if (preg_match('/^\s*(\d\d?)[^\w](\d\d?)[^\w](\d{1,4}\s*$)/', $string, $match)) { $string = $match[2] . '/' . $match[1] . '/' . $match[3]; } return strtotime($string); } //this will return user id from email format name: Forename.Surname in case users in Manits are users in format ForenameSurname function get_userID_from_email($mail_address) { //remove . from email an make username ... Forename.Surname -> ForenameSurname $tmp = explode(".",$mail_address); $reporter = $tmp[0].$tmp[1]; //return user ID return user_get_id_by_name($reporter); } //this will find in email header fields under Keywords (Categories) and decode standard Mantis Category format: Keywords:[Project] Category function get_project_id_and_category($mbox, $message_number,$user_id) { global $g_project_id, $g_category; global $g_default_email_project_id; global $g_default_email_category; $g_project_id =0; $g_category =''; $fetchheader = imap_fetchheader ( $mbox, $message_number); //find category - they are in header after: Keywords $pattern = "/Keywords:?.*(Message-ID:)?/"; preg_match($pattern,$fetchheader, $keywords); //get project name from Field Keywords: $pattern = "/(?P<foo>\[)(.*)(?P<bar>\])/"; preg_match($pattern,$keywords[0], $projects); //get project ID from name $g_project_id = project_get_id_by_name($projects[2]); //check permission $t_user_access_level = user_get_access_level( $user_id, $g_project_id ); //get category name from Field Keywords: $pattern = "/(?P<foo>\].)(.*)(?P<bar>.)/"; preg_match($pattern,$keywords[0], $categories); $g_category = $categories[2]; echo '<br>Project: '.$projects[2].' / ID: '.$g_project_id.' / Permision: '.$t_user_access_level.' / Category: '.$g_category.'<br>'; if ((($t_user_access_level < REPORTER) OR ($g_category == null) OR ($g_project_id==0)) AND ($keywords[0]!= null)) {//error if keywords found in header but don't mach any project, category or if user doesn't have permision for the project echo "Permission or category error - project and category set to default<br>"; //use default project and category $g_project_id = $g_default_email_project_id; $g_category = $g_default_email_category; return false; } if ($keywords[0] == null) {//if project and category are not in email header then use default project and category $g_project_id = $g_default_email_project_id; $g_category = $g_default_email_category; } return true; } //this will insert new bug and attachments function insert_new_bug_to_db($mbox, $message_number) { global $g_debug,$g_p_bug_data; global $htmlmsg,$plainmsg,$charset,$attachments; echo '<br>Creating new issue ...'; # Create the bug // $g_p_bug_data->summary = 'TEST FROM EMAIL RECEIVER'; // $g_p_bug_data->description = 'This was created by email_receiver'; // $g_p_bug_data->project_id = 51; //51 = Test // $g_p_bug_data->reporter_id = 8 ; //8 - user // $g_p_bug_data->handler_id = 8; //8 - user $g_p_bug_data->priority = 30; //30=normal $g_p_bug_data->severity = 50; //50=minor $g_p_bug_data->reproducibility = 100; //N/A // $g_p_bug_data->category = 'EMAILED'; $g_p_bug_data->os = ''; $g_p_bug_data->os_build = ''; $g_p_bug_data->platform = ''; $g_p_bug_data->version = ''; $g_p_bug_data->build = ''; $g_p_bug_data->profile_id = 0; $g_p_bug_data->view_state = 10; $g_p_bug_data->steps_to_reproduce = ''; $g_p_bug_data->additional_information = ''; if ($g_debug==1) { echo '<br>$g_p_bug_data->summary = '.$g_p_bug_data->summary; echo '<br>$g_p_bug_data->description = '.$g_p_bug_data->description; echo '<br>$g_p_bug_data->project_id = '.$g_p_bug_data->project_id; echo '<br>$g_p_bug_data->reporter_id = '.$g_p_bug_data->reporter_id; echo '<br>$g_p_bug_data->handler_id = '.$g_p_bug_data->handler_id; echo '<br>$g_p_bug_data->priority = '.$g_p_bug_data->priority; echo '<br>$g_p_bug_data->severity = '.$g_p_bug_data->severity; echo '<br>$g_p_bug_data->reproducibility = '.$g_p_bug_data->reproducibility; echo '<br>$g_p_bug_data->category = '.$g_p_bug_data->category; echo '<br>$g_p_bug_data->os = '.$g_p_bug_data->os; echo '<br>$g_p_bug_data->os_build = '.$g_p_bug_data->os_build; echo '<br>$g_p_bug_data->platform = '.$g_p_bug_data->platform; echo '<br>$g_p_bug_data->version = '.$g_p_bug_data->version; echo '<br>$g_p_bug_data->build = '.$g_p_bug_data->build; echo '<br>$g_p_bug_data->profile_id = '.$g_p_bug_data->profile_id; echo '<br>$g_p_bug_data->view_state = '.$g_p_bug_data->view_state; echo '<br>$g_p_bug_data->steps_to_reproduce = '.$g_p_bug_data->steps_to_reproduce; echo '<br>$g_p_bug_data->additional_information = '.$g_p_bug_data->additional_information; } //when debugged rename tmp_bug_create to bug_create $t_bug_id = tmp_bug_create( $g_p_bug_data ); //this is standard mantis function but i had to remove logging because of problems when file runs frpm php command line echo '<br>New issue submitted: ',$t_bug_id.'<br>'; # Handle attachments if ($attachments!=null){ $add_attachment_error =0; echo '<br>Attachemet(s): '; foreach ($attachments as $filename => $data) { echo $filename.', '; //add all attachments if (!add_attachement( $t_bug_id, $filename, $data, tmp_mime_content_type($filename), 'bug' )) $add_attachment_error++; //if return false then error adding attachments } if (!$add_attachment_error) {//ATTACHMENTS added ok - move email to OK directory if (!imap_mail_move($mbox,$message_number,"IssueOK")) echo "<br>ERROR: Message '.$message_number.' can not be moved!<br>"; } else {//ATTACHMENTS need to be added again - move email to error directory if (!imap_mail_move($mbox,$message_number,"IssueCreatedAttachmentMissing")) echo "<br>ERROR: Message '.$message_number.' can not be moved!<br>"; } } else {//if tehre are no attachments just move to IssueOK directory if (!imap_mail_move($mbox,$message_number,"IssueOK")) echo "<br>ERROR: Message '.$message_number.' can not be moved!<br>"; } //send notification //email_new_bug( $t_bug_id ); //this is doing problem when runs wrom php command line //echo "<br>OK<br>"; return $t_bug_id; } //used together with getpart to extract body and attachments from email function getmsg($mbox,$mid) { // input $mbox = IMAP stream, $mid = message id // output all the following: global $htmlmsg,$plainmsg,$charset,$attachments; // the message may in $htmlmsg, $plainmsg, or both $htmlmsg = $plainmsg = $charset = ''; $attachments = array(); // HEADER $h = imap_header($mbox,$mid); // add code here to get date, from, to, cc, subject... // BODY $s = imap_fetchstructure($mbox,$mid); if (!$s->parts) // not multipart getpart($mbox,$mid,$s,0); // no part-number, so pass 0 else { // multipart: iterate through each part foreach ($s->parts as $partno0=>$p) getpart($mbox,$mid,$p,$partno0+1); } } //used together with getmsg to extract body and attachments from email function getpart($mbox,$mid,$p,$partno) { // $partno = '1', '2', '2.1', '2.1.3', etc if multipart, 0 if not multipart global $htmlmsg,$plainmsg,$charset,$attachments; // DECODE DATA $data = ($partno)? imap_fetchbody($mbox,$mid,$partno): // multipart imap_body($mbox,$mid); // not multipart // Any part may be encoded, even plain text messages, so check everything. if ($p->encoding==4) $data = quoted_printable_decode($data); elseif ($p->encoding==3) $data = base64_decode($data); // no need to decode 7-bit, 8-bit, or binary // PARAMETERS // get all parameters, like charset, filenames of attachments, etc. $params = array(); if ($p->parameters) foreach ($p->parameters as $x) $params[ strtolower( $x->attribute ) ] = $x->value; if ($p->dparameters) foreach ($p->dparameters as $x) $params[ strtolower( $x->attribute ) ] = $x->value; // ATTACHMENT // Any part with a filename is an attachment, // so an attached text file (type 0) is not mistaken as the message. if ($params['filename'] || $params['name']) { // filename may be given as 'Filename' or 'Name' or both $filename = ($params['filename'])? $params['filename'] : $params['name']; // filename may be encoded, so see imap_mime_header_decode() $attachments[$filename] = $data; // this is a problem if two files have same name } // TEXT elseif ($p->type==0 && $data) { // Messages may be split in different parts because of inline attachments, // so append parts together with blank row. if (strtolower($p->subtype)=='plain') $plainmsg .= trim($data) ."\n\n"; else $htmlmsg .= $data ."<br><br>"; $charset = $params['charset']; // assume all parts are same charset } // EMBEDDED MESSAGE // Many bounce notifications embed the original message as type 2, // but AOL uses type 1 (multipart), which is not handled here. // There are no PHP functions to parse embedded messages, // so this just appends the raw source to the main message. elseif ($p->type==2 && $data) { $plainmsg .= trim($data) ."\n\n"; } // SUBPART RECURSION if ($p->parts) { foreach ($p->parts as $partno0=>$p2) getpart($mbox,$mid,$p2,$partno.'.'.($partno0+1)); // 1.2, 1.2.1, etc. } } //copied form matis and cleaned from errors - this will add attachment to issue function add_attachement( $p_id, $p_name, $p_content, $p_file_type, $p_table, $p_title = '', $p_desc = '' ) { if ( !file_type_check( $p_name ) ) { echo 'file_type_error'; return false; } if ( !file_is_name_unique( $p_name, $p_id ) ) { echo 'file_is_name_error'; return false; } $t_file_size = strlen( $p_content ); $t_max_file_size = (int)min( ini_get_number( 'upload_max_filesize' ), ini_get_number( 'post_max_size' ), config_get( 'max_file_size' ) ); if ( $t_file_size > $t_max_file_size ) { echo 'file_is_too_big_error'; return false; } if ( 'bug' == $p_table ) { $t_project_id = bug_get_field( $p_id, 'project_id' ); $t_issue_id = bug_format_id( $p_id ); } else { $t_project_id = $p_id; $t_issue_id = 0; } # prepare variables for insertion $c_issue_id = db_prepare_int( $t_issue_id ); $c_project_id = db_prepare_int( $t_project_id ); $c_file_type = db_prepare_string( $p_file_type ); $c_title = db_prepare_string( $p_title ); $c_desc = db_prepare_string( $p_desc ); if( $t_project_id == ALL_PROJECTS ) { $t_file_path = config_get( 'absolute_path_default_upload_folder' ); } else { $t_file_path = project_get_field( $t_project_id, 'file_path' ); if( $t_file_path == '' ) { $t_file_path = config_get( 'absolute_path_default_upload_folder' ); } } $c_file_path = db_prepare_string( $t_file_path ); $c_new_file_name = db_prepare_string( $p_name ); $t_file_hash = $t_issue_id; $t_disk_file_name = $t_file_path . file_generate_unique_name( $t_file_hash . '-' . $p_name, $t_file_path ); $c_disk_file_name = db_prepare_string( $t_disk_file_name ); $t_file_size = strlen( $p_content ); $c_file_size = db_prepare_int( $t_file_size ); $t_method = config_get( 'file_upload_method' ); switch ( $t_method ) { case FTP: case DISK: if ( !file_exists( $t_file_path ) || !is_dir( $t_file_path ) || !is_writable( $t_file_path ) || !is_readable( $t_file_path ) ) { echo 'upload_folder_does_not_exist_error'; return false; } file_ensure_valid_upload_path( $t_file_path ); if ( !file_exists( $t_disk_file_name ) ) { tmp_file_write_local( $t_disk_file_name, $p_content ); if ( FTP == $t_method ) { $conn_id = file_ftp_connect(); file_ftp_put ( $conn_id, $t_disk_file_name, $t_disk_file_name ); file_ftp_disconnect ( $conn_id ); file_delete_local( $p_disk_file_name ); } chmod( $t_disk_file_name, config_get( 'attachments_file_permissions' ) ); $c_content = ''; } break; case DATABASE: $c_content = db_prepare_string( $p_content ); break; } $t_file_table = config_get( 'mantis_' . $p_table . '_file_table' ); $c_id = ( 'bug' == $p_table ) ? $c_issue_id : $c_project_id; $query = "INSERT INTO $t_file_table (" . $p_table . "_id, title, description, diskfile, filename, folder, filesize, file_type, date_added, content) VALUES ($c_id, '$c_title', '$c_desc', '$c_disk_file_name', '$c_new_file_name', '$c_file_path', $c_file_size, '$c_file_type', " . db_now() .", '$c_content')"; db_query( $query ); # get attachment id $t_attachment_id = db_insert_id( $t_file_table ); if ( 'bug' == $p_table ) { # updated the last_updated date $result = bug_update_date( $c_issue_id ); # log new bug // history_log_event_special( $c_issue_id, FILE_ADDED, $c_new_file_name ); } return $t_attachment_id; } # Write a local file - used with add attachments. function tmp_file_write_local( $p_diskfile, $p_content ) { $t_handle = fopen( $p_diskfile, "w" ); fwrite( $t_handle, $p_content ); fclose( $t_handle ); } //used when attachment is added - file format needs to be identified function tmp_mime_content_type($filename) { $mime_types = array( 'txt' => 'text/plain', 'htm' => 'text/html', 'html' => 'text/html', 'php' => 'text/html', 'css' => 'text/css', 'js' => 'application/javascript', 'json' => 'application/json', 'xml' => 'application/xml', 'swf' => 'application/x-shockwave-flash', 'flv' => 'video/x-flv', // images 'png' => 'image/png', 'jpe' => 'image/jpeg', 'jpeg' => 'image/jpeg', 'jpg' => 'image/jpeg', 'gif' => 'image/gif', 'bmp' => 'image/bmp', 'ico' => 'image/vnd.microsoft.icon', 'tiff' => 'image/tiff', 'tif' => 'image/tiff', 'svg' => 'image/svg+xml', 'svgz' => 'image/svg+xml', // archives 'zip' => 'application/zip', 'rar' => 'application/x-rar-compressed', 'exe' => 'application/x-msdownload', 'msi' => 'application/x-msdownload', 'cab' => 'application/vnd.ms-cab-compressed', // audio/video 'mp3' => 'audio/mpeg', 'qt' => 'video/quicktime', 'mov' => 'video/quicktime', // adobe 'pdf' => 'application/pdf', 'psd' => 'image/vnd.adobe.photoshop', 'ai' => 'application/postscript', 'eps' => 'application/postscript', 'ps' => 'application/postscript', // ms office 'doc' => 'application/msword', 'rtf' => 'application/rtf', 'xls' => 'application/vnd.ms-excel', 'ppt' => 'application/vnd.ms-powerpoint', // open office 'odt' => 'application/vnd.oasis.opendocument.text', 'ods' => 'application/vnd.oasis.opendocument.spreadsheet', ); $ext = strtolower(array_pop(explode('.',$filename))); if (array_key_exists($ext, $mime_types)) { return $mime_types[$ext]; } elseif (function_exists('finfo_open')) { $finfo = finfo_open(FILEINFO_MIME); $mimetype = finfo_file($finfo, $filename); finfo_close($finfo); return $mimetype; } else { return 'application/octet-stream'; } } //this will clean body and subject from hidden characters - otherwise text is not possible upload to database function clean_text($str) { $force_php = false; // UTF-8 validity is checked since PHP 4.3.5 // This is an optimization: if the string is already valid UTF-8, no // need to do PHP stuff. 99% of the time, this will be the case. // The regexp matches the XML char production, as well as well as excluding // non-SGML codepoints U+007F to U+009F if (preg_match('/^[\x{9}\x{A}\x{D}\x{20}-\x{7E}\x{A0}-\x{D7FF}\x{E000}-\x{FFFD}\x{10000}-\x{10FFFF}]*$/Du', $str)) { return $str; } $mState = 0; // cached expected number of octets after the current octet // until the beginning of the next UTF8 character sequence $mUcs4 = 0; // cached Unicode character $mBytes = 1; // cached expected number of octets in the current sequence // original code involved an $out that was an array of Unicode // codepoints. Instead of having to convert back into UTF-8, we've // decided to directly append valid UTF-8 characters onto a string // $out once they're done. $char accumulates raw bytes, while $mUcs4 // turns into the Unicode code point, so there's some redundancy. $out = ''; $char = ''; $len = strlen($str); for($i = 0; $i < $len; $i++) { $in = ord($str{$i}); $char .= $str[$i]; // append byte to char if (0 == $mState) { // When mState is zero we expect either a US-ASCII character // or a multi-octet sequence. if (0 == (0x80 & ($in))) { // US-ASCII, pass straight through. if (($in <= 31 || $in == 127) && !($in == 9 || $in == 13 || $in == 10) // save \r\t\n ) { // control characters, remove } else { $out .= $char; } // reset $char = ''; $mBytes = 1; } elseif (0xC0 == (0xE0 & ($in))) { // First octet of 2 octet sequence $mUcs4 = ($in); $mUcs4 = ($mUcs4 & 0x1F) << 6; $mState = 1; $mBytes = 2; } elseif (0xE0 == (0xF0 & ($in))) { // First octet of 3 octet sequence $mUcs4 = ($in); $mUcs4 = ($mUcs4 & 0x0F) << 12; $mState = 2; $mBytes = 3; } elseif (0xF0 == (0xF8 & ($in))) { // First octet of 4 octet sequence $mUcs4 = ($in); $mUcs4 = ($mUcs4 & 0x07) << 18; $mState = 3; $mBytes = 4; } elseif (0xF8 == (0xFC & ($in))) { // First octet of 5 octet sequence. // // This is illegal because the encoded codepoint must be // either: // (a) not the shortest form or // (b) outside the Unicode range of 0-0x10FFFF. // Rather than trying to resynchronize, we will carry on // until the end of the sequence and let the later error // handling code catch it. $mUcs4 = ($in); $mUcs4 = ($mUcs4 & 0x03) << 24; $mState = 4; $mBytes = 5; } elseif (0xFC == (0xFE & ($in))) { // First octet of 6 octet sequence, see comments for 5 // octet sequence. $mUcs4 = ($in); $mUcs4 = ($mUcs4 & 1) << 30; $mState = 5; $mBytes = 6; } else { // Current octet is neither in the US-ASCII range nor a // legal first octet of a multi-octet sequence. $mState = 0; $mUcs4 = 0; $mBytes = 1; $char = ''; } } else { // When mState is non-zero, we expect a continuation of the // multi-octet sequence if (0x80 == (0xC0 & ($in))) { // Legal continuation. $shift = ($mState - 1) * 6; $tmp = $in; $tmp = ($tmp & 0x0000003F) << $shift; $mUcs4 |= $tmp; if (0 == --$mState) { // End of the multi-octet sequence. mUcs4 now contains // the final Unicode codepoint to be output // Check for illegal sequences and codepoints. // From Unicode 3.1, non-shortest form is illegal if (((2 == $mBytes) && ($mUcs4 < 0x0080)) || ((3 == $mBytes) && ($mUcs4 < 0x0800)) || ((4 == $mBytes) && ($mUcs4 < 0x10000)) || (4 < $mBytes) || // From Unicode 3.2, surrogate characters = illegal (($mUcs4 & 0xFFFFF800) == 0xD800) || // Codepoints outside the Unicode range are illegal ($mUcs4 > 0x10FFFF) ) { } elseif (0xFEFF != $mUcs4 && // omit BOM // check for valid Char unicode codepoints ( 0x9 == $mUcs4 || 0xA == $mUcs4 || 0xD == $mUcs4 || (0x20 <= $mUcs4 && 0x7E >= $mUcs4) || // 7F-9F is not strictly prohibited by XML, // but it is non-SGML, and thus we don't allow it (0xA0 <= $mUcs4 && 0xD7FF >= $mUcs4) || (0x10000 <= $mUcs4 && 0x10FFFF >= $mUcs4) ) ) { $out .= $char; } // initialize UTF8 cache (reset) $mState = 0; $mUcs4 = 0; $mBytes = 1; $char = ''; } } else { // ((0xC0 & (*in) != 0x80) && (mState != 0)) // Incomplete multi-octet sequence. // used to result in complete fail, but we'll reset $mState = 0; $mUcs4 = 0; $mBytes = 1; $char =''; } } } return $out; } //copied from Mantis - will add person to monitor issue - currently cleaned from some stuff doing error when runs from php command line function add_person_monitor_issue ($f_bug_id,$user_id) { # Automically add recipients to monitor list if they are above the monitor # threshold, option is enabled, and not reporter or handler. if ( ON == config_get( 'reminder_recipents_monitor_bug' ) ){ // access_has_bug_level( config_get( 'monitor_bug_threshold' ), $f_bug_id ) && // !bug_is_user_handler( $f_bug_id, $user_id ) && // !bug_is_user_reporter( $f_bug_id, $user_id ) ) { bug_monitor( $f_bug_id, $user_id ); } // $result = email_bug_reminder( $user_id, $f_bug_id, "You were added to monitor this issue." ); /* # Add reminder as bugnote if store reminders option is ON. if ( ON == config_get( 'store_reminders' ) ) { if ( count( $f_to ) > 50 ) { # too many recipients to log, truncate the list $t_to = array(); for ( $i=0; $i<50; $i++ ) { $t_to[] = $f_to[$i]; } $f_to = $t_to; } $t_attr = '|' . implode( '|', $f_to ) . '|'; bugnote_add( $f_bug_id, $f_body, 0, config_get( 'default_reminder_view_status' ) == VS_PRIVATE, REMINDER, $t_attr, NULL, FALSE ); } */ } //copied form Mantis and cleaned from logging - this was doing problem when runs from php commandline function tmp_bug_create( $p_bug_data ) { $c_summary = db_prepare_string( $p_bug_data->summary ); $c_description = db_prepare_string( $p_bug_data->description ); $c_project_id = db_prepare_int( $p_bug_data->project_id ); $c_reporter_id = db_prepare_int( $p_bug_data->reporter_id ); $c_handler_id = db_prepare_int( $p_bug_data->handler_id ); $c_priority = db_prepare_int( $p_bug_data->priority ); $c_severity = db_prepare_int( $p_bug_data->severity ); $c_reproducibility = db_prepare_int( $p_bug_data->reproducibility ); $c_category = db_prepare_string( $p_bug_data->category ); $c_os = db_prepare_string( $p_bug_data->os ); $c_os_build = db_prepare_string( $p_bug_data->os_build ); $c_platform = db_prepare_string( $p_bug_data->platform ); $c_version = db_prepare_string( $p_bug_data->version ); $c_build = db_prepare_string( $p_bug_data->build ); $c_profile_id = db_prepare_int( $p_bug_data->profile_id ); $c_view_state = db_prepare_int( $p_bug_data->view_state ); $c_steps_to_reproduce = db_prepare_string( $p_bug_data->steps_to_reproduce ); $c_additional_info = db_prepare_string( $p_bug_data->additional_information ); $c_sponsorship_total = 0; $c_sticky = 0; # Summary cannot be blank if ( is_blank( $c_summary ) ) { error_parameters( lang_get( 'summary' ) ); trigger_error( ERROR_EMPTY_FIELD, ERROR ); } # Description cannot be blank if ( is_blank( $c_description ) ) { error_parameters( lang_get( 'description' ) ); trigger_error( ERROR_EMPTY_FIELD, ERROR ); } # If category is not specified and not defaulted + project has categories defined, then error. if ( is_blank( $c_category ) && ( category_get_count( $c_project_id ) > 0 ) ) { error_parameters( lang_get( 'category' ) ); trigger_error( ERROR_EMPTY_FIELD, ERROR ); } # Only set target_version if user has access to do so // if ( access_has_project_level( config_get( 'roadmap_update_threshold' ) ) ) { $c_target_version = db_prepare_string( $p_bug_data->target_version ); // } else { // $c_target_version = ''; // } // echo '>tmp_bug_create06 ... '; $t_bug_table = config_get( 'mantis_bug_table' ); $t_bug_text_table = config_get( 'mantis_bug_text_table' ); $t_project_category_table = config_get( 'mantis_project_category_table' ); # Insert text information $query = "INSERT INTO $t_bug_text_table ( description, steps_to_reproduce, additional_information ) VALUES ( '$c_description', '$c_steps_to_reproduce', '$c_additional_info' )"; db_query( $query ); # Get the id of the text information we just inserted # NOTE: this is guarranteed to be the correct one. # The value LAST_INSERT_ID is stored on a per connection basis. $t_text_id = db_insert_id($t_bug_text_table); # check to see if we want to assign this right off $t_status = config_get( 'bug_submit_status' ); # if not assigned, check if it should auto-assigned. if ( 0 == $c_handler_id ) { # if a default user is associated with the category and we know at this point # that that the bug was not assigned to somebody, then assign it automatically. $query = "SELECT user_id FROM $t_project_category_table WHERE project_id='$c_project_id' AND category='$c_category'"; $result = db_query( $query ); if ( db_num_rows( $result ) > 0 ) { $c_handler_id = $p_handler_id = db_result( $result ); } } # Check if bug was pre-assigned or auto-assigned. if ( ( $c_handler_id != 0 ) && ( ON == config_get( 'auto_set_status_to_assigned' ) ) ) { $t_status = config_get( 'bug_assigned_status' ); } # Insert the rest of the data $t_resolution = OPEN; $query = "INSERT INTO $t_bug_table ( project_id, reporter_id, handler_id, duplicate_id, priority, severity, reproducibility, status, resolution, projection, category, date_submitted, last_updated, eta, bug_text_id, os, os_build, platform, version, build, profile_id, summary, view_state, sponsorship_total, sticky, fixed_in_version, target_version ) VALUES ( '$c_project_id', '$c_reporter_id', '$c_handler_id', '0', '$c_priority', '$c_severity', '$c_reproducibility', '$t_status', '$t_resolution', 10, '$c_category', " . db_now() . "," . db_now() . ", 10, '$t_text_id', '$c_os', '$c_os_build', '$c_platform', '$c_version', '$c_build', '$c_profile_id', '$c_summary', '$c_view_state', '$c_sponsorship_total', '$c_sticky', '', '$c_target_version' )"; db_query( $query ); $t_bug_id = db_insert_id($t_bug_table); return $t_bug_id; } function tmp_custom_field_set_value( $p_field_id, $p_bug_id, $p_value ) { echo '> Debug 04 '; $c_field_id = db_prepare_int( $p_field_id ); $c_bug_id = db_prepare_int( $p_bug_id ); echo '> Debug 05 '; custom_field_ensure_exists( $p_field_id ); echo '> Debug 06 '; $t_custom_field_table = config_get( 'mantis_custom_field_table' ); $query = "SELECT name, type, possible_values, valid_regexp, access_level_rw, length_min, length_max, default_value FROM $t_custom_field_table WHERE id='$c_field_id'"; $result = db_query( $query ); echo '> Debug 07 '; $row = db_fetch_array( $result ); $t_name = $row['name']; $t_type = $row['type']; $t_possible_values = $row['possible_values']; $t_valid_regexp = $row['valid_regexp']; $t_access_level_rw = $row['access_level_rw']; $t_length_min = $row['length_min']; $t_length_max = $row['length_max']; $t_default_value = $row['default_value']; echo '> Debug 08 '; $c_value = db_prepare_string( custom_field_value_to_database( $p_value, $t_type ) ); echo '> Debug 09 '; # check for valid value if ( !is_blank( $t_valid_regexp ) ) { if ( !ereg( $t_valid_regexp, $p_value ) ) { return false; } } echo '> Debug 10 '; if ( strlen( $p_value ) < $t_length_min ) { return false; } echo '> Debug 11 '; if ( ( 0 != $t_length_max ) && ( strlen( $p_value ) > $t_length_max ) ) { return false; } echo '> Debug 12 '; //this checking is making problem - but it is not necessary to check it // if( !custom_field_has_write_access( $p_field_id, $p_bug_id, auth_get_current_user_id() ) ) { // return false; // } echo '> Debug 13 '; $t_custom_field_string_table = config_get( 'mantis_custom_field_string_table' ); # do I need to update or insert this value? $query = "SELECT value FROM $t_custom_field_string_table WHERE field_id='$c_field_id' AND bug_id='$c_bug_id'"; $result = db_query( $query ); echo '> Debug 14 '; if ( db_num_rows( $result ) > 0 ) { $query = "UPDATE $t_custom_field_string_table SET value='$c_value' WHERE field_id='$c_field_id' AND bug_id='$c_bug_id'"; db_query( $query ); $row = db_fetch_array( $result ); // history_log_event_direct( $c_bug_id, $t_name, custom_field_database_to_value( $row['value'], $t_type ), $p_value ); } else { # Always store the value, even if it's the dafault value # This is important, as the definitions might change but the # values stored with a bug must not change $query = "INSERT INTO $t_custom_field_string_table ( field_id, bug_id, value ) VALUES ( '$c_field_id', '$c_bug_id', '$c_value' )"; db_query( $query ); // history_log_event_direct( $c_bug_id, $t_name, '', $p_value ); } echo '> Debug 15 '; custom_field_clear_cache( $p_field_id ); echo '> Debug 16 '; #db_query() errors on failure so: return true; } function tmp_custom_field_type( $p_field_id ) { echo '> Debug 17 '; $t_field = tmp_custom_field_cache_row( $p_field_id, false ) ; echo '> Debug 18 '; if ( $t_field == false ) { return -1 ; } else { return $t_field[ 'type' ] ; } } function tmp_custom_field_cache_row( $p_field_id, $p_trigger_errors=true ) { global $g_cache_custom_field; echo '> Debug 19 '; $c_field_id = db_prepare_int( $p_field_id ); echo '> Debug 20 '; $t_custom_field_table = config_get( 'mantis_custom_field_table' ); echo '> Debug 21 '; if ( isset ( $g_cache_custom_field[$c_field_id] ) ) { return $g_cache_custom_field[$c_field_id]; } echo '> Debug 22 '; $query = "SELECT * FROM $t_custom_field_table WHERE id='$c_field_id'"; $result = db_query( $query ); echo '> Debug 23 '; if ( 0 == db_num_rows( $result ) ) { if ( $p_trigger_errors ) { // error_parameters( 'Custom ' . $p_field_id ); // trigger_error( ERROR_CUSTOM_FIELD_NOT_FOUND, ERROR ); } else { return false; } } $row = db_fetch_array( $result ); echo '> Debug 24 '; $g_cache_custom_field[$c_field_id] = $row; echo '> Debug 25 '; return $row; } ?> | ||||