1 <?php # vim:ts=2:sw=2:et:
2 /* For licensing and copyright terms, see the file named LICENSE */
5 // Browse.php - only for rendering the body..
6 // Tree.php - the actually tree..
8 require_once 'MTrackWeb.php';
10 class MTrackWeb_Tree extends MTrackWeb
12 var $baseURL; // 0 = new
13 var $masterTemplate = 'tree.html';
19 var $elements = array();
21 var $showCreate = false; // show create repo.
22 var $canEditRepo = false;
25 var $canDeleteFork = false;
36 require_once 'MTrack/ACL.php';
37 MTrackACL::requireAllRights('Browser', 'read');
45 $this->pi = '/'. $pi . (strlen($pi) ? $this->bootLoader->ext : '');
48 $crumbs = MTrackSCM::makeBreadcrumbs($this->pi); // i think this modifieds pi... naughty really.
50 // print_R($this->pi);
51 //var_dump($this->pi);
52 if (!strlen($this->pi) || $this->pi == '/') {
56 $this->repo = (count($crumbs) > 2) ? MTrackSCM::factory($this->pi) : null ;
62 if (isset($_GET['jump']) && strlen($_GET['jump'])) {
63 list($this->object, $this->ident) = explode(':', $_GET['jump'], 2);
67 $this->bdata = $this->getBrowseData($this->repo, $this->pi, $this->object, $this->ident);
69 //$this->bdata = mtrack_cache(
70 // array($this,'getBrowseData'),
71 // array($this->repo, $this->pi, $this->object, $this->ident)
74 if (isset($this->bdata->err) && strlen($this->pi) > 1) {
75 throw new Exception($this->bdata->err);
79 $this->crumbs = array();
81 // array_unshift($crumbs, '');
82 foreach($crumbs as $path)
84 if (count($this->crumbs) && !strlen($path)) {
88 $c->name = strlen($path) ? $path : '[root]';
89 $location .= strlen($location) ? '/' : '';
90 $location .= strlen($path) ? urlencode($path) : '';
91 $c->location = $location;
96 if (count($this->bdata->jumps)) {
97 require_once 'HTML/Template/Flexy/Element.php';
98 $this->elements['jump'] = new HTML_Template_Flexy_Element('select');
99 // print_r($bdata->jumps);
100 $this->elements['jump']->setOptions($this->bdata->jumps);
107 if (MTrackACL::hasAllRights('Browser', 'create')) {
108 /* some users may have rights to create repos that belong to projects.
109 * Determine that list of projects here, because we need it for both
110 * the fork and new repo cases */
111 $owners = array("user:{$this->authUser->userid}" => $this->authUser->userid);
112 $q = MTrackDB::q( 'select projid, shortname, name from projects order by ordinal') ;
113 foreach ($q->fetchAll(PDO::FETCH_ASSOC) as $row) {
114 if (MTrackACL::hasAllRights("project:". $row['projid'], 'modify')) {
115 $owners["project:". $row['shortname']] = $row['shortname'];
118 $this->showCreate = count($owners) > 1 ? true : false;
119 require_once 'HTML/Template/Flexy/Element.php';
120 $this->elements['repo:parent'] = new HTML_Template_Flexy_Element('select');
121 $this->elements['repo:parent']->setOptions($owners);
125 MTrackACL::requireAllRights("repo:{$this->repo->repoid}", 'read');
127 // this looks buggy..
129 if ( $this->repo->canFork() &&
130 MTrackACL::hasAllRights('Browser', 'fork') &&
131 MTrackConfig::get('repos', 'allow_user_repo_creation')
134 $this->canFork = true;
135 $this->forkname = $this->repo->shortname;
137 if ("{$this->authUser->userid}/{$this->repo->shortname}" == $this->repo->getBrowseRootName()) {
138 /* if this is mine already, make a "more unique" name for my new fork */
139 $this->forkname = $this->repo->shortname . '2';
143 if ( $this->repo->parent &&
144 MTrackACL::hasAllRights("repo:{$this->repo->repoid}", "delete")
147 $this->canDeleteFork = true;
150 if (MTrackACL::hasAllRights("repo:{$this->repo->repoid}", "modify")) {
151 $this->canEditRepo = true;
153 // watch UI is different in this version..
154 // MTrackWatch::renderWatchUI('repo', $repo->repoid);
158 /// non repo options..
162 && MTrackACL::hasAllRights('Browser', 'fork')
163 && MTrackConfig::get('repos', 'allow_user_repo_creation')
166 $repotypes = array();
168 foreach (MTrackRepo::getAvailableSCMs() as $t => $r) {
169 $d = $r->getSCMMetaData();
170 $repotypes[$t] = $d['name'];
172 require_once 'HTML/Template/Flexy/Element.php';
173 $this->elements['repo:type'] = new HTML_Template_Flexy_Element('select');
174 $this->elements['repo:type']->setOptions($repotypes);
179 if (count($this->crumbs) > 1) {
180 $this->dirname = $this->repo ? $this->repo->displayName() : '';
181 if (strlen($this->pi)) {
182 $this->dirname .='/'. $this->pi;
184 $this->up = dirname($pi);
185 $this->jump = isset($_GET['jump']) ? $_GET['jump'] : '';
193 $mine = 'user:' . $this->authUser->userid;
196 if (count($crumbs) == 2 && $crumbs[1] != 'default') {
197 /* looking for a particular subset */
198 $where = "parent like('%:' || ?)";
199 $params[] = $crumbs[1];
200 } else if (count($crumbs) == 2 && $crumbs[1] == 'default') {
201 /* looking at system items */
202 $where = "parent = ''";
204 /* looking for top level items */
207 /* have my own repos bubble up */
210 $q = MTrackDB::get()->prepare("
215 CASE WHEN parent = ? THEN 0 ELSE 1 END,
218 $q->execute($params);
219 $this->repos = array();
220 foreach ($q->fetchAll(PDO::FETCH_OBJ) as $rep) {
221 if (!MTrackACL::hasAnyRights("repo:{$rep->repoid}", 'read')) {
225 $this->repos[]= MTrackRepo::loadById($rep->repoid);
229 //print_r($this); exit;
242 function getBrowseData($repo, $pi, $object, $ident)
245 $data = new StdClass;
246 $data->dirs = array();
247 $data->files = array();
248 $data->jumps = array();
253 $branches = $repo->getBranches();
254 $tags = $repo->getTags();
255 if (count($branches) + count($tags)) {
256 $jumps = array("" => "- Select Branch / Tag - ");
257 if (is_array($branches)) {
258 foreach ($branches as $name => $notcare) {
259 $jumps["branch:$name"] = "Branch: $name";
262 if (is_array($tags)) {
263 foreach ($tags as $name => $notcare) {
264 $jumps["tag:$name"] = "Tag: $name";
267 $data->jumps = $jumps;
274 $ents = $repo->readdir($pi, $object, $ident);
275 } catch (Exception $e) {
276 // Typically a freshly created repo
278 $data->err = $e->getMessage();
280 // echo '<PRE>' ; var_dump($ents); echo '</PRE>' ;
281 foreach ($ents as $file) {
282 $basename = basename($file->name);
284 $dirs[$basename] = $file;
286 $files[$basename] = $file;
290 uksort($files, 'strnatcmp');
291 uksort($dirs, 'strnatcmp');
293 $data->files = array();
294 $data->dirs = array();
296 $urlbase = $this->baseURL . '/browse.php';
297 $pathbase = '/' . $repo->getBrowseRootName();
299 foreach ($dirs as $basename => $file) {
301 $ent = $file->getChangeEvent(); //MTrackSCMEvent
302 // let's copy extra stuff into the event..
303 $ent->url = $urlbase . $pathbase . '/' . $file->name;
304 $ent->basename = $basename;
305 $ent->changelogOne = $ent->changelogOneToHtml();
307 $data->dirs[] = $ent;
310 foreach ($files as $basename => $file) {
311 $ent = $file->getChangeEvent();
312 if (!$ent) { // skips broken files..
316 $ent->basename = $basename;
318 $data->files[] = $ent;
332 // read the data for the page..
333 //$bdata = get_browse_data($repo, $pi, $object, $ident);
338 /* Render a bread-crumb enabled location indicator */