<?php
# --------------------------------------------------------
# mantis_perforce
# Basic Perforce Integration with Mantis Bug Tracker
# Copyright (C) 2004 T-VEC Technologies, Inc.
# This program is distributed under the terms and conditions of the GPL
# --------------------------------------------------------

# Mantis is a php based bugtracking system (http://mantisbt.sourceforge.net)
# Perforce is a source control tool (http://mantisbt.sourceforge.net)
# This script monitors the changelists submitted to Perforce.  When it
# detects a new changelist, it checks the changelist for a bug id in the
# form "Bug ###" where ### represents a numeric identifier.  If it locates
# a bug id, it adds a bugnote to the bug in mantis with the contents of
# the changelist.

# This script requires access to the Mantis API.  It uses the mantis
# configuation settings for contacting mantis server. It also requires the
# perforce p4 client.  To get the script working, configure the perforce
# host and port.  Specify the location of mantis on the filesystem.  You
# can also change the name of the log file and polling interval.

# This script has been tested on Windows.  We are currently running it as a 
# windows service.  The script is started using PHP from the command-line
#
#    php -f mantis_perforce.php
#
# For information on running this as a service, google "srvany install perl".

include_once "mantis_perforce.inc.php";

$mantis_location = mantis_location();

require_once( $mantis_location.DIRECTORY_SEPARATOR.core.".php" );

# uncomment for debugging
$g_show_detailed_errors = ON;
$g_show_notices     = ON;
$g_show_warnings    = ON;
$g_stop_on_errors   = ON;

$p4 = "$p4 -H $p4_host -p $p4_port ";

msg("starting.\n");


while (1)
{
	do_review();
	echo "sleeping $interval seconds....\n";
	sleep($interval);
}

function do_review()
{
  global $p4;
  global $p4_counter;

  $topchange = 0;

  $cmd = "$p4 review -t $p4_counter";
  $pipe = popen($cmd, "r"); 

  if (!$pipe) 
  { 
    msg("couldn't open pipe for cmd: $cmd\n");
    return; 
  }

  db_connect( false, $g_hostname, $g_db_username, $g_db_password );
#  db_select_db( $g_database_name );

  if (db_is_connected())
  {
    while($s = fgets($pipe, 1024))
    {
      # Format: "Change x user <email> (Full Name)"
      if (preg_match("/^Change (\d*) (\S*) <(\S*)> (\(.*\))/",$s,$matches))
      {
        $change = $matches[1];    
        $user = $matches[2];    
  
        process_change($change, $user);
        $topchange = $change;
    }
    }
    pclose($pipe);

    if ($topchange) 
    { 
      run_cmd("$p4 counter $p4_counter $topchange");
    }
  db_close();
  }
}

function process_change($change, $user)
{
  global $p4;

  msg("processing change: $change for user $user\n");

  $cmd = "$p4 describe -s $change";
  $pipe = popen($cmd, "r"); 

  if (!$pipe) 
  {
    msg("error opening pipe for cmd: $cmd\n");
    return;
  }

  $bug = "";
  $desc = "";
  while($s = fgets($pipe, 1024))
  {
    if (preg_match("/$bug_flag (\d+)/i",$s,$matches))
    { 
      $bug = $matches[1]; 
    }
    $desc .= $s;
  }
  pclose($pipe);

  if (strlen($bug))
  {
    update_mantis($bug, $change, $desc, $user);
  }
}

function update_mantis($bug, $change, $desc, $user) 
{
  msg("updating mantis bug $bug\n");

  if (bug_exists( $bug ))
  {
    if (!get_user_id($user))
    {
      msg("aborting update b/c invalid user");
      return;
    }

    bugnote_add ( $bug, $desc, false);
  }
  else
  {
    msg("invalid bug id ($bug) specified in changelist ($change)\n");
  }
}

function get_user_id($user)
{
  global $g_cache_current_user_id;

  $g_cache_current_user_id = null;

  $user_id = user_get_id_by_name($user);

  if ( ! $user_id ) 
  {
    msg("could not locate user: $user trying to find user 'perforce'\n");

    $user_id = user_get_id_by_name('perforce');
  }

  if ( ! $user_id ) 
  {
    msg("could not locate user: $user or user 'perforce'.  Add perforce user to mantis.\n");
    return 0;
  }

  $g_cache_current_user_id = (int)$user_id;

  return $g_cache_current_user_id;
}

function run_cmd($cmd)
{
  msg("running: $cmd\n");

  $pipe = popen("$cmd", "r"); 

  if (!$pipe) 
  {
    msg("cmd failed: $cmd\n");
    return;
  }
  $output = "";
  while($s = fgets($pipe, 1024))
  {
    $output .= $s;
  }
  pclose($pipe);

  return ($output);
}


function msg($msg)
{
  global $log;

  print($msg);

  if (! $log) { return; }

  error_log($msg, 3, $log);
}

?>
