MTrackWeb/Browse.php
[web.mtrack] / MTrackWeb / Browse.php
1 <?php # vim:ts=2:sw=2:et:
2 /* For licensing and copyright terms, see the file named LICENSE */
3
4 /**
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
8  *
9  *
10  *
11  */
12
13 // Browse.php - only for rendering the body..
14 // Tree.php - the actually tree..
15
16 require_once 'MTrackWeb.php';
17
18 class MTrackWeb_Browse extends MTrackWeb
19 {
20    
21     
22     
23     
24  
25     var $object;
26     var $ident;
27     
28     var $repo;
29     var $elements = array();
30     
31     var $showCreate = false; // show create repo.
32     var $canEditRepo = false;
33     
34     var $canFork = false;
35     var $canDeleteFork = false;
36     
37     var $forkname = '';
38     
39     var $bdata = false;
40   
41     var $up = '';
42     var $jump = '';
43     
44     function getAuth() 
45     {
46         parent::getAuth();
47         
48         return true;
49   
50     }
51  
52     function get($pi)
53     {
54          $this->pi =  $pi . (strlen($pi) ? $this->bootLoader->ext : '');
55        
56         if (!isset($_REQUEST['ajax_body'])) {
57             $this->title =  $this->pi;
58             return;
59         }
60         $this->masterTemplate = 'tree.html';
61         //DB_DataObject::debugLevel(1);
62        
63         //var_dump($pi);
64         
65          
66         $this->repo = DB_DataObject::factory('mtrack_repos');
67         $file = $this->repo->loadFromPath($this->pi);
68         if (!$this->repo->id) {
69             $this->repo = false;
70         }
71         
72         $this->object = null;
73         $this->ident = null;
74         
75         if (isset($_GET['jump']) && strlen($_GET['jump'])) {
76             list($this->object, $this->ident) = explode(':', $_GET['jump'], 2);
77         }
78         
79         if ($this->repo) {
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..
82             }
83             
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);
87             }
88             require_once 'MTrack/Wiki/Item.php';
89             //make sure we can render..
90             MTrack_Wiki_Item::$repo = $this->repo->impl();
91         }    
92         //$this->repo  = (count($crumbs) > 2) ?   MTrackSCM::factory($this->pi) : null ;
93          
94         
95         
96         
97        
98         
99         //$this->bdata = mtrack_cache(
100         //    array($this,'getBrowseData'), 
101         //    array($this->repo, $this->pi, $this->object, $this->ident)
102         //);
103
104         $this->basename  = basename($file);
105         $location = '';
106         $crumbs = explode('/', dirname($file));
107         if (strlen($file)) {
108             array_unshift($crumbs, ''); // add empty at front..
109         }
110         
111         $this->crumbs = array();
112         
113         if (!$this->repo) {
114             $crumbs = array();
115         }
116         
117         foreach($crumbs as $path) 
118         {
119              
120             $c = new StdClass;
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;
126         }
127        // echo '<PRE>';print_R($this->crumbs);
128          
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);
134         }
135         
136         
137         
138         
139          /*
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 */
144             /*
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'];
150                 }
151             }
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);
156             
157         }
158           
159         if ($this->repo) {
160             MTrackACL::requireAllRights("repo:{$this->repo->id}", 'read');
161              
162             // this looks buggy..
163            
164             if (    $this->repo->canFork() && 
165                     MTrackACL::hasAllRights('Browser', 'fork') &&
166                     MTrackConfig::get('repos', 'allow_user_repo_creation')
167                 ) {
168                     
169                 $this->canFork = true;
170                 $this->forkname = $this->repo->shortname;
171                 
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';
175                 }
176             }
177             
178             if (    $this->repo->parent &&
179                     MTrackACL::hasAllRights("repo:{$this->repo->id}", "delete")
180                 ) {
181                     
182                 $this->canDeleteFork = true;
183             }
184             
185             if (MTrackACL::hasAllRights("repo:{$this->repo->id}", "modify")) {
186                 $this->canEditRepo = true;
187             }
188             // watch UI is different in this version..
189             // MTrackWatch::renderWatchUI('repo', $repo->id);
190             
191         }
192          */
193         /// non repo options..
194         
195
196         
197         $this->dirname = $this->repo ? $this->repo->displayName() : '';
198         // up...
199         if (strlen($file)) {
200             $this->dirname .= '/'. $file;
201         }
202         $this->up =  strlen($file) ? dirname($this->dirname) : '';
203         $this->jump =  isset($_GET['jump']) ? $_GET['jump'] : '';
204     
205          if (!$this->repo) {
206             return $this->noRepo(explode('/', $pi));
207          
208         }
209         //print_r($this); exit;
210         
211           
212     }
213      
214     function noRepo($crumbs)
215     {
216         
217         /*if (  MTrackACL::hasAllRights('Browser', 'fork')
218             && MTrackConfig::get('repos', 'allow_user_repo_creation')
219             ){
220                 
221             $repotypes = array();
222             
223             foreach (MTrack_Repo::getAvailableSCMs() as $t => $r) {
224               $d = $r->getSCMMetaData();
225               $repotypes[$t] = $d['name'];
226             }
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);
230         }
231         */
232        // DB_DataObject::debugLevel(1);
233         $mine = $this->authUser ? "user:{$this->authUser->id}" : '';
234         
235         $do = DB_DataObject::factory('mtrack_repos');
236         $params = array();
237          
238         $crumbs[0]  = empty($crumbs[0]) ? 'default' : $crumbs[0] ;
239         
240         if (count($crumbs) == 1 && $crumbs[0] != 'default') {
241         
242              $do->whereAdd("parent like('%:". $do->escape($crumbs[0]). "')"); // subset
243              
244          } else if (count($crumbs) == 1 && $crumbs[0] == 'default') {
245          
246             $do->whereAdd(" parent = ''"); // top level..
247          } else {
248              /* looking for top level items */
249              ///$where = "1 = 1";
250          }
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");
254         } else {
255             $do->orderBy("shortname ASC");
256         }
257 // FIXME -> permissions on repositories goes here.. 
258         //$do->ensurePerm($this->authUser); 
259         //$do->fetchAll();
260         $do->find();
261         $this->repos= array();
262         while ($do->fetch()) {
263              
264             if (!$this->projectPerm($do->project_id, 'MTrack.Repos', 'S')) {
265                  continue;
266             }
267              
268             $this->repos[]= clone($do);
269             
270         }
271       
272     
273      
274     }
275     
276     
277
278
279 // static..?
280     function getBrowseData($repo, $pi, $object, $ident)
281     {
282          $data = new StdClass;
283         $data->dirs = array();
284         $data->files = array();
285         $data->jumps = array();
286
287         if (!$repo) {
288             return $data;
289         }
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";
297                 }
298             }
299             if (is_array($tags)) {
300                 foreach ($tags as $name => $notcare) {
301                     $jumps["tag:$name"] = "Tag: $name";
302                 }
303             }
304             $data->jumps = $jumps;
305         }
306         $files = array();
307         $dirs = array();
308        
309         if ($repo) {
310             //try {
311                 $ents = $repo->readdir($pi, $object, $ident);
312             //} catch (Exception $e) {
313                   // Typically a freshly created repo
314               //    $ents = array();
315                 //  $data->err = $e->getMessage();
316             //}
317            // echo '<PRE>' ; var_dump($ents); echo '</PRE>' ;
318             foreach ($ents as $file) {
319                 $basename = basename($file->name);
320                 if ($file->is_dir) {
321                     $dirs[$basename] = $file;
322                 } else {
323                     $files[$basename] = $file;
324                 }
325             }
326         }
327         uksort($files, 'strnatcmp');
328         uksort($dirs, 'strnatcmp');
329
330         $data->files = array();
331         $data->dirs = array();
332
333         //$urlbase    = $this->baseURL . '/browse.php';
334         //$pathbase   = '/' . $repo->getBrowseRootName();
335         
336         foreach ($dirs as $basename => $file) {
337             
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();
343             
344             $data->dirs[] = $ent;
345         }
346         
347         foreach ($files as $basename => $file) {
348             $ent = $file->getChangeEvent();
349             if (!$ent) { // skips broken files..
350                 continue;
351             }
352             // needed?
353             $ent->basename = $basename;
354             
355             $data->files[] = $ent;
356         }
357
358         return $data;
359     }
360     
361      
362     
363 }
364     
365      
366     
367      
368     
369
370