final move of files
[web.mtrack] / MTrackWeb / Tree.php
1 <?php # vim:ts=2:sw=2:et:
2 /* For licensing and copyright terms, see the file named LICENSE */
3
4
5 // Browse.php - only for rendering the body..
6 // Tree.php - the actually tree..
7
8 require_once 'MTrackWeb.php';
9  
10 class MTrackWeb_Tree extends MTrackWeb
11 {
12     var $baseURL; // 0 = new
13     var $masterTemplate = 'tree.html';
14  
15     var $object;
16     var $ident;
17     
18     var $repo;
19     var $elements = array();
20     
21     var $showCreate = false; // show create repo.
22     var $canEditRepo = false;
23     
24     var $canFork = false;
25     var $canDeleteFork = false;
26     
27     var $forkname = '';
28     
29   
30     var $up = '';
31     var $jump = '';
32     
33     function getAuth() 
34     {
35         parent::getAuth();
36         require_once 'MTrack/ACL.php';
37         MTrackACL::requireAllRights('Browser', 'read');
38         return true;
39   
40     }
41  
42     function get($pi)
43     {
44           
45         $this->pi = '/'. $pi . (strlen($pi) ? $this->bootLoader->ext : '');
46        
47         //var_dump($pi);
48         $crumbs = MTrackSCM::makeBreadcrumbs($this->pi); // i think this modifieds pi... naughty really.
49         
50        // print_R($this->pi);
51         //var_dump($this->pi);
52         if (!strlen($this->pi) || $this->pi == '/') {
53             $this->pi = '/';
54         }
55           
56         $this->repo  = (count($crumbs) > 2) ?   MTrackSCM::factory($this->pi) : null ;
57          
58         
59         $this->object = null;
60         $this->ident = null;
61         
62         if (isset($_GET['jump']) && strlen($_GET['jump'])) {
63             list($this->object, $this->ident) = explode(':', $_GET['jump'], 2);
64         }
65         
66         
67         $this->bdata = $this->getBrowseData($this->repo, $this->pi, $this->object, $this->ident);
68         
69         //$this->bdata = mtrack_cache(
70         //    array($this,'getBrowseData'), 
71         //    array($this->repo, $this->pi, $this->object, $this->ident)
72         //);
73
74         if (isset($this->bdata->err) && strlen($this->pi) > 1) {
75             throw new Exception($this->bdata->err);
76         }
77         
78         
79         $this->crumbs = array();
80         $location = null;
81        // array_unshift($crumbs, '');
82         foreach($crumbs as $path) 
83         {
84             if (count($this->crumbs) && !strlen($path)) {
85                 continue;
86             }
87             $c = new StdClass;
88             $c->name = strlen($path) ? $path : '[root]';
89             $location .=  strlen($location) ? '/' : '';
90             $location .=  strlen($path)  ?  urlencode($path)  : '';
91             $c->location = $location;
92             $this->crumbs[] = $c;
93         }
94
95          
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);
101         }
102         
103         
104         
105         
106         
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'];
116                 }
117             }
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);
122         }
123         
124         if ($this->repo) {
125             MTrackACL::requireAllRights("repo:{$this->repo->repoid}", 'read');
126              
127             // this looks buggy..
128      
129             if (    $this->repo->canFork() && 
130                     MTrackACL::hasAllRights('Browser', 'fork') &&
131                     MTrackConfig::get('repos', 'allow_user_repo_creation')
132                 ) {
133                     
134                 $this->canFork = true;
135                 $this->forkname = $this->repo->shortname;
136                 
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';
140                 }
141             }
142             
143             if (    $this->repo->parent &&
144                     MTrackACL::hasAllRights("repo:{$this->repo->repoid}", "delete")
145                 ) {
146                     
147                 $this->canDeleteFork = true;
148             }
149             
150             if (MTrackACL::hasAllRights("repo:{$this->repo->repoid}", "modify")) {
151                 $this->canEditRepo = true;
152             }
153             // watch UI is different in this version..
154             // MTrackWatch::renderWatchUI('repo', $repo->repoid);
155             
156         }
157         
158         /// non repo options..
159         
160
161         if (!$this->repo 
162             && MTrackACL::hasAllRights('Browser', 'fork')
163             && MTrackConfig::get('repos', 'allow_user_repo_creation')
164             ){
165                 
166             $repotypes = array();
167             
168             foreach (MTrackRepo::getAvailableSCMs() as $t => $r) {
169               $d = $r->getSCMMetaData();
170               $repotypes[$t] = $d['name'];
171             }
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);
175         }
176         
177         
178         // up...
179         if (count($this->crumbs) > 1) {
180             $this->dirname = $this->repo ? $this->repo->displayName() : '';
181             if (strlen($this->pi)) {
182                 $this->dirname .='/'. $this->pi;
183             }
184             $this->up =  dirname($pi);
185             $this->jump =  isset($_GET['jump']) ? $_GET['jump'] : '';
186         }
187     
188         
189         
190         
191                 
192         if (!$this->repo) {
193             $mine = 'user:' . $this->authUser->userid; 
194           
195             $params = array();
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 = ''";
203             } else {
204                 /* looking for top level items */
205                 $where = "1 = 1";
206             }
207             /* have my own repos bubble up */
208             $params[] = $mine;
209             
210             $q = MTrackDB::get()->prepare("
211                 SELECT repoid
212                 FROM repos
213                 WHERE $where
214                 ORDER BY
215                   CASE WHEN parent = ? THEN 0 ELSE 1 END,
216                   shortname
217             ");
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')) {
222                     continue;
223                 }
224                 
225                 $this->repos[]= MTrackRepo::loadById($rep->repoid);
226             }
227         }
228
229         //print_r($this); exit;
230         
231           
232     }
233      
234     
235      
236   
237     
238     
239
240
241 // static..?
242     function getBrowseData($repo, $pi, $object, $ident)
243     {
244         
245         $data = new StdClass;
246         $data->dirs = array();
247         $data->files = array();
248         $data->jumps = array();
249
250         if (!$repo) {
251             return $data;
252         }
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";
260                 }
261             }
262             if (is_array($tags)) {
263                 foreach ($tags as $name => $notcare) {
264                     $jumps["tag:$name"] = "Tag: $name";
265                 }
266             }
267             $data->jumps = $jumps;
268         }
269         $files = array();
270         $dirs = array();
271        
272         if ($repo) {
273             try {
274                 $ents = $repo->readdir($pi, $object, $ident);
275             } catch (Exception $e) {
276                   // Typically a freshly created repo
277                   $ents = array();
278                   $data->err = $e->getMessage();
279             }
280            // echo '<PRE>' ; var_dump($ents); echo '</PRE>' ;
281             foreach ($ents as $file) {
282                 $basename = basename($file->name);
283                 if ($file->is_dir) {
284                     $dirs[$basename] = $file;
285                 } else {
286                     $files[$basename] = $file;
287                 }
288             }
289         }
290         uksort($files, 'strnatcmp');
291         uksort($dirs, 'strnatcmp');
292
293         $data->files = array();
294         $data->dirs = array();
295
296         $urlbase    = $this->baseURL . '/browse.php';
297         $pathbase   = '/' . $repo->getBrowseRootName();
298
299         foreach ($dirs as $basename => $file) {
300             
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();
306             
307             $data->dirs[] = $ent;
308         }
309         
310         foreach ($files as $basename => $file) {
311             $ent = $file->getChangeEvent();
312             if (!$ent) { // skips broken files..
313                 continue;
314             }
315             // needed?
316             $ent->basename = $basename;
317             
318             $data->files[] = $ent;
319         }
320
321         return $data;
322     }
323     
324      
325     
326 }
327     
328     
329
330   
331
332 // read the data for the page..
333 //$bdata = get_browse_data($repo, $pi, $object, $ident);
334
335 //print_R($bdata);
336
337
338 /* Render a bread-crumb enabled location indicator */
339
340
341
342
343
344   
345   
346  
347   
348  
349
350
351
352  
353   
354
355