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;
}
?>
| ||||