8e69ffd189df1b7a95333d1952b9bc3faa16ef4e
[phpgitweb.git] / htdocs / pages / shortlog.class.php
1 <?php
2 /* shortlog.class.php - phpgitweb
3  * Copyright (C) 2011-2012  Philipp Kreil (pk910)
4  * 
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  * 
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  * 
15  * You should have received a copy of the GNU General Public License 
16  * along with this program. If not, see <http://www.gnu.org/licenses/>. 
17  */
18
19 require_once('lib/graph.class.php');
20
21 class shortlog {
22         private $project;
23         private $graph_data;
24         private $first_commit;
25         private $have_more = false;
26         
27         public function generate_shortlog($project, $head, $max, $skip, $file = null, $pages = true, $next_page = 0) {
28                 $this->project = $project;
29                 if($head && strtolower($head) == 'all')
30                         $head = null;
31                 $content = new ContentProvider('shortlog', 'shortlog');
32                 
33                 if(GitConfig::GITGRAPH_ENABLE) {
34                         if($max+$skip >= 2000) { //only load the last 2k commits
35                                 $real_skip = ($max+$skip) - 2000;
36                                 $skip -= $real_skip;
37                         } else
38                                 $real_skip = 0;
39                 } else {
40                         $real_skip = $skip;
41                         $skip = 0;
42                 }
43                 
44                 $commits = GitCommand::get_commits($project['path'], $head, $max+$skip+1, $real_skip, $file);
45                 
46                 if(GitConfig::GITGRAPH_ENABLE) {
47                         $this->graph_data = new graph_data_generator();
48                         if($head == null) {
49                                 //add all refs to the graph
50                                 $rhash = GitCommand::get_hash($project['path'], "HEAD");
51                                 if($rhash)
52                                         $this->graph_data->add_branch($rhash, null);
53                                 
54                                 foreach($this->project['refs'] as $ref => $rhash) {
55                                         if(preg_match('#^refs/heads/#i', $ref) && preg_match('/^[a-f0-9]*$/i', $rhash)) {
56                                                 $this->graph_data->add_branch($rhash, $ref);
57                                         }
58                                 }
59                                 foreach($this->project['refs'] as $ref => $rhash) {
60                                         if(preg_match('#^refs/remotes/#i', $ref) && preg_match('/^[a-f0-9]*$/i', $rhash)) {
61                                                 $this->graph_data->add_branch($rhash, $ref);
62                                         }
63                                 }
64                         }
65                         $this->graph_data->parse($commits);
66                         $content->set('graph_data', $this->graph_data->get_header_graph());
67                 }
68                 
69                 $commit_counter = 0;
70                 $this->first_commit = $commits[0];
71                 foreach($commits as $commit) {
72                         $commit_counter++;
73                         if($commit_counter < $skip)
74                                 continue;
75                         if($commit_counter > $max+$skip) {
76                                 $this->have_more = true;
77                                 if($pages) {
78                                         $content->append('entries', new ContentProvider('shortlog', 'shortlog_page', array("page" => $next_page)));
79                                 } else
80                                         $content->append('entries', new ContentProvider('shortlog', 'shortlog_more'));
81                         } else
82                                 $content->append('entries', $this->shortlog_entry(($commit_counter % 2 ? 'dark' : 'light'), $commit));
83                 }
84                 
85                 return $content;
86         }
87         
88         public function get_first_commit() {
89                 return $this->first_commit;
90         }
91         
92         public function get_have_more() {
93                 return $this->have_more;
94         }
95         
96         private function shortlog_entry($class, $commit) {
97                 $entry = new ContentProvider('shortlog', 'shortlog_entry');
98                 $entry->set('class', $class);
99                 $entry->set('hash', $commit['id']);
100                 $entry->set('author', htmlentities($commit['author']));
101                 $entry->set('message', htmlentities(Tools::chop_text($commit['text'], 50, 5)));
102                 $age = time() - $commit['committer_time'];
103                 $date_str = date("Y-m-d", ($commit['committer_time'] ? $commit['committer_time'] : $commit['author_time']));
104                 $age_calc = Tools::age_calculate($commit['committer_time']);
105                 $age_str = $age_calc['age_str'];
106                 if($age > 60*60*24*7*2) {
107                         $entry->set('date', $age_str);
108                         $entry->set('age', $date_str);
109                 } else {
110                         $entry->set('date', $date_str);
111                         $entry->set('age', $age_str);
112                 }
113                 if(GitConfig::GITGRAPH_ENABLE)
114                         $entry->set('graph_data', $this->graph_data->get_graph($commit['id']));
115                 
116                 $entry->set('refs', $this->shortlog_commit_refs($this->project, $commit['id']));
117                 
118                 return $entry;
119         }
120         
121         public function shortlog_commit_refs($project, $hash) {
122                 if(!is_array($project['refs']))
123                         return "";
124                 $refs = new ContentProvider('shortlog', 'shortlog_refs');
125                 $found = false;
126                 foreach($project['refs'] as $ref => $rhash) {
127                         if(strtolower($rhash) == strtolower($hash)) {
128                                 $refexp = explode('/', $ref, 3);
129                                 $reftype = $refexp[1];
130                                 if($reftype == 'heads')
131                                         $reftype = 'head';
132                                 else if($reftype == 'remotes')
133                                         $reftype = 'remote';
134                                 else if($reftype == 'tags')
135                                         $reftype = 'tag';
136                                 $refs->append('refs', new ContentProvider('shortlog', 'shortlog_ref_'.$reftype, array("name" => $refexp[2], "ref_link" => $ref)));
137                                 $found = true;
138                         }
139                 }
140                 return ($found ? $refs : "");
141         }
142         
143 }
144
145
146 class page_shortlog {
147     private $page, $phpgitweb;
148         
149     public function main($phpgitweb, $project) {
150                 $this->phpgitweb = $phpgitweb;
151                 $this->project = $project;
152                 if(!$this->project)
153                         return new ContentProvider('main', 'err400');
154                 $project['refs'] = $phpgitweb->get_project_loader()->getProjectRefs($project);
155                 $phpgitweb->append_header_nav("shortlog", null, true);
156                 $phpgitweb->append_title("shortlog");
157                 CommitLoader::parse(true);
158                 
159                 $this->page = new ContentProvider('shortlog', 'main');
160                 
161                 //pages
162                 if(array_key_exists('pg', $_GET)) {
163                         $pg = $_GET['pg'];
164                         if($pg < 0)
165                                 $pg = 0;
166                         $skip = $_GET['pg'] * 100;
167                         $next_page = $_GET['pg'] + 1;
168                 } else {
169                         $pg = 0;
170                         $skip = 0;
171                         $next_page = 1;
172                 }
173                 
174                 $subnav = new ContentProvider('shortlog', 'shortlog_subnav');
175                 $phpgitweb->append_sub_nav($subnav);
176                 
177                 if($pg) {
178                         $subnav->set('first', new ContentProvider('shortlog', 'shortlog_subnav_first_link'));
179                         $subnav->set('prev', new ContentProvider('shortlog', 'shortlog_subnav_prev_link', array('page' => ($pg - 1))));
180                 } else {
181                         $subnav->set('first', new ContentProvider('shortlog', 'shortlog_subnav_first'));
182                         $subnav->set('prev', new ContentProvider('shortlog', 'shortlog_subnav_prev'));
183                 }
184                 
185                 $shortlog = new shortlog();
186                 $this->page->set('shortlog', $shortlog->generate_shortlog($project, CommitLoader::$commit_base_id, 100, $skip, null, true, $next_page));
187                 
188                 if($shortlog->get_have_more())
189                         $subnav->set('next', new ContentProvider('shortlog', 'shortlog_subnav_next_link', array('page' => ($pg + 1))));
190                 else
191                         $subnav->set('next', new ContentProvider('shortlog', 'shortlog_subnav_next'));
192                 
193                 return $this->page;
194         }
195         
196 }
197
198 ?>