pi = $pi . (strlen($pi) ? $this->bootLoader->ext : ''); if (!isset($_REQUEST['ajax_body'])) { $this->title = "Changeset: " . $this->pi; return; } $this->masterTemplate = 'changeset.html'; $this->repo = DB_DataObject::factory('mtrack_repos'); $this->cs = $this->repo->loadFromPath($this->pi); if (!$this->repo->id) { return HTML_FlexyFramework::run('Browse'); }; if (!$this->projectPerm($this->repo->project_id, 'MTrack.Repos', 'S')) { return HTML_FlexyFramework::run('Noperm'); // noperm = loggedin -> need more perms / not.. try loggin in.. } //$data = mtrack_cache('get_change_data', array($path), 864000); $this->data = $this->get_change_data($this->cs); if (!empty($_REQUEST['part'])) { foreach($this->data->ent->files as $f) { if ($f->name != $_REQUEST['part']) { continue; } echo $this->diff($this->repo->diff($f, $this->data->ent->rev)); exit; } die("can not find part?"); } $this->ent = $this->data->ent; if ($this->ent === null) { throw new Exception("invalid parameters"); } //$rdata = mtrack_cache('get_change_data_relatives', array($path, $ent->rev)); $rdata = $this->get_change_data_relatives($this->cs, $this->ent->rev); // print_R($rdata);exit; if (isset($_GET['fmt']) && $_GET['fmt'] == 'diff') { $this->downloadDiff(); } $this->title = "Changeset " . $this->ent->rev; } function downloadDiff() { $filename = "$this->repo->shortname.$this->ent->rev.diff"; header("Content-Type: text/plain; name=\"$filename\""); header("Content-Disposition: attachment; filename=\"$filename\""); echo "Changeset: $repo->shortname $ent->rev\n"; echo "By: $ent->changeby\n"; echo "When: $ent->ctime\n"; echo "\n"; echo $data->changelog . "\n\n"; if (is_array($ent->files) && count($ent->files)) { foreach ($ent->files as $id => $file) { echo "$file->status $file->name\n"; } echo "\n"; foreach ($ent->files as $id => $file) { $fpath = $file->name; if ($fpath[0] != '/') $fpath = '/' . $fpath; $diff = $repo->diff($file, $ent->rev); if (is_resource($diff)) { echo stream_get_contents($diff); } elseif (is_array($diff)) { echo join("\n", $diff); } else { echo $diff; } } } exit; } function get_change_data($pi) { $ents = $this->repo->history(null, 1, 'rev', $pi); $data = new stdclass; if (!count($ents)) { $data->ent = null; } else { $ent = $ents[0]; $data->ent = $ent; // Determine project from the file list $changelog = $ent->changelog; /*$the_proj = $this->repo->projectFromPath($ent->files); if ($the_proj > 1) { $proj = MTrackProject::loadById($the_proj); $changelog = $proj->adjust_links($ent->changelog, true); } */ $data->changelog = $changelog; $ent->files = is_array($ent->files) ? array_values($ent->files) : array(); // we should not do this here.. // it's to slow on huge commits.. //foreach ($ent->files as $file) { // $file->diff = $this->diff($this->repo->diff($file, $ent->rev)); //} } return $data; } function get_change_data_relatives($pi, $rev) { $data = new stdclass; list($data->parents, $data->kids) = $this->repo->getRelatedChanges($rev); return $data; } function diff($diffstr) // fixme... code should be in template.. { $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)); } // diffstr should now contain a string... /* 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 = " "; //$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; } }