var $up = '';
var $jump = '';
+ var $pi;
+ var $basename;
+ var $crumbs;
+ var $dirname;
+ var $repos;
function getAuth()
{
}
- function get($pi)
+ function get($pi='', $args = array())
{
- $this->pi = $pi . (strlen($pi) ? $this->bootLoader->ext : '');
+ $this->pi = $pi . (strlen($pi) ? $this->bootLoader->ext : '');
if (!isset($_REQUEST['ajax_body'])) {
- $this->title = $this->pi;
+ $this->title = "Browse: " . $this->pi;
return;
}
$this->masterTemplate = 'tree.html';
if (!$this->repo->id) {
$this->repo = false;
}
+ // if we have an active project.. enforce it..
+ if ($this->currentProject() && $this->repo && $this->repo->project_id != $this->currentProject()) {
+ $this->repo = false; // no repo..
+ }
+
$this->object = null;
$this->ident = null;
$this->basename = basename($file);
$location = '';
- $crumbs = explode('/', dirname($file));
- if (strlen($file)) {
- array_unshift($crumbs, ''); // add empty at front..
- }
+ $crumbs = !strlen($file) || dirname($file) == '.' || !strlen(dirname($file)) ? array() :
+ explode('/', dirname($file));
+
$this->crumbs = array();
{
$c = new StdClass;
- $c->name = strlen($path) ? $path : '[root]';
+ $c->name = $path ;
$location .= strlen($location) ? '/' : '';
$location .= strlen($path) ? urlencode($path) : '';
$c->location = $location;
} else {
$do->orderBy("shortname ASC");
}
+
+ if ($this->currentProject()) {
+ $do->project_id = $this->currentProject();
+ }
// FIXME -> permissions on repositories goes here..
//$do->ensurePerm($this->authUser);
//$do->fetchAll();
// static..?
- function getBrowseData($repo, $pi, $object, $ident)
+ function getBrowseData($repo, $pi, $object, $ident, $hashes = false)
{
$data = new StdClass;
$data->dirs = array();
}
$files = array();
$dirs = array();
-
+
+ $needLog = array();
if ($repo) {
//try {
- $ents = $repo->readdir($pi, $object, $ident);
- //} catch (Exception $e) {
- // Typically a freshly created repo
- // $ents = array();
- // $data->err = $e->getMessage();
- //}
- // echo '<PRE>' ; var_dump($ents); echo '</PRE>' ;
+ $ents = $repo->readdir($pi, $object, $ident);
+ if ($hashes === false) {
+ $ents = $this->cachedChangeEvent($ents);
+ } else {
+ // we are filling the cache..
+ return $this->cachedChangeEventFill($ents, $hashes);
+
+ }
+
foreach ($ents as $file) {
+ if (isset($file->hash)) {
+ $needLog[] = $file->hash;
+ }
+
$basename = basename($file->name);
if ($file->is_dir) {
$dirs[$basename] = $file;
uksort($files, 'strnatcmp');
uksort($dirs, 'strnatcmp');
- $data->files = array();
- $data->dirs = array();
-
- //$urlbase = $this->baseURL . '/browse.php';
- //$pathbase = '/' . $repo->getBrowseRootName();
+
+ $data->dirs = array_values($dirs);
+ $data->files = array_values($files);
- foreach ($dirs as $basename => $file) {
-
- $ent = $file->getChangeEvent(); //MTrackSCMEvent
- // let's copy extra stuff into the event..
- //$ent->url = $urlbase . $pathbase . '/' . $file->name;
- $ent->basename = $basename;
- $ent->changelogOne = $ent->changelogOneToHtml();
+ $this->repopath = $this->repo->displayName();
+ $this->needLog = $needLog;
+ // gather list
+
+ return $data;
+ }
+ /**
+ * New version of Directory listing
+ * Basically fetching the last change is very slow...
+ * - 1st run through -> fetch all the change events that we have
+ * for ones we do not have, fetch them later..
+ *
+ */
+ function cachedChangeEvent($ar)
+ {
+ // fetch a list of hashes...
+ // build a map...
+ $map = array();
+ foreach($ar as $e) {
+ $e->basename = basename($e->name);
+ // remove e->rev as it's not valid..
+ $e->rev = false;
+ $map[$e->hash] = $e;
- $data->dirs[] = $ent;
}
- foreach ($files as $basename => $file) {
- $ent = $file->getChangeEvent();
- if (!$ent) { // skips broken files..
+ $q = DB_DataObject::factory('mtrack_clcache');
+ $q->whereAddIn('rev', array_keys($map), 'string');
+ $q->repo_id = $this->repo->id;
+ $revs = $q->fetchAll('rev', 'sobject');
+ $impl = $this->repo->impl();
+
+ foreach($revs as $hash => $sobject) {
+ $event = $impl->commitLogToEvent($sobject);
+ // add something???
+ if (!$event) {
continue;
}
- // needed?
- $ent->basename = $basename;
+ $event->is_dir = $map[$hash]->is_dir;
+ $event->name = $map[$hash]->name;
+ $event->basename = $map[$hash]->basename;
+
+ $map[$hash] = $event; // this was previous only done for directories??? why???
+ }
+ return array_values($map);
+ }
+
+ function cachedChangeEventFill($ar,$hashes)
+ {
+ $map = array();
+ $impl = $this->repo->impl();
+
+ foreach($ar as $e) {
+ if (!in_array($e->hash,$hashes)) {
+ continue;
+ }
+
+ // there is a small chance that concurrent users are looking for the same info..
+ $q = DB_DataObject::factory('mtrack_clcache');
+ $q->rev = $e->hash;
+ $q->repo_id = $this->repo->id;
+
+ if ($q->find(true)) {
+ $event = $impl->commitLogToEvent($q->sobject);
+ } else {
+ $ent = $this->repo->history($e->name, 1, 'rev', $e->rev);
+
+
+ if (!$ent) {
+ continue;
+ }
+ $event = $ent[0];
+ // cache it..
+ $q = DB_DataObject::factory('mtrack_clcache');
+ $q->rev = $e->hash;
+ $q->repo_id = $this->repo->id;
+ $q->sobject = $event->commit;
+ $q->insert();
+ }
+
+ // only copy a few essentials from ent, as we will send it back via json.
+ // these all need escaoing..
+ $add = new stdClass;
+ $add->changelog = $event->changelogOneToHtml($this->link);
+ $add->age = $event->ctimeToHtml($this->link);
+ $add->basename = basename($e->name);
+ $add->changeby = htmlspecialchars($event->changeby);
+ $add->rev = '<a class="changesetlink browse-link" href="'.
+ htmlspecialchars($this->baseURL) .
+ '/Changeset/' .
+ htmlspecialchars($this->repo->displayName()).
+ '/'.
+ htmlspecialchars($event->rev) .
+ '">'.
+ htmlspecialchars($event->rev) .
+ '</a>';
+
+ $map[$e->hash] = $add;
+
- $data->files[] = $ent;
}
-
- return $data;
+ return $map;
+
+
+
+ }
+ function post($pi)
+ {
+ $this->pi = $pi . (strlen($pi) ? $this->bootLoader->ext : '');
+
+
+
+ $this->repo = DB_DataObject::factory('mtrack_repos');
+ $file = $this->repo->loadFromPath($this->pi);
+ if (!$this->repo->id) {
+ $this->jerr("INVALID URL");
+ }
+
+ $this->object = null;
+ $this->ident = null;
+
+ if (isset($_GET['jump']) && strlen($_GET['jump'])) {
+ list($this->object, $this->ident) = explode(':', $_GET['jump'], 2);
+ }
+
+ if (!$this->repo) {
+ $this->jerr("INVALID URL");
+ }
+ if (!$this->projectPerm($this->repo->project_id, 'MTrack.Repos', 'S')) {
+ $this->jerr("INVALID URL");
+ }
+ if (empty($_POST['hashes'])) {
+ $this->jerr("INVALID URL");
+ }
+
+ $ar = $this->getBrowseData($this->repo, $file, $this->object, $this->ident, explode(',', $_POST['hashes']));
+ $this->jdata($ar);
+ exit;
+
+
}
-
}