$value) { if (isset($data[$i])) { $return_vars[$name] = $data[$i]; $i++; } else { $return_vars[$name] = $value; } } return $return_vars; } /* Pathinfo retrieval minus starting slash */ function mtrack_get_pathinfo($no_strip = false) { $pi = isset($_SERVER['PATH_INFO']) ? $_SERVER['PATH_INFO'] : NULL; if ($pi !== NULL && strlen($pi) && $no_strip == false) { $pi = substr($pi, 1); } return $pi; } function mtrack_calc_root() { /* ABSWEB: the absolute URL to the base of the web app */ global $ABSWEB; /* if they have one, use the weburl config value for this */ $ABSWEB = MTrackConfig::get('core', 'weburl'); if (strlen($ABSWEB)) { return; } /* otherwise, determine the root of the app. * This is complicated because the DOCUMENT_ROOT may refer to an area that * is completely unrelated to the actual root of the web application, for * instance, in the case that the user has a public_html dir where they * are running mtrack */ /* determine the root of the app */ $sdir = dirname($_SERVER['SCRIPT_FILENAME']); $idir = dirname(dirname(__FILE__)) . '/web'; $diff = substr($sdir, strlen($idir)+1); $rel = preg_replace('@[^/]+@', '..', $diff); if (strlen($rel)) { $rel .= '/'; } /* $rel is now the relative path to the root of the web app, from the current * page */ if (isset($_SERVER['HTTP_HOST'])) { $ABSWEB = ((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') ? 'https' : 'http') . '://' . $_SERVER['HTTP_HOST']; } else { $ABSWEB = 'http://localhost'; } $bits = explode('/', $rel); $base = $_SERVER['SCRIPT_NAME']; foreach ($bits as $b) { $base = dirname($base); } if ($base == '/') { $ABSWEB .= '/'; } else { $ABSWEB .= $base . '/'; } } mtrack_calc_root(); function mtrack_head($title, $navbar = true) { global $ABSWEB; static $mtrack_did_head; $whoami = mtrack_username(MTrackAuth::whoami(), array( 'no_image' => true ) ); if ($mtrack_did_head) { return; } $mtrack_did_head = true; $projectname = htmlentities(MTrackConfig::get('core', 'projectname'), ENT_QUOTES, 'utf-8'); $logo = MTrackConfig::get('core', 'projectlogo'); if (strlen($logo)) { $projectname = "$projectname"; } $fav = MTrackConfig::get('core', 'favicon'); if (strlen($fav)) { $fav = << HTML; } else { $fav = ''; } $title = htmlentities($title, ENT_QUOTES, 'utf-8'); $userinfo = "Logged in as $whoami"; MTrackNavigation::augmentUserInfo($userinfo); echo " $title $fav "; /* For licensing and copyright terms, see the file named LICENSE */ $scripts = array( 'css/smoothness/jquery-ui-1.7.2.custom.css', 'mtrack.css', 'css/ticket.css', 'css/markitup/markitup-simple.css', 'css/markitup/wiki.css', 'css/hyperlight/plain.css', 'css/hyperlight/vibrant-ink.css', 'css/hyperlight/zenburn.css', 'css/hyperlight/wezterm.css', ); foreach ($scripts as $name) { echo ""; } $scripts = array( 'excanvas.pack.js', 'jquery-1.4.2.min.js', 'jquery-ui-1.8.2.custom.min.js', 'jquery.asmselect.js', 'jquery.flot.pack.js', 'jquery.MultiFile.pack.js', 'jquery.cookie.js', 'jquery.treeview.js', 'jquery.tablesorter.js', 'jquery.metadata.js', 'jquery.markitup.js', 'jquery.timeago.js', 'json2.js', 'mtrack.js', 'mtrack.ticket.js', 'mtrack.watch.js', ); echo ' '; foreach ($scripts as $name) { echo "\n"; } $PRI_SWITCH = ''; foreach (MTrackDB::q('select priorityname, value from priorities') ->fetchAll() as $row) { $PRI_SWITCH .= "case '$row[0]': return $row[1];\n"; } $SEV_SWITCH = ''; foreach (MTrackDB::q('select sevname, ordinal from severities') ->fetchAll() as $row) { $SEV_SWITCH .= "case '$row[0]': return $row[1];\n"; } echo << $(document).ready(function() { $.tablesorter.addParser({ id: 'priority', is: function(s) { // don't auto-detect return false; }, format: function(s) { switch (s) { $PRI_SWITCH } return s; }, type: 'numeric' }); $.tablesorter.addParser({ id: 'severity', is: function(s) { // don't auto-detect return false; }, format: function(s) { switch (s) { $SEV_SWITCH } return s; }, type: 'numeric' }); JAVASCRIPT; echo << HTML; if ($navbar) { echo <<
$userinfo
HTML; echo << HTML; $nav = array(); if (MTrackAuth::whoami() !== 'anonymous') { // $nav['/'] = 'Today'; } $navcandidates = array( "/Browse.php" => array("Browse", 'read', 'Browser'), // "/wiki.php" => array("Wiki", 'read', 'Wiki'), "/timeline.php" => array("Timeline", 'read', 'Timeline'), // "/roadmap.php" => array("Roadmap", 'read', 'Roadmap'), "/report.php/1" => array("Active Tickets", 'read', 'Reports'), "/report.php/3" => array("Pending Review", 'read', 'Reports'), "/Ticket.php/new" => array("New Ticket", 'create', 'Tickets'), // "/snippet.php" => array("Snippets", 'read', 'Snippets'), "/admin/" => array("Administration", 'modify', 'Enumerations', 'Components', 'Projects', 'Browser'), ); foreach ($navcandidates as $url => $data) { $label = array_shift($data); $right = array_shift($data); $ok = false; foreach ($data as $object) { if (MTrackACL::hasAllRights($object, $right)) { $ok = true; break; } } if ($ok) { $nav[$url] = $label; } } echo mtrack_nav('mainnav', $nav); echo << HTML; } if (MTrackConfig::get('core', 'admin_party') == 1 && MTrackAuth::whoami() == 'adminparty' && ($_SERVER['REMOTE_ADDR'] == '127.0.0.1' || $_SERVER['REMOTE_ADDR'] == '::1')) { echo << Welcome to the admin party! Authentication is not yet configured; while it is in this state, any user connecting from the localhost address is treated as having admin rights (that includes you, and this is why you are seeing this message). All other users are treated as anonymous users.
Click here to Configure Authentication HTML; } elseif (!MTrackAuth::isAuthConfigured() && MTrackConfig::get('core', 'admin_party') == 1) { $localaddr = preg_replace('@^(https?://)([^/]+)/(.*)$@', "\\1localhost/\\3", $ABSWEB); echo << Authentication is not yet configured. If you are the admin, you should use the localhost address to reach the system and configure it. HTML; } elseif (!MTrackAuth::isAuthConfigured()) { echo << Authentication is not yet configured. If you are the admin, you will need to edit the config.ini file to configure authentication. HTML; } if (ini_get('magic_quotes_gpc') === true || !strcasecmp(ini_get('magic_quotes_gpc'), 'on')) { echo << magic_quotes_gpc is enabled. This causes mtrack not to work. Please disable this setting in your server configuration. HTML; } echo <<
HTML; } function mtrack_foot($visible_markup = true) { echo << HTML; if ($visible_markup) { echo <<
HTML; if (MTrackConfig::get('core', 'debug.footer')) { global $FORKS; echo ""; } } } interface IMTrackExtensionPage { /** called to dispatch a page render */ function dispatchRequest(); } class MTrackExtensionPage { static $locations = array(); static function registerLocation($location, IMTrackExtensionPage $page) { self::$locations[$location] = $page; } static function locationToURL($location) { global $ABSWEB; return $ABSWEB . 'ext.php/' . $location; } static function bindToPage($location) { while (strlen($location)) { if (isset(self::$locations[$location])) { return self::$locations[$location]; } if (strpos($location, '/') === false) { return null; } $location = dirname($location); } } } function mtrack_date($tstring, $show_full = false) { /* database time is always relative to UTC */ $d = date_create($tstring, new DateTimeZone('UTC')); if (!is_object($d)) { throw new Exception("could not represent $tstring as a datetime object"); } $iso8601 = $d->format(DateTime::W3C); /* but we want to render relative to user prefs */ date_timezone_set($d, new DateTimeZone(date_default_timezone_get())); $full = $d->format('D, M d Y H:i'); if (!$show_full) { return "$full"; } return "$full $full"; } function mtrack_rmdir($dir) { foreach (scandir($dir) as $ent) { if ($ent == '.' || $ent == '..') { continue; } $full = $dir . DIRECTORY_SEPARATOR . $ent; if (is_dir($full)) { mtrack_rmdir($full); } else { unlink($full); } } rmdir($dir); } function mtrack_make_temp_dir($do_make = true) { $tempdir = sys_get_temp_dir(); $base = $tempdir . DIRECTORY_SEPARATOR . "mtrack." . uniqid(); for ($i = 0; $i < 1024; $i++) { $candidate = $base . sprintf("%04x", $i); if ($do_make) { if (mkdir($candidate)) { return $candidate; } } else { /* racy */ if (!file_exists($candidate) && !is_dir($candidate)) { return $candidate; } } } throw new Exception("unable to make temp dir based on path $candidate"); } /// moved to mtrack_dataobjects_event (currently) //function mtrack_diff_strings($before, $now) function mtrack_last_chance_saloon($e) { // adding headers on exceptions here causes nightmares for dynamic content.. if ($e instanceof MTrackAuthorizationException) { if (MTrackAuth::whoami() == 'anonymous') { MTrackAuth::forceAuthenticate(); } // mtrack_head('Insufficient Privilege'); echo '

Insufficient Privilege

'; $rights = is_array($e->rights) ? join(', ', $e->rights) : $e->rights; echo "You do not have the required set of rights ($rights) to access this page
"; //mtrack_foot(); exit; } $msg = $e->getMessage(); try { // mtrack_head('Whoops: ' . $msg); } catch (Exception $doublefault) { } echo "

An error occurred!

"; echo htmlentities($msg, ENT_QUOTES, 'utf-8'); echo "
"; echo nl2br(htmlentities($e->getTraceAsString(), ENT_QUOTES, 'utf-8')); try { // mtrack_foot(); } catch (Exception $doublefault) { } } function mtrack_gravatar($email, $size = 24) { // d=identicon // d=monsterid // d=wavatar return ""; } // mtrack_defrepo ==> MTrack_Repo::defaultRepo($cfg); // mtrack_changeset_url ==> MTrack_Repo::loadByChangeSet = see linkhandler::changeset function mtrack_tag($tag, $repo = null) { return "$tag"; } function mtrack_keyword($keyword) { global $ABSWEB; $kw = urlencode($keyword); return "$keyword"; } function mtrack_multi_select_box($name, $title, $items, $values = null) { $title = htmlentities($title, ENT_QUOTES, 'utf-8'); $html = ""; } function mtrack_select_box($name, $items, $value = null, $keyed = true) { $html = ""; } function mtrack_radio($name, $value, $curval) { $checked = $curval == $value ? " checked='checked'": ''; return ""; } function mtrack_diff($diffstr) { $nlines = 0; if (is_resource($diffstr)) { $lines = array(); while (($line = fgets($diffstr)) !== false) { $lines[] = rtrim($line, "\r\n"); } $diffstr = $lines; } if (is_string($diffstr)) { $abase = md5($diffstr); $diffstr = preg_split("/\r?\n/", $diffstr); } else { $abase = md5(join("\n", $diffstr)); } /* we could use toggle() below, but it is much faster to determine * if we are hiding or showing based on a single variable than evaluating * that for each possible cell */ $html = <<Toggle Diff Line Numbers HTML; $html .= ""; //$html = "
";

  while (true) {
    if (!count($diffstr)) {
      break;
    }
    $line = array_shift($diffstr);
    $nlines++;
    if (!strncmp($line, '@@ ', 3)) {
      /* done with preamble */
      break;
    }
    $line = htmlspecialchars($line, ENT_QUOTES, 'utf-8');
    $line = "
"; $html .= $line . "\n"; } $lines = array(0, 0); $first = false; while (true) { $class = 'unmod'; if (preg_match("/^@@\s+-(\pN+)(?:,\pN+)?\s+\+(\pN+)(?:,\pN+)?\s*@@/", $line, $M)) { $lines[0] = (int)$M[1] - 1; $lines[1] = (int)$M[2] - 1; $class = 'meta'; $first = true; } elseif (strlen($line)) { if ($line[0] == '-') { $lines[0]++; $class = 'removed'; } elseif ($line[0] == '+') { $lines[1]++; $class = 'added'; } else { $lines[0]++; $lines[1]++; } } else { $lines[0]++; $lines[1]++; } $row = ""; break; case 'removed': $row .= ""; break; default: $row .= ""; } $anchor = $abase . '.' . $nlines; $row .= ""; $line = htmlspecialchars($line, ENT_QUOTES, 'utf-8'); $row .= "\n"; $html .= $row; if (!count($diffstr)) { break; } $line = array_shift($diffstr); $nlines++; } if ($nlines == 0) { return null; } $html .= "
$line
" . $lines[0] . "" . $lines[0] . "" . $lines[1] . "$line
"; return $html; } function mtrack_mime_detect($filename, $namehint = null) { /* does config tell us how to decide mimetype */ $detector = MTrackConfig::get('core', 'mimetype_detect'); /* if detector is blank, we'll try to figure out which one to use */ if (empty($detector)) { if (function_exists('finfo_open')) { $detector = 'fileinfo'; } elseif (function_exists('mime_content_type')) { $detector = 'mime_magic'; } else { $detector = 'file'; } } /* use detector or all mimetypes will be blank */ if ($detector === 'fileinfo') { if (defined('FILEINFO_MIME_TYPE')) { $fileinfo = finfo_open(FILEINFO_MIME_TYPE); } else { $magic = MTrackConfig::get('core', 'mime.magic'); if (strlen($magic)) { $fileinfo = finfo_open(FILEINFO_MIME, $magic); } else { $fileinfo = finfo_open(FILEINFO_MIME); } } $mimetype = finfo_file($fileinfo, $filename); finfo_close($fileinfo); } elseif ($detector === 'mime_magic') { $mimetype = mime_content_type($filename); } elseif (PHP_OS != 'SunOS') { $mimetype = shell_exec("file -b --mime " . escapeshellarg($filename)); } else { $mimetype = 'application/octet-stream'; } $mimetype = trim(preg_replace("/\s*;.*$/", '', $mimetype)); if (empty($mimetype)) { $mimetype = 'application/octet-stream'; } if ($mimetype == 'application/octet-stream') { if ($namehint === null) { $namehint = $filename; } $pi = pathinfo($namehint); switch (strtolower($pi['extension'])) { case 'bin': return 'application/octet-stream'; case 'exe': return 'application/octet-stream'; case 'dll': return 'application/octet-stream'; case 'iso': return 'application/octet-stream'; case 'so': return 'application/octet-stream'; case 'a': return 'application/octet-stream'; case 'lib': return 'application/octet-stream'; case 'pdf': return 'application/pdf'; case 'ps': return 'application/postscript'; case 'ai': return 'application/postscript'; case 'eps': return 'application/postscript'; case 'ppt': return 'application/vnd.ms-powerpoint'; case 'xls': return 'application/vnd.ms-excel'; case 'tiff': return 'image/tiff'; case 'tif': return 'image/tiff'; case 'wbmp': return 'image/vnd.wap.wbmp'; case 'png': return 'image/png'; case 'gif': return 'image/gif'; case 'jpg': return 'image/jpeg'; case 'jpeg': return 'image/jpeg'; case 'ico': return 'image/x-icon'; case 'bmp': return 'image/bmp'; case 'css': return 'text/css'; case 'htm': return 'text/html'; case 'html': return 'text/html'; case 'txt': return 'text/plain'; case 'xml': return 'text/xml'; case 'eml': return 'message/rfc822'; case 'asc': return 'text/plain'; case 'rtf': return 'application/rtf'; case 'wml': return 'text/vnd.wap.wml'; case 'wmls': return 'text/vnd.wap.wmlscript'; case 'gtar': return 'application/x-gtar'; case 'gz': return 'application/x-gzip'; case 'tgz': return 'application/x-gzip'; case 'tar': return 'application/x-tar'; case 'zip': return 'application/zip'; case 'sql': return 'text/plain'; } // if the file is ascii, then treat it as text/plain $fp = fopen($filename, 'rb'); $mimetype = 'text/plain'; do { $x = fread($fp, 8192); if (!strlen($x)) break; if (preg_match('/([\x80-\xff])/', $x, $M)) { $mimetype = 'application/octet-stream'; break; } } while (true); $fp = null; } return $mimetype; } if (php_sapi_name() != 'cli') { set_exception_handler('mtrack_last_chance_saloon'); error_reporting(E_NOTICE|E_ERROR|E_WARNING); // ini_set('display_errors', false); set_time_limit(300); }