InDefero

Sign in or create your account | Project List | Help

InDefero Git Source Tree

Root/src/IDF/Commit.php

1<?php
2/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3/*
4# ***** BEGIN LICENSE BLOCK *****
5# This file is part of InDefero, an open source project management application.
6# Copyright (C) 2008 Céondo Ltd and contributors.
7#
8# InDefero is free software; you can redistribute it and/or modify
9# it under the terms of the GNU General Public License as published by
10# the Free Software Foundation; either version 2 of the License, or
11# (at your option) any later version.
12#
13# InDefero is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16n# GNU General Public License for more details.
17#
18# You should have received a copy of the GNU General Public License
19# along with this program; if not, write to the Free Software
20# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21#
22# ***** END LICENSE BLOCK ***** */
23
24Pluf::loadFunction('Pluf_HTTP_URL_urlForView');
25Pluf::loadFunction('Pluf_Template_dateAgo');
26
27/**
28 * Base definition of a commit.
29 *
30 * By having a reference in the database for each commit, one can
31 * easily generate a timeline or use the search engine. Commit details
32 * are normally always taken from the underlining SCM.
33 */
34class IDF_Commit extends Pluf_Model
35{
36    public $_model = __CLASS__;
37
38    function init()
39    {
40        $this->_a['table'] = 'idf_commits';
41        $this->_a['model'] = __CLASS__;
42        $this->_a['cols'] = array(
43                             // It is mandatory to have an "id" column.
44                            'id' =>
45                            array(
46                                  'type' => 'Pluf_DB_Field_Sequence',
47                                  'blank' => true,
48                                  ),
49                            'project' =>
50                            array(
51                                  'type' => 'Pluf_DB_Field_Foreignkey',
52                                  'model' => 'IDF_Project',
53                                  'blank' => false,
54                                  'verbose' => __('project'),
55                                  'relate_name' => 'commits',
56                                  ),
57                            'author' =>
58                            array(
59                                  'type' => 'Pluf_DB_Field_Foreignkey',
60                                  'model' => 'Pluf_User',
61                                  'is_null' => true,
62                                  'verbose' => __('submitter'),
63                                  'relate_name' => 'submitted_commit',
64                                  'help_text' => 'This will allow us to list the latest commits of a user in its profile.',
65                                  ),
66                            'origauthor' =>
67                            array(
68                                  'type' => 'Pluf_DB_Field_Varchar',
69                                  'blank' => false,
70                                  'size' => 150,
71                                  'help_text' => 'As we do not necessary have the mapping between the author in the database and the scm, we store the scm author commit information here. That way we can update the author info later in the process.',
72                                  ),
73                            'scm_id' =>
74                            array(
75                                  'type' => 'Pluf_DB_Field_Varchar',
76                                  'blank' => false,
77                                  'size' => 50,
78                                  'index' => true,
79                                  'help_text' => 'The id of the commit. For git, it will be the SHA1 hash, for subversion it will be the revision id.',
80                                  ),
81                            'summary' =>
82                            array(
83                                  'type' => 'Pluf_DB_Field_Varchar',
84                                  'blank' => false,
85                                  'size' => 250,
86                                  'verbose' => __('summary'),
87                                  ),
88                            'fullmessage' =>
89                            array(
90                                  'type' => 'Pluf_DB_Field_Text',
91                                  'blank' => true,
92                                  'verbose' => __('changelog'),
93                                  'help_text' => 'This is the full message of the commit.',
94                                  ),
95                            'creation_dtime' =>
96                            array(
97                                  'type' => 'Pluf_DB_Field_Datetime',
98                                  'blank' => true,
99                                  'verbose' => __('creation date'),
100                                  'index' => true,
101                                  'help_text' => 'Date of creation by the scm',
102                                  ),
103                            );
104    }
105
106    function __toString()
107    {
108        return $this->summary.' - ('.$this->scm_id.')';
109    }
110
111    function _toIndex()
112    {
113        $str = str_repeat($this->summary.' ', 4).' '.$this->fullmessage;
114        return Pluf_Text::cleanString(html_entity_decode($str, ENT_QUOTES, 'UTF-8'));
115    }
116
117    function postSave($create=false)
118    {
119        IDF_Search::index($this);
120        if ($create) {
121            IDF_Timeline::insert($this, $this->get_project(),
122                                 $this->get_author(), $this->creation_dtime);
123        }
124    }
125
126    function preDelete()
127    {
128        IDF_Timeline::remove($this);
129        IDF_Search::remove($this);
130    }
131
132    /**
133     * Create a commit from a simple class commit info of a changelog.
134     *
135     * @param stdClass Commit info
136     * @param IDF_Project Current project
137     * @return IDF_Commit
138     */
139    public static function getOrAdd($change, $project)
140    {
141        $sql = new Pluf_SQL('project=%s AND scm_id=%s',
142                            array($project->id, $change->commit));
143        $r = Pluf::factory('IDF_Commit')->getList(array('filter'=>$sql->gen()));
144        if ($r->count() > 0) {
145            return $r[0];
146        }
147        if (!isset($change->full_message)) {
148            $change->full_message = '';
149        }
150        $scm = IDF_Scm::get($project);
151        $commit = new IDF_Commit();
152        $commit->project = $project;
153        $commit->scm_id = $change->commit;
154        list($commit->summary, $commit->fullmessage) = self::toUTF8(array($change->title, $change->full_message));
155        $commit->author = $scm->findAuthor($change->author);
156        $commit->origauthor = $change->author;
157        $commit->creation_dtime = $change->date;
158        $commit->create();
159        $commit->notify($project->getConf());
160        return $commit;
161    }
162
163    /**
164     * Convert encoding to UTF8.
165     *
166     * If an array is given, the encoding is detected only on the
167     * first value and then used to convert all the strings.
168     *
169     * @param mixed String or array of string to be converted
170     * @return mixed String or array of string
171     */
172    public static function toUTF8($text)
173    {
174        $enc = 'ASCII, UTF-8, ISO-8859-1, JIS, EUC-JP, SJIS';
175        $ref = $text;
176        if (is_array($text)) {
177            $ref = $text[0];
178        }
179        if (Pluf_Text_UTF8::check($ref)) {
180            return $text;
181        }
182        $encoding = mb_detect_encoding($ref, $enc, true);
183        if ($encoding == false) {
184            $encoding = Pluf_Text_UTF8::detect_cyr_charset($ref);
185        }
186        if (is_array($text)) {
187            foreach ($text as $t) {
188                $res[] = mb_convert_encoding($t, 'UTF-8', $encoding);
189            }
190            return $res;
191        } else {
192            return mb_convert_encoding($text, 'UTF-8', $encoding);
193        }
194    }
195
196    /**
197     * Returns the timeline fragment for the commit.
198     *
199     *
200     * @param Pluf_HTTP_Request
201     * @return Pluf_Template_SafeString
202     */
203    public function timelineFragment($request)
204    {
205        $url = Pluf_HTTP_URL_urlForView('IDF_Views_Source::commit',
206                                        array($request->project->shortname,
207                                              $this->scm_id));
208        $out = '<tr class="log"><td><a href="'.$url.'">'.
209            Pluf_esc(Pluf_Template_dateAgo($this->creation_dtime, 'without')).
210            '</a></td><td>';
211        $stag = new IDF_Template_ShowUser();
212        $user = $stag->start($this->get_author(), $request, $this->origauthor, false);
213        $tag = new IDF_Template_IssueComment();
214        $out .= $tag->start($this->summary, $request, false);
215        if (0 && $this->fullmessage) {
216            $out .= '<br /><br />'.$tag->start($this->fullmessage, $request, false);
217        }
218        $out .= '</td>
219</tr>
220<tr class="extra">
221<td colspan="2">
222<div class="helptext right">'.sprintf(__('Commit&nbsp;%s, by %s'), '<a href="'.$url.'" class="mono">'.$this->scm_id.'</a>', $user).'</div></td></tr>';
223        return Pluf_Template::markSafe($out);
224    }
225
226    /**
227     * Returns the feed fragment for the commit.
228     *
229     * @param Pluf_HTTP_Request
230     * @return Pluf_Template_SafeString
231     */
232    public function feedFragment($request)
233    {
234        $url = Pluf::f('url_base')
235            .Pluf_HTTP_URL_urlForView('IDF_Views_Source::commit',
236                                      array($request->project->shortname,
237                                            $this->scm_id));
238        $date = Pluf_Date::gmDateToGmString($this->creation_dtime);
239        $author = ($this->get_author()) ?
240            $this->get_author() : $this->origauthor;
241        $cproject = $this->get_project();
242        $context = new Pluf_Template_Context_Request(
243                       $request,
244                       array(
245                             'c' => $this,
246                             'cproject' => $cproject,
247                             'url' => $url,
248                             'date' => $date,
249                             'author' => $author,
250                             )
251                                             );
252        $tmpl = new Pluf_Template('idf/source/feedfragment.xml');
253        return $tmpl->render($context);
254    }
255
256    /**
257     * Notification of change of the object.
258     *
259     * @param IDF_Conf Current configuration
260     * @param bool Creation (true)
261     */
262    public function notify($conf, $create=true)
263    {
264        if ('' == $conf->getVal('source_notification_email', '')) {
265            return;
266        }
267        $current_locale = Pluf_Translation::getLocale();
268        $langs = Pluf::f('languages', array('en'));
269        Pluf_Translation::loadSetLocale($langs[0]);
270
271        $context = new Pluf_Template_Context(
272                       array(
273                             'c' => $this,
274                             'project' => $this->get_project(),
275                             'url_base' => Pluf::f('url_base'),
276                             )
277                                             );
278        $tmpl = new Pluf_Template('idf/source/commit-created-email.txt');
279        $text_email = $tmpl->render($context);
280        $email = new Pluf_Mail(Pluf::f('from_email'),
281                               $conf->getVal('source_notification_email'),
282                               sprintf(__('New Commit %s - %s (%s)'),
283                                       $this->scm_id, $this->summary,
284                                       $this->get_project()->shortname));
285        $email->addTextMessage($text_email);
286        $email->sendMail();
287        Pluf_Translation::loadSetLocale($current_locale);
288    }
289}
290

Archive Download this file

Branches:
dev
master
newdiff
svn