1 <?php # vim:ts=2:sw=2:et:
2 /* For licensing and copyright terms, see the file named LICENSE */
5 * Think about how to handle the nav stuff...
6 * -> all urls need to respond to direct requests.
7 * -> the direct request is always an ajax
13 // Browse.php - only for rendering the body..
14 // Tree.php - the actually tree..
16 require_once 'MTrackWeb.php';
18 class MTrackWeb_Browse extends MTrackWeb
29 var $elements = array();
31 var $showCreate = false; // show create repo.
32 var $canEditRepo = false;
35 var $canDeleteFork = false;
54 $this->pi = $pi . (strlen($pi) ? $this->bootLoader->ext : '');
56 if (!isset($_REQUEST['ajax_body'])) {
57 $this->title = $this->pi;
60 $this->masterTemplate = 'tree.html';
61 //DB_DataObject::debugLevel(1);
66 $this->repo = DB_DataObject::factory('mtrack_repos');
67 $file = $this->repo->loadFromPath($this->pi);
68 if (!$this->repo->id) {
75 if (isset($_GET['jump']) && strlen($_GET['jump'])) {
76 list($this->object, $this->ident) = explode(':', $_GET['jump'], 2);
80 if (!$this->projectPerm($this->repo->project_id, 'MTrack.Repos', 'S')) {
81 return HTML_FlexyFramework::run('Noperm'); // noperm = loggedin -> need more perms / not.. try loggin in..
84 $this->bdata = $this->getBrowseData($this->repo, $file, $this->object, $this->ident);
85 if (isset($this->bdata->err) ) {
86 throw new Exception($this->bdata->err);
88 require_once 'MTrack/Wiki/Item.php';
89 //make sure we can render..
90 MTrack_Wiki_Item::$repo = $this->repo->impl();
92 //$this->repo = (count($crumbs) > 2) ? MTrackSCM::factory($this->pi) : null ;
99 //$this->bdata = mtrack_cache(
100 // array($this,'getBrowseData'),
101 // array($this->repo, $this->pi, $this->object, $this->ident)
104 $this->basename = basename($file);
106 $crumbs = explode('/', dirname($file));
108 array_unshift($crumbs, ''); // add empty at front..
111 $this->crumbs = array();
117 foreach($crumbs as $path)
121 $c->name = strlen($path) ? $path : '[root]';
122 $location .= strlen($location) ? '/' : '';
123 $location .= strlen($path) ? urlencode($path) : '';
124 $c->location = $location;
125 $this->crumbs[] = $c;
127 // echo '<PRE>';print_R($this->crumbs);
129 if ($this->bdata && count($this->bdata->jumps)) {
130 require_once 'HTML/Template/Flexy/Element.php';
131 $this->elements['jump'] = new HTML_Template_Flexy_Element('select');
132 // print_r($bdata->jumps);
133 $this->elements['jump']->setOptions($this->bdata->jumps);
140 if (MTrackACL::hasAllRights('Browser', 'create')) {
141 some users may have rights to create repos that belong to projects.
142 * Determine that list of projects here, because we need it for both
143 * the fork and new repo cases */
145 $owners = array("user:{$this->authUser->userid}" => $this->authUser->userid);
146 $q = MTrackDB::q( 'select projid, shortname, name from projects order by ordinal') ;
147 foreach ($q->fetchAll(PDO::FETCH_ASSOC) as $row) {
148 if (MTrackACL::hasAllRights("project:". $row['projid'], 'modify')) {
149 $owners["project:". $row['shortname']] = $row['shortname'];
152 $this->showCreate = count($owners) > 1 ? true : false;
153 require_once 'HTML/Template/Flexy/Element.php';
154 $this->elements['repo:parent'] = new HTML_Template_Flexy_Element('select');
155 $this->elements['repo:parent']->setOptions($owners);
160 MTrackACL::requireAllRights("repo:{$this->repo->id}", 'read');
162 // this looks buggy..
164 if ( $this->repo->canFork() &&
165 MTrackACL::hasAllRights('Browser', 'fork') &&
166 MTrackConfig::get('repos', 'allow_user_repo_creation')
169 $this->canFork = true;
170 $this->forkname = $this->repo->shortname;
172 if ("{$this->authUser->userid}/{$this->repo->shortname}" == $this->repo->getBrowseRootName()) {
173 // if this is mine already, make a "more unique" name for my new fork
174 $this->forkname = $this->repo->shortname . '2';
178 if ( $this->repo->parent &&
179 MTrackACL::hasAllRights("repo:{$this->repo->id}", "delete")
182 $this->canDeleteFork = true;
185 if (MTrackACL::hasAllRights("repo:{$this->repo->id}", "modify")) {
186 $this->canEditRepo = true;
188 // watch UI is different in this version..
189 // MTrackWatch::renderWatchUI('repo', $repo->id);
193 /// non repo options..
197 $this->dirname = $this->repo ? $this->repo->displayName() : '';
200 $this->dirname .= '/'. $file;
202 $this->up = strlen($file) ? dirname($this->dirname) : '';
203 $this->jump = isset($_GET['jump']) ? $_GET['jump'] : '';
206 return $this->noRepo(explode('/', $pi));
209 //print_r($this); exit;
214 function noRepo($crumbs)
217 /*if ( MTrackACL::hasAllRights('Browser', 'fork')
218 && MTrackConfig::get('repos', 'allow_user_repo_creation')
221 $repotypes = array();
223 foreach (MTrack_Repo::getAvailableSCMs() as $t => $r) {
224 $d = $r->getSCMMetaData();
225 $repotypes[$t] = $d['name'];
227 require_once 'HTML/Template/Flexy/Element.php';
228 $this->elements['repo:type'] = new HTML_Template_Flexy_Element('select');
229 $this->elements['repo:type']->setOptions($repotypes);
232 // DB_DataObject::debugLevel(1);
233 $mine = $this->authUser ? "user:{$this->authUser->id}" : '';
235 $do = DB_DataObject::factory('mtrack_repos');
238 $crumbs[0] = empty($crumbs[0]) ? 'default' : $crumbs[0] ;
240 if (count($crumbs) == 1 && $crumbs[0] != 'default') {
242 $do->whereAdd("parent like('%:". $do->escape($crumbs[0]). "')"); // subset
244 } else if (count($crumbs) == 1 && $crumbs[0] == 'default') {
246 $do->whereAdd(" parent = ''"); // top level..
248 /* looking for top level items */
251 /* have my own repos bubble up */
252 if ($this->authUser) {
253 $do->orderBy("CASE WHEN parent = '" . $do->escape('user:' . $this->authUser->id) . "' THEN 0 ELSE 1 END, shortname ASC");
255 $do->orderBy("shortname ASC");
257 // FIXME -> permissions on repositories goes here..
258 //$do->ensurePerm($this->authUser);
261 $this->repos= array();
262 while ($do->fetch()) {
264 if (!$this->projectPerm($do->project_id, 'MTrack.Repos', 'S')) {
268 $this->repos[]= clone($do);
280 function getBrowseData($repo, $pi, $object, $ident)
282 $data = new StdClass;
283 $data->dirs = array();
284 $data->files = array();
285 $data->jumps = array();
290 $branches = $repo->getBranches();
291 $tags = $repo->getTags();
292 if (count($branches) + count($tags)) {
293 $jumps = array("" => "- Select Branch / Tag - ");
294 if (is_array($branches)) {
295 foreach ($branches as $name => $notcare) {
296 $jumps["branch:$name"] = "Branch: $name";
299 if (is_array($tags)) {
300 foreach ($tags as $name => $notcare) {
301 $jumps["tag:$name"] = "Tag: $name";
304 $data->jumps = $jumps;
311 $ents = $repo->readdir($pi, $object, $ident);
312 //} catch (Exception $e) {
313 // Typically a freshly created repo
315 // $data->err = $e->getMessage();
317 // echo '<PRE>' ; var_dump($ents); echo '</PRE>' ;
318 foreach ($ents as $file) {
319 $basename = basename($file->name);
321 $dirs[$basename] = $file;
323 $files[$basename] = $file;
327 uksort($files, 'strnatcmp');
328 uksort($dirs, 'strnatcmp');
330 $data->files = array();
331 $data->dirs = array();
333 //$urlbase = $this->baseURL . '/browse.php';
334 //$pathbase = '/' . $repo->getBrowseRootName();
336 foreach ($dirs as $basename => $file) {
338 $ent = $file->getChangeEvent(); //MTrackSCMEvent
339 // let's copy extra stuff into the event..
340 //$ent->url = $urlbase . $pathbase . '/' . $file->name;
341 $ent->basename = $basename;
342 $ent->changelogOne = $ent->changelogOneToHtml();
344 $data->dirs[] = $ent;
347 foreach ($files as $basename => $file) {
348 $ent = $file->getChangeEvent();
349 if (!$ent) { // skips broken files..
353 $ent->basename = $basename;
355 $data->files[] = $ent;