use data links for git graph images
[phpgitweb.git] / htdocs / lib / PageClasses.shortlog.class.php
1 <?php
2 /* PageClasses.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 class shortlog {
20         private $project;
21         private $graph_data, $graph_gen;
22         private $first_commit;
23         private $have_more = false;
24         
25         public function generate_shortlog($project, $head, $max, $skip, $file = null, $pages = true, $next_page = 0) {
26                 $this->project = $project;
27                 if($head && strtolower($head) == 'all')
28                         $head = null;
29                 $content = new ContentProvider('shortlog', 'shortlog');
30                 
31                 if(GitConfig::GITGRAPH_ENABLE) {
32                         if($max+$skip >= 2000) { //only load the last 2k commits
33                                 $real_skip = ($max+$skip) - 2000;
34                                 $skip -= $real_skip;
35                         } else
36                                 $real_skip = 0;
37                 } else {
38                         $real_skip = $skip;
39                         $skip = 0;
40                 }
41                 
42                 $commits = GitCommand::get_commits($project['path'], $head, $max+$skip+1, $real_skip, $file);
43                 
44                 if(GitConfig::GITGRAPH_ENABLE) {
45                         $this->graph_data = new graph_data_generator();
46                         if($head == null) {
47                                 //add all refs to the graph
48                                 $rhash = GitCommand::get_hash($project['path'], "HEAD");
49                                 if($rhash)
50                                         $this->graph_data->add_branch($rhash, null);
51                                 
52                                 foreach($this->project['refs'] as $ref => $rhash) {
53                                         if(preg_match('#^refs/heads/#i', $ref) && preg_match('/^[a-f0-9]*$/i', $rhash)) {
54                                                 $this->graph_data->add_branch($rhash, $ref);
55                                         }
56                                 }
57                                 foreach($this->project['refs'] as $ref => $rhash) {
58                                         if(preg_match('#^refs/remotes/#i', $ref) && preg_match('/^[a-f0-9]*$/i', $rhash)) {
59                                                 $this->graph_data->add_branch($rhash, $ref);
60                                         }
61                                 }
62                         }
63                         $this->graph_data->parse($commits);
64                         
65                         $graph = $this->graph_data->get_header_graph();
66                         if(GitConfig::GITGRAPH_DATA_URL) {
67                                 $this->graph_gen = new graph_image_generator();
68                                 $graph = $this->graph_gen->generate($graph, true);
69                                 $graph = base64_encode($graph);
70                                 $graph = "data:image/png;base64,".$graph;
71                         } else
72                                 $graph = "?e=graph&gd=".$graph;
73                         $content->set('graph_data', $graph);
74                 }
75                 
76                 $commit_counter = 0;
77                 $this->first_commit = $commits[0];
78                 foreach($commits as $commit) {
79                         $commit_counter++;
80                         if($commit_counter <= $skip)
81                                 continue;
82                         if($commit_counter > $max+$skip) {
83                                 $this->have_more = true;
84                                 if($pages) {
85                                         $content->append('entries', new ContentProvider('shortlog', 'shortlog_page', array("page" => $next_page)));
86                                 } else
87                                         $content->append('entries', new ContentProvider('shortlog', 'shortlog_more'));
88                         } else
89                                 $content->append('entries', $this->shortlog_entry(($commit_counter % 2 ? 'dark' : 'light'), $commit));
90                 }
91                 
92                 return $content;
93         }
94         
95         public function get_first_commit() {
96                 return $this->first_commit;
97         }
98         
99         public function get_have_more() {
100                 return $this->have_more;
101         }
102         
103         private function shortlog_entry($class, $commit) {
104                 $entry = new ContentProvider('shortlog', 'shortlog_entry');
105                 $entry->set('class', $class);
106                 $entry->set('hash', $commit['id']);
107                 $entry->set('author', htmlentities($commit['author']));
108                 $entry->set('message', htmlentities(Tools::chop_text($commit['text'], 50, 5)));
109                 $age = time() - $commit['committer_time'];
110                 $date_str = date("Y-m-d", ($commit['committer_time'] ? $commit['committer_time'] : $commit['author_time']));
111                 $age_calc = Tools::age_calculate($commit['committer_time']);
112                 $age_str = $age_calc['age_str'];
113                 if($age > 60*60*24*7*2) {
114                         $entry->set('date', $age_str);
115                         $entry->set('age', $date_str);
116                 } else {
117                         $entry->set('date', $date_str);
118                         $entry->set('age', $age_str);
119                 }
120                 if(GitConfig::GITGRAPH_ENABLE) {
121                         $graph = $this->graph_data->get_graph($commit['id']);
122                         if(GitConfig::GITGRAPH_DATA_URL) {
123                                 $graph = $this->graph_gen->generate($graph, true);
124                                 $graph = base64_encode($graph);
125                                 $graph = "data:image/png;base64,".$graph;
126                         } else
127                                 $graph = "?e=graph&gd=".$graph;
128                         $entry->set('graph_data', $graph);
129                 }
130                 
131                 $entry->set('refs', $this->shortlog_commit_refs($this->project, $commit['id']));
132                 
133                 return $entry;
134         }
135         
136         public function shortlog_commit_refs($project, $hash) {
137                 if(!is_array($project['refs']))
138                         return "";
139                 $refs = new ContentProvider('shortlog', 'shortlog_refs');
140                 $found = false;
141                 foreach($project['refs'] as $ref => $rhash) {
142                         if(strtolower($rhash) == strtolower($hash)) {
143                                 $refexp = explode('/', $ref, 3);
144                                 $reftype = $refexp[1];
145                                 if($reftype == 'heads')
146                                         $reftype = 'head';
147                                 else if($reftype == 'remotes')
148                                         $reftype = 'remote';
149                                 else if($reftype == 'tags')
150                                         $reftype = 'tag';
151                                 $refs->append('refs', new ContentProvider('shortlog', 'shortlog_ref_'.$reftype, array("name" => $refexp[2], "ref_link" => $ref)));
152                                 $found = true;
153                         }
154                 }
155                 return ($found ? $refs : "");
156         }
157         
158 }
159
160 ?>