Merged master back into the code review work.
This commit is contained in:
		
							
								
								
									
										12
									
								
								AUTHORS
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								AUTHORS
									
									
									
									
									
								
							| @@ -9,4 +9,14 @@ Much appreciated contributors: | |||||||
|     Baptiste Michaud <bactisme@gmail.com> - Subversion synchronization |     Baptiste Michaud <bactisme@gmail.com> - Subversion synchronization | ||||||
|     Julien Issler  |     Julien Issler  | ||||||
|     Manuel Eidenberger <eidenberger@gmail.com> |     Manuel Eidenberger <eidenberger@gmail.com> | ||||||
|     Patrick Georgi |     Ciaran Gultnieks | ||||||
|  |     Mehdi Kabab | ||||||
|  |     Sindre R. Myren | ||||||
|  |     Patrick Georgi <patrick.georgi@coresystems.de> | ||||||
|  |     Adrien Bustany | ||||||
|  |     Charles Melbye | ||||||
|  |     Baptiste Durand-Bret | ||||||
|  |  | ||||||
|  | And all the nice users who spent time reporting issues and promoting | ||||||
|  | the project. The project could not live without them. | ||||||
|  |  | ||||||
|   | |||||||
| @@ -70,6 +70,13 @@ folder. Here is a configuration example: | |||||||
|     $cfg['idf_plugin_syncgit_path_gitserve'] = '/home/www/indefero/scripts/gitserve.py'; # yes .py |     $cfg['idf_plugin_syncgit_path_gitserve'] = '/home/www/indefero/scripts/gitserve.py'; # yes .py | ||||||
|     $cfg['idf_plugin_syncgit_path_authorized_keys'] = '/home/git/.ssh/authorized_keys'; |     $cfg['idf_plugin_syncgit_path_authorized_keys'] = '/home/git/.ssh/authorized_keys'; | ||||||
|     $cfg['idf_plugin_syncgit_sync_file'] = '/tmp/SYNC-GIT'; |     $cfg['idf_plugin_syncgit_sync_file'] = '/tmp/SYNC-GIT'; | ||||||
|  |     # Remove the git repositories which do not have a corresponding project | ||||||
|  |     # This is run at cron time | ||||||
|  |     $cfg['idf_plugin_syncgit_remove_orphans'] = false; | ||||||
|  |     # git account home dir | ||||||
|  |     $cfg['idf_plugin_syncgit_git_home_dir'] = '/home/git';  | ||||||
|  |     # where are going to be the git repositories | ||||||
|  |     $cfg['idf_plugin_sncgit_base_repositories'] = '/home/git/repositories';  | ||||||
|  |  | ||||||
| When someone will change his SSH key or add a new one, the | When someone will change his SSH key or add a new one, the | ||||||
| `/tmp/SYNC-GIT` file will be created. The cron job | `/tmp/SYNC-GIT` file will be created. The cron job | ||||||
|   | |||||||
| @@ -66,6 +66,8 @@ need to put the following in your configuration file: | |||||||
|     $cfg['idf_plugin_syncsvn_authz_file'] = '/home/svn/dav_svn.authz'; |     $cfg['idf_plugin_syncsvn_authz_file'] = '/home/svn/dav_svn.authz'; | ||||||
|     $cfg['idf_plugin_syncsvn_passwd_file'] = '/home/svn/dav_svn.passwd'; |     $cfg['idf_plugin_syncsvn_passwd_file'] = '/home/svn/dav_svn.passwd'; | ||||||
|     $cfg['idf_plugin_syncsvn_svn_path'] = '/home/svn/repositories';  |     $cfg['idf_plugin_syncsvn_svn_path'] = '/home/svn/repositories';  | ||||||
|  |     // Delete the corresponding repository when deleting the project | ||||||
|  |     $cfg['idf_plugin_syncsvn_remove_orphans'] = false; | ||||||
|  |  | ||||||
| You can have more control over the permissions given to the owners, | You can have more control over the permissions given to the owners, | ||||||
| members, extra authorized users and anonymous users if you want with | members, extra authorized users and anonymous users if you want with | ||||||
|   | |||||||
| @@ -37,5 +37,5 @@ set_include_path(get_include_path() | |||||||
| require 'Pluf.php'; | require 'Pluf.php'; | ||||||
| Pluf::start(dirname(__FILE__).'/../src/IDF/conf/idf.php'); | Pluf::start(dirname(__FILE__).'/../src/IDF/conf/idf.php'); | ||||||
| Pluf_Dispatcher::loadControllers(Pluf::f('idf_views')); | Pluf_Dispatcher::loadControllers(Pluf::f('idf_views')); | ||||||
| IDF_Plugin_SyncGit_Serve::main($argv, $_ENV); | IDF_Plugin_SyncGit_Serve::main($argv, array_merge($_SERVER, $_ENV)); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -144,12 +144,14 @@ class IDF_Commit extends Pluf_Model | |||||||
|         if ($r->count() > 0) { |         if ($r->count() > 0) { | ||||||
|             return $r[0]; |             return $r[0]; | ||||||
|         } |         } | ||||||
|  |         if (!isset($change->full_message)) { | ||||||
|  |             $change->full_message = ''; | ||||||
|  |         } | ||||||
|         $scm = IDF_Scm::get($project); |         $scm = IDF_Scm::get($project); | ||||||
|         $commit = new IDF_Commit(); |         $commit = new IDF_Commit(); | ||||||
|         $commit->project = $project; |         $commit->project = $project; | ||||||
|         $commit->scm_id = $change->commit; |         $commit->scm_id = $change->commit; | ||||||
|         $commit->summary = $change->title; |         list($commit->summary, $commit->fullmessage) = self::toUTF8(array($change->title, $change->full_message)); | ||||||
|         $commit->fullmessage = $change->full_message; |  | ||||||
|         $commit->author = $scm->findAuthor($change->author); |         $commit->author = $scm->findAuthor($change->author); | ||||||
|         $commit->origauthor = $change->author; |         $commit->origauthor = $change->author; | ||||||
|         $commit->creation_dtime = $change->date; |         $commit->creation_dtime = $change->date; | ||||||
| @@ -176,6 +178,39 @@ class IDF_Commit extends Pluf_Model | |||||||
|         return $commit; |         return $commit; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Convert encoding to UTF8. | ||||||
|  |      * | ||||||
|  |      * If an array is given, the encoding is detected only on the | ||||||
|  |      * first value and then used to convert all the strings. | ||||||
|  |      * | ||||||
|  |      * @param mixed String or array of string to be converted | ||||||
|  |      * @return mixed String or array of string | ||||||
|  |      */ | ||||||
|  |     public static function toUTF8($text) | ||||||
|  |     { | ||||||
|  |         $enc = 'ASCII, UTF-8, ISO-8859-1, JIS, EUC-JP, SJIS'; | ||||||
|  |         $ref = $text; | ||||||
|  |         if (is_array($text)) { | ||||||
|  |             $ref = $text[0]; | ||||||
|  |         } | ||||||
|  |         if (Pluf_Text_UTF8::check($ref)) { | ||||||
|  |             return $text; | ||||||
|  |         } | ||||||
|  |         $encoding = mb_detect_encoding($ref, $enc, true); | ||||||
|  |         if ($encoding == false) { | ||||||
|  |             $encoding = Pluf_Text_UTF8::detect_cyr_charset($ref); | ||||||
|  |         } | ||||||
|  |         if (is_array($text)) { | ||||||
|  |             foreach ($text as $t) { | ||||||
|  |                 $res[] = mb_convert_encoding($t, 'UTF-8', $encoding); | ||||||
|  |             } | ||||||
|  |             return $res; | ||||||
|  |         } else { | ||||||
|  |             return mb_convert_encoding($text, 'UTF-8', $encoding); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Returns the timeline fragment for the commit. |      * Returns the timeline fragment for the commit. | ||||||
|      * |      * | ||||||
| @@ -202,7 +237,7 @@ class IDF_Commit extends Pluf_Model | |||||||
| </tr> | </tr> | ||||||
| <tr class="extra"> | <tr class="extra"> | ||||||
| <td colspan="2"> | <td colspan="2"> | ||||||
| <div class="helptext right">'.__('Commit').' <a href="'.$url.'" class="mono">'.$this->scm_id.'</a>, '.__('by').' '.$user.'</div></td></tr>';  | <div class="helptext right">'.sprintf(__('Commit %s, by %s'), '<a href="'.$url.'" class="mono">'.$this->scm_id.'</a>', $user).'</div></td></tr>';  | ||||||
|         return Pluf_Template::markSafe($out); |         return Pluf_Template::markSafe($out); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -172,6 +172,7 @@ class IDF_Diff | |||||||
|  |  | ||||||
|     public static function padLine($line) |     public static function padLine($line) | ||||||
|     { |     { | ||||||
|  |         $line = str_replace("\t", '    ', $line); | ||||||
|         $n = strlen($line); |         $n = strlen($line); | ||||||
|         for ($i=0;$i<$n;$i++) { |         for ($i=0;$i<$n;$i++) { | ||||||
|             if (substr($line, $i, 1) != ' ') { |             if (substr($line, $i, 1) != ' ') { | ||||||
|   | |||||||
| @@ -60,7 +60,7 @@ class IDF_Form_Admin_ProjectCreate extends Pluf_Form | |||||||
|                                       array('required' => true, |                                       array('required' => true, | ||||||
|                                             'label' => __('Shortname'), |                                             'label' => __('Shortname'), | ||||||
|                                             'initial' => '', |                                             'initial' => '', | ||||||
|                                             'help_text' => __('It must be unique for each project and composed only of letters and digits.'), |                                             'help_text' => __('It must be unique for each project and composed only of letters, digits and dash (-) like "my-project".'), | ||||||
|                                             )); |                                             )); | ||||||
|  |  | ||||||
|         $this->fields['scm'] = new Pluf_Form_Field_Varchar( |         $this->fields['scm'] = new Pluf_Form_Field_Varchar( | ||||||
| @@ -133,6 +133,16 @@ class IDF_Form_Admin_ProjectCreate extends Pluf_Form | |||||||
|                           'IDF_Form_Admin_ProjectCreate', $params); |                           'IDF_Form_Admin_ProjectCreate', $params); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     public function clean_owners() | ||||||
|  |     { | ||||||
|  |         return IDF_Form_MembersConf::checkBadLogins($this->cleaned_data['owners']); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public function clean_members() | ||||||
|  |     { | ||||||
|  |         return IDF_Form_MembersConf::checkBadLogins($this->cleaned_data['members']); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     public function clean_svn_remote_url() |     public function clean_svn_remote_url() | ||||||
|     { |     { | ||||||
|         $this->cleaned_data['svn_remote_url'] = (!empty($this->cleaned_data['svn_remote_url'])) ? $this->cleaned_data['svn_remote_url'] : ''; |         $this->cleaned_data['svn_remote_url'] = (!empty($this->cleaned_data['svn_remote_url'])) ? $this->cleaned_data['svn_remote_url'] : ''; | ||||||
| @@ -150,7 +160,7 @@ class IDF_Form_Admin_ProjectCreate extends Pluf_Form | |||||||
|     { |     { | ||||||
|         $shortname = $this->cleaned_data['shortname']; |         $shortname = $this->cleaned_data['shortname']; | ||||||
|         if (preg_match('/[^\-A-Za-z0-9]/', $shortname)) { |         if (preg_match('/[^\-A-Za-z0-9]/', $shortname)) { | ||||||
|             throw new Pluf_Form_Invalid(__('This shortname contains illegal characters, please use only letters and digits.')); |             throw new Pluf_Form_Invalid(__('This shortname contains illegal characters, please use only letters, digits and dash (-).')); | ||||||
|         } |         } | ||||||
|         if (mb_substr($shortname, 0, 1) == '-') { |         if (mb_substr($shortname, 0, 1) == '-') { | ||||||
|             throw new Pluf_Form_Invalid(__('The shortname cannot start with the dash (-) character.')); |             throw new Pluf_Form_Invalid(__('The shortname cannot start with the dash (-) character.')); | ||||||
|   | |||||||
| @@ -61,6 +61,16 @@ class IDF_Form_Admin_ProjectUpdate extends Pluf_Form | |||||||
|                                             )); |                                             )); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     public function clean_owners() | ||||||
|  |     { | ||||||
|  |         return IDF_Form_MembersConf::checkBadLogins($this->cleaned_data['owners']); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public function clean_members() | ||||||
|  |     { | ||||||
|  |         return IDF_Form_MembersConf::checkBadLogins($this->cleaned_data['members']); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     public function save($commit=true) |     public function save($commit=true) | ||||||
|     { |     { | ||||||
|         if (!$this->isValid()) { |         if (!$this->isValid()) { | ||||||
|   | |||||||
| @@ -179,8 +179,11 @@ class IDF_Form_Admin_UserUpdate  extends Pluf_Form | |||||||
|     function clean_first_name() |     function clean_first_name() | ||||||
|     { |     { | ||||||
|         $first_name = trim($this->cleaned_data['first_name']); |         $first_name = trim($this->cleaned_data['first_name']); | ||||||
|  |         if ($first_name == '---') { | ||||||
|  |             throw new Pluf_Form_Invalid(__('--- is not a valid first name.')); | ||||||
|  |         } | ||||||
|         if ($first_name == mb_strtoupper($first_name)) { |         if ($first_name == mb_strtoupper($first_name)) { | ||||||
|             return mb_convert_case(mb_strtolower($first_name),  |             $first_name = mb_convert_case(mb_strtolower($first_name),  | ||||||
|                                           MB_CASE_TITLE, 'UTF-8'); |                                           MB_CASE_TITLE, 'UTF-8'); | ||||||
|         } |         } | ||||||
|         return $first_name; |         return $first_name; | ||||||
|   | |||||||
| @@ -67,6 +67,45 @@ class IDF_Form_MembersConf extends Pluf_Form | |||||||
|         $this->project->membershipsUpdated(); |         $this->project->membershipsUpdated(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     public function clean_owners() | ||||||
|  |     { | ||||||
|  |         return self::checkBadLogins($this->cleaned_data['owners']); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public function clean_members() | ||||||
|  |     { | ||||||
|  |         return self::checkBadLogins($this->cleaned_data['members']); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * From the input, find the bad logins. | ||||||
|  |      * | ||||||
|  |      * @throws Pluf_Form_Invalid exception when bad logins are found | ||||||
|  |      * @param string Comma, new line delimited list of logins | ||||||
|  |      * @return string Comma, new line delimited list of logins | ||||||
|  |      */ | ||||||
|  |     public static function checkBadLogins($logins) | ||||||
|  |     { | ||||||
|  |         $bad = array(); | ||||||
|  |         foreach (preg_split("/\015\012|\015|\012|\,/", $logins, -1, PREG_SPLIT_NO_EMPTY) as $login) { | ||||||
|  |             $sql = new Pluf_SQL('login=%s', array(trim($login))); | ||||||
|  |             try { | ||||||
|  |                 $user = Pluf::factory('Pluf_User')->getOne(array('filter'=>$sql->gen())); | ||||||
|  |                 if (null == $user) { | ||||||
|  |                     $bad[] = $login; | ||||||
|  |                 } | ||||||
|  |             } catch (Exception $e) { | ||||||
|  |                 $bad[] = $login; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         $n = count($bad); | ||||||
|  |         if ($n) { | ||||||
|  |             $badlogins = Pluf_esc(implode(', ', $bad)); | ||||||
|  |             throw new Pluf_Form_Invalid(sprintf(_n('The following login is invalid: %s.', 'The following login are invalids: %s.', $n), $badlogins)); | ||||||
|  |         } | ||||||
|  |         return $logins; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * The update of the memberships is done in different places. This |      * The update of the memberships is done in different places. This | ||||||
|      * avoids duplicating code. |      * avoids duplicating code. | ||||||
|   | |||||||
| @@ -95,6 +95,10 @@ class IDF_Form_PasswordInputKey extends Pluf_Form | |||||||
|             return false; |             return false; | ||||||
|         } |         } | ||||||
|         $cr = new Pluf_Crypt(md5(Pluf::f('secret_key'))); |         $cr = new Pluf_Crypt(md5(Pluf::f('secret_key'))); | ||||||
|         return split(':', $cr->decrypt($encrypted), 3); |         $f = split(':', $cr->decrypt($encrypted), 3); | ||||||
|  |         if (count($f) != 3) { | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  |         return $f; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -59,8 +59,10 @@ class IDF_Form_ReviewCreate extends Pluf_Form | |||||||
|                                                        'rows' => 7, |                                                        'rows' => 7, | ||||||
|                                                                     ), |                                                                     ), | ||||||
|                                             )); |                                             )); | ||||||
|  |         $sql = new Pluf_SQL('project=%s', array($this->project->id)); | ||||||
|         $commits = Pluf::factory('IDF_Commit')->getList(array('order' => 'creation_dtime DESC', |         $commits = Pluf::factory('IDF_Commit')->getList(array('order' => 'creation_dtime DESC', | ||||||
|                                                               'nb' => 10)); |                                                               'nb' => 10, | ||||||
|  |                                                               'filter' => $sql->gen())); | ||||||
|         $choices = array(); |         $choices = array(); | ||||||
|         foreach ($commits as $c) { |         foreach ($commits as $c) { | ||||||
|             $id = (strlen($c->scm_id) > 10) ? substr($c->scm_id, 0, 10) : $c->scm_id; |             $id = (strlen($c->scm_id) > 10) ? substr($c->scm_id, 0, 10) : $c->scm_id; | ||||||
|   | |||||||
| @@ -86,6 +86,11 @@ class IDF_Form_TabsConf extends Pluf_Form | |||||||
|                                             )); |                                             )); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     public function clean_authorized_users() | ||||||
|  |     { | ||||||
|  |         return IDF_Form_MembersConf::checkBadLogins($this->cleaned_data['authorized_users']); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     public function save($commit=true) |     public function save($commit=true) | ||||||
|     { |     { | ||||||
|         if (!$this->isValid()) { |         if (!$this->isValid()) { | ||||||
|   | |||||||
| @@ -46,6 +46,16 @@ class IDF_Form_UpdateUpload extends Pluf_Form | |||||||
|                                                        'size' => 67, |                                                        'size' => 67, | ||||||
|                                                                     ), |                                                                     ), | ||||||
|                                             )); |                                             )); | ||||||
|  |         $this->fields['changelog'] = new Pluf_Form_Field_Varchar( | ||||||
|  |                                       array('required' => false, | ||||||
|  |                                             'label' => __('Description'), | ||||||
|  |                                             'initial' => $this->upload->changelog, | ||||||
|  |                                             'widget' => 'Pluf_Form_Widget_TextareaInput', | ||||||
|  |                                             'widget_attrs' => array( | ||||||
|  |                                                        'cols' => 58, | ||||||
|  |                                                        'rows' => 13, | ||||||
|  |                                                                     ), | ||||||
|  |                                             )); | ||||||
|         $tags = $this->upload->get_tags_list(); |         $tags = $this->upload->get_tags_list(); | ||||||
|         for ($i=1;$i<7;$i++) { |         for ($i=1;$i<7;$i++) { | ||||||
|             $initial = ''; |             $initial = ''; | ||||||
| @@ -132,6 +142,7 @@ class IDF_Form_UpdateUpload extends Pluf_Form | |||||||
|         } |         } | ||||||
|         // Create the upload |         // Create the upload | ||||||
|         $this->upload->summary = trim($this->cleaned_data['summary']); |         $this->upload->summary = trim($this->cleaned_data['summary']); | ||||||
|  |         $this->upload->changelog = trim($this->cleaned_data['changelog']); | ||||||
|         $this->upload->modif_dtime = gmdate('Y-m-d H:i:s'); |         $this->upload->modif_dtime = gmdate('Y-m-d H:i:s'); | ||||||
|         $this->upload->update(); |         $this->upload->update(); | ||||||
|         $this->upload->batchAssoc('IDF_Tag', $tags); |         $this->upload->batchAssoc('IDF_Tag', $tags); | ||||||
|   | |||||||
| @@ -44,6 +44,16 @@ class IDF_Form_Upload extends Pluf_Form | |||||||
|                                                        'size' => 67, |                                                        'size' => 67, | ||||||
|                                                                     ), |                                                                     ), | ||||||
|                                             )); |                                             )); | ||||||
|  |         $this->fields['changelog'] = new Pluf_Form_Field_Varchar( | ||||||
|  |                                       array('required' => false, | ||||||
|  |                                             'label' => __('Description'), | ||||||
|  |                                             'initial' => '', | ||||||
|  |                                             'widget' => 'Pluf_Form_Widget_TextareaInput', | ||||||
|  |                                             'widget_attrs' => array( | ||||||
|  |                                                        'cols' => 58, | ||||||
|  |                                                        'rows' => 13, | ||||||
|  |                                                                     ), | ||||||
|  |                                             )); | ||||||
|         $this->fields['file'] = new Pluf_Form_Field_File( |         $this->fields['file'] = new Pluf_Form_Field_File( | ||||||
|                                       array('required' => true, |                                       array('required' => true, | ||||||
|                                             'label' => __('File'), |                                             'label' => __('File'), | ||||||
| @@ -155,6 +165,7 @@ class IDF_Form_Upload extends Pluf_Form | |||||||
|         $upload->project = $this->project; |         $upload->project = $this->project; | ||||||
|         $upload->submitter = $this->user; |         $upload->submitter = $this->user; | ||||||
|         $upload->summary = trim($this->cleaned_data['summary']); |         $upload->summary = trim($this->cleaned_data['summary']); | ||||||
|  |         $upload->changelog = trim($this->cleaned_data['changelog']); | ||||||
|         $upload->file = $this->cleaned_data['file']; |         $upload->file = $this->cleaned_data['file']; | ||||||
|         $upload->filesize = filesize(Pluf::f('upload_path').'/'.$this->project->shortname.'/files/'.$this->cleaned_data['file']); |         $upload->filesize = filesize(Pluf::f('upload_path').'/'.$this->project->shortname.'/files/'.$this->cleaned_data['file']); | ||||||
|         $upload->downloads = 0; |         $upload->downloads = 0; | ||||||
|   | |||||||
| @@ -193,7 +193,7 @@ class IDF_Issue extends Pluf_Model | |||||||
|         $ic = (in_array($this->status, $request->project->getTagIdsByStatus('closed'))) ? 'issue-c' : 'issue-o'; |         $ic = (in_array($this->status, $request->project->getTagIdsByStatus('closed'))) ? 'issue-c' : 'issue-o'; | ||||||
|         $out .= sprintf(__('<a href="%1$s" class="%2$s" title="View issue">Issue %3$d</a>, %4$s'), $url, $ic, $this->id, Pluf_esc($this->summary)).'</td>'; |         $out .= sprintf(__('<a href="%1$s" class="%2$s" title="View issue">Issue %3$d</a>, %4$s'), $url, $ic, $this->id, Pluf_esc($this->summary)).'</td>'; | ||||||
|         $out .= "\n".'<tr class="extra"><td colspan="2"> |         $out .= "\n".'<tr class="extra"><td colspan="2"> | ||||||
| <div class="helptext right">'.sprintf(__('Creation of <a href="%s" class="%s">issue %d</a>'), $url, $ic, $this->id).', '.__('by').' '.$user.'</div></td></tr>';  | <div class="helptext right">'.sprintf(__('Creation of <a href="%s" class="%s">issue %d</a>, by %s'), $url, $ic, $this->id, $user).'</div></td></tr>';  | ||||||
|         return Pluf_Template::markSafe($out); |         return Pluf_Template::markSafe($out); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -170,7 +170,7 @@ class IDF_IssueComment extends Pluf_Model | |||||||
|  |  | ||||||
|  |  | ||||||
|         $out .= "\n".'<tr class="extra"><td colspan="2"> |         $out .= "\n".'<tr class="extra"><td colspan="2"> | ||||||
| <div class="helptext right">'.sprintf(__('Comment on <a href="%s" class="%s">issue %d</a>'), $url, $ic, $issue->id).', '.__('by').' '.$user.'</div></td></tr>';  | <div class="helptext right">'.sprintf(__('Comment on <a href="%s" class="%s">issue %d</a>, by %s'), $url, $ic, $issue->id, $user).'</div></td></tr>';  | ||||||
|  |  | ||||||
|         return Pluf_Template::markSafe($out); |         return Pluf_Template::markSafe($out); | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -123,4 +123,9 @@ class IDF_IssueFile extends Pluf_Model | |||||||
|         } |         } | ||||||
|         $this->modif_dtime = gmdate('Y-m-d H:i:s'); |         $this->modif_dtime = gmdate('Y-m-d H:i:s'); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     function preDelete() | ||||||
|  |     { | ||||||
|  |         @unlink(Pluf::f('upload_issue_path').'/'.$this->attachment); | ||||||
|  |     } | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										52
									
								
								src/IDF/Migrations/11GitCache.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								src/IDF/Migrations/11GitCache.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,52 @@ | |||||||
|  | <?php | ||||||
|  | /* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ | ||||||
|  | /* | ||||||
|  | # ***** BEGIN LICENSE BLOCK ***** | ||||||
|  | # This file is part of InDefero, an open source project management application. | ||||||
|  | # Copyright (C) 2008 Céondo Ltd and contributors. | ||||||
|  | # | ||||||
|  | # InDefero is free software; you can redistribute it and/or modify | ||||||
|  | # it under the terms of the GNU General Public License as published by | ||||||
|  | # the Free Software Foundation; either version 2 of the License, or | ||||||
|  | # (at your option) any later version. | ||||||
|  | # | ||||||
|  | # InDefero is distributed in the hope that it will be useful, | ||||||
|  | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  | # GNU General Public License for more details. | ||||||
|  | # | ||||||
|  | # You should have received a copy of the GNU General Public License | ||||||
|  | # along with this program; if not, write to the Free Software | ||||||
|  | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA | ||||||
|  | # | ||||||
|  | # ***** END LICENSE BLOCK ***** */ | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Add the DB based Git cache. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | function IDF_Migrations_11GitCache_up($params=null) | ||||||
|  | { | ||||||
|  |     $models = array( | ||||||
|  |                     'IDF_Scm_Cache_Git', | ||||||
|  |                     ); | ||||||
|  |     $db = Pluf::db(); | ||||||
|  |     $schema = new Pluf_DB_Schema($db); | ||||||
|  |     foreach ($models as $model) { | ||||||
|  |         $schema->model = new $model(); | ||||||
|  |         $schema->createTables(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function IDF_Migrations_11GitCache_down($params=null) | ||||||
|  | { | ||||||
|  |     $models = array( | ||||||
|  |                     'IDF_Scm_Cache_Git', | ||||||
|  |                     ); | ||||||
|  |     $db = Pluf::db(); | ||||||
|  |     $schema = new Pluf_DB_Schema($db); | ||||||
|  |     foreach ($models as $model) { | ||||||
|  |         $schema->model = new $model(); | ||||||
|  |         $schema->dropTables(); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										55
									
								
								src/IDF/Migrations/12DownloadDesc.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								src/IDF/Migrations/12DownloadDesc.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,55 @@ | |||||||
|  | <?php | ||||||
|  | /* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ | ||||||
|  | /* | ||||||
|  | # ***** BEGIN LICENSE BLOCK ***** | ||||||
|  | # This file is part of InDefero, an open source project management application. | ||||||
|  | # Copyright (C) 2008 Céondo Ltd and contributors. | ||||||
|  | # | ||||||
|  | # InDefero is free software; you can redistribute it and/or modify | ||||||
|  | # it under the terms of the GNU General Public License as published by | ||||||
|  | # the Free Software Foundation; either version 2 of the License, or | ||||||
|  | # (at your option) any later version. | ||||||
|  | # | ||||||
|  | # InDefero is distributed in the hope that it will be useful, | ||||||
|  | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  | # GNU General Public License for more details. | ||||||
|  | # | ||||||
|  | # You should have received a copy of the GNU General Public License | ||||||
|  | # along with this program; if not, write to the Free Software | ||||||
|  | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA | ||||||
|  | # | ||||||
|  | # ***** END LICENSE BLOCK ***** */ | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Add the private column for the project. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | function IDF_Migrations_12DownloadDesc_up($params=null) | ||||||
|  | { | ||||||
|  |     $table = Pluf::factory('IDF_Upload')->getSqlTable(); | ||||||
|  |     $sql = array(); | ||||||
|  |     $sql['PostgreSQL'] = 'ALTER TABLE '.$table.' ADD COLUMN "changelog" TEXT DEFAULT \'\''; | ||||||
|  |     $sql['MySQL'] = 'ALTER TABLE '.$table.' ADD COLUMN `changelog` LONGTEXT DEFAULT \'\''; | ||||||
|  |     $db = Pluf::db(); | ||||||
|  |     $engine = Pluf::f('db_engine'); | ||||||
|  |     if (!isset($sql[$engine])) { | ||||||
|  |         throw new Exception('SQLite complex migration not supported.'); | ||||||
|  |     } | ||||||
|  |     $db->execute($sql[$engine]); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function IDF_Migrations_12DownloadDesc_down($params=null) | ||||||
|  | { | ||||||
|  |     $table = Pluf::factory('IDF_Upload')->getSqlTable(); | ||||||
|  |     $sql = array(); | ||||||
|  |     $sql['PostgreSQL'] = 'ALTER TABLE '.$table.' DROP COLUMN "changelog"'; | ||||||
|  |     $sql['MySQL'] = 'ALTER TABLE '.$table.' DROP COLUMN `changelog`'; | ||||||
|  |     $db = Pluf::db(); | ||||||
|  |     $engine = Pluf::f('db_engine'); | ||||||
|  |     if (!isset($sql[$engine])) { | ||||||
|  |         throw new Exception('SQLite complex migration not supported.'); | ||||||
|  |     } | ||||||
|  |     $db->execute($sql[$engine]); | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -46,6 +46,7 @@ function IDF_Migrations_Install_setup($params=null) | |||||||
|                     'IDF_Review_Patch', |                     'IDF_Review_Patch', | ||||||
|                     'IDF_Review_FileComment', |                     'IDF_Review_FileComment', | ||||||
|                     'IDF_Key', |                     'IDF_Key', | ||||||
|  |                     'IDF_Scm_Cache_Git', | ||||||
|                     ); |                     ); | ||||||
|     $db = Pluf::db(); |     $db = Pluf::db(); | ||||||
|     $schema = new Pluf_DB_Schema($db); |     $schema = new Pluf_DB_Schema($db); | ||||||
| @@ -83,6 +84,7 @@ function IDF_Migrations_Install_teardown($params=null) | |||||||
|     $perm = Pluf_Permission::getFromString('IDF.project-authorized-user'); |     $perm = Pluf_Permission::getFromString('IDF.project-authorized-user'); | ||||||
|     if ($perm) $perm->delete(); |     if ($perm) $perm->delete(); | ||||||
|     $models = array( |     $models = array( | ||||||
|  |                     'IDF_Scm_Cache_Git', | ||||||
|                     'IDF_Key', |                     'IDF_Key', | ||||||
|                     'IDF_Review_FileComment', |                     'IDF_Review_FileComment', | ||||||
|                     'IDF_Review_Patch', |                     'IDF_Review_Patch', | ||||||
|   | |||||||
| @@ -40,7 +40,7 @@ class IDF_Plugin_SyncGit_Cron | |||||||
|         $cmd = Pluf::f('idf_plugin_syncgit_path_gitserve', '/dev/null'); |         $cmd = Pluf::f('idf_plugin_syncgit_path_gitserve', '/dev/null'); | ||||||
|         $authorized_keys = Pluf::f('idf_plugin_syncgit_path_authorized_keys', false); |         $authorized_keys = Pluf::f('idf_plugin_syncgit_path_authorized_keys', false); | ||||||
|         if (false == $authorized_keys) { |         if (false == $authorized_keys) { | ||||||
|             throw new Pluf_Exception_SettingError('Setting git_path_authorized_keys not set.'); |             throw new Pluf_Exception_SettingError('Setting idf_plugin_syncgit_path_authorized_keys not set.'); | ||||||
|         } |         } | ||||||
|         if (!is_writable($authorized_keys)) { |         if (!is_writable($authorized_keys)) { | ||||||
|             throw new Exception('Cannot create file: '.$authorized_keys); |             throw new Exception('Cannot create file: '.$authorized_keys); | ||||||
| @@ -69,6 +69,44 @@ class IDF_Plugin_SyncGit_Cron | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Remove orphan repositories. | ||||||
|  |      */ | ||||||
|  |     public static function removeOrphanRepositories() | ||||||
|  |     { | ||||||
|  |         $path = Pluf::f('idf_plugin_syncgit_base_repositories', '/home/git/repositories'); | ||||||
|  |         if (!is_dir($path) || is_link($path)) { | ||||||
|  |             throw new Pluf_Exception_SettingError(sprintf( | ||||||
|  |                 'Directory %s does not exist! Setting "idf_plugin_syncgit_base_repositories not set.', | ||||||
|  |                 $path)); | ||||||
|  |         } | ||||||
|  |         if (!is_writable($path)) { | ||||||
|  |             throw new Exception(sprintf('Repository %s is not writable.', $path)); | ||||||
|  |         } | ||||||
|  |         $projects = array(); | ||||||
|  |         foreach (Pluf::factory('IDF_Project')->getList() as $project) { | ||||||
|  |             $projects[] = $project->shortname; | ||||||
|  |         } | ||||||
|  |         unset($project); | ||||||
|  |         $it = new DirectoryIterator($path); | ||||||
|  |         $orphans = array(); | ||||||
|  |         while ($it->valid()) { | ||||||
|  |             if (!$it->isDot() && $it->isDir() && !in_array(basename($it->getFileName(), '.git'), $projects)) { | ||||||
|  |                 $orphans[] = $it->getPathName(); | ||||||
|  |             } | ||||||
|  |             $it->next(); | ||||||
|  |         } | ||||||
|  |         if (count($orphans)) { | ||||||
|  |             $cmd = Pluf::f('idf_exec_cmd_prefix', '').'rm -rf '.implode(' ', $orphans); | ||||||
|  |             exec($cmd); | ||||||
|  |             while (list(, $project) = each($orphans)) { | ||||||
|  |                 if (is_dir($project)) { | ||||||
|  |                     throw new Exception(sprintf('Cannot remove %s directory.', $project)); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Check if a sync is needed. |      * Check if a sync is needed. | ||||||
|      * |      * | ||||||
| @@ -79,6 +117,9 @@ class IDF_Plugin_SyncGit_Cron | |||||||
|             @unlink(Pluf::f('idf_plugin_syncgit_sync_file')); |             @unlink(Pluf::f('idf_plugin_syncgit_sync_file')); | ||||||
|             self::sync(); |             self::sync(); | ||||||
|             self::markExport(); |             self::markExport(); | ||||||
|  |             if (Pluf::f('idf_plugin_syncgit_remove_orphans', false)) { | ||||||
|  |                 self::removeOrphanRepositories(); | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -52,6 +52,9 @@ class IDF_Plugin_SyncSvn | |||||||
|         case 'Pluf_User::passwordUpdated': |         case 'Pluf_User::passwordUpdated': | ||||||
|             $plug->processSyncPasswd($params['user']); |             $plug->processSyncPasswd($params['user']); | ||||||
|             break; |             break; | ||||||
|  |         case 'IDF_Project::preDelete': | ||||||
|  |             $plug->processSvnDelete($params['project']); | ||||||
|  |             break; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -84,6 +87,31 @@ class IDF_Plugin_SyncSvn | |||||||
|         return ($return == 0); |         return ($return == 0); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Remove the project from the drive and update the access rights. | ||||||
|  |      * | ||||||
|  |      * @param IDF_Project  | ||||||
|  |      * @return bool Success | ||||||
|  |      */ | ||||||
|  |     function processSvnDelete($project) | ||||||
|  |     { | ||||||
|  |         if (!Pluf::f('idf_plugin_syncsvn_remove_orphans', false)) { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |         if ($project->getConf()->getVal('scm') != 'svn') { | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  |         $this->SyncAccess($project); // exclude $project | ||||||
|  |         $shortname = $project->shortname; | ||||||
|  |         if (false===($svn_path=Pluf::f('idf_plugin_syncsvn_svn_path',false))) { | ||||||
|  |             throw new Pluf_Exception_SettingError("'idf_plugin_syncsvn_svn_path' must be defined in your configuration file."); | ||||||
|  |         } | ||||||
|  |         if (file_exists($svn_path.'/'.$shortname)) { | ||||||
|  |             $cmd = Pluf::f('idf_exec_cmd_prefix', '').'rm -rf '.$svn_path.'/'.$shortname; | ||||||
|  |             exec($cmd); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |      | ||||||
|     /** |     /** | ||||||
|      * Synchronise an user's password. |      * Synchronise an user's password. | ||||||
|      * |      * | ||||||
| @@ -156,8 +184,10 @@ class IDF_Plugin_SyncSvn | |||||||
|      * We rebuild the complete file each time. This is just to be sure |      * We rebuild the complete file each time. This is just to be sure | ||||||
|      * not to bork the rights when trying to just edit part of the |      * not to bork the rights when trying to just edit part of the | ||||||
|      * file. |      * file. | ||||||
|  |      * | ||||||
|  |      * @param IDF_Project Possibly exclude a project (null) | ||||||
|      */ |      */ | ||||||
|     function SyncAccess() |     function SyncAccess($exclude=null) | ||||||
|     { |     { | ||||||
|         $authz_file = Pluf::f('idf_plugin_syncsvn_authz_file'); |         $authz_file = Pluf::f('idf_plugin_syncsvn_authz_file'); | ||||||
|         $access_owners = Pluf::f('idf_plugin_syncsvn_access_owners', 'rw'); |         $access_owners = Pluf::f('idf_plugin_syncsvn_access_owners', 'rw'); | ||||||
| @@ -170,6 +200,9 @@ class IDF_Plugin_SyncSvn | |||||||
|         } |         } | ||||||
|         $fcontent = ''; |         $fcontent = ''; | ||||||
|         foreach (Pluf::factory('IDF_Project')->getList() as $project) { |         foreach (Pluf::factory('IDF_Project')->getList() as $project) { | ||||||
|  |             if ($exclude and $exclude->id == $project->id) { | ||||||
|  |                 continue; | ||||||
|  |             } | ||||||
|             $conf = new IDF_Conf(); |             $conf = new IDF_Conf(); | ||||||
|             $conf->setProject($project); |             $conf->setProject($project); | ||||||
|             if ($conf->getVal('scm') != 'svn' or  |             if ($conf->getVal('scm') != 'svn' or  | ||||||
|   | |||||||
| @@ -349,16 +349,54 @@ class IDF_Project extends Pluf_Model | |||||||
|         return new Pluf_Template_ContextVars($tags); |         return new Pluf_Template_ContextVars($tags); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Get the repository size. | ||||||
|  |      * | ||||||
|  |      * @param bool Force to skip the cache (false) | ||||||
|  |      * @return int Size in byte or -1 if not available | ||||||
|  |      */ | ||||||
|  |     public function getRepositorySize($force=false) | ||||||
|  |     { | ||||||
|  |         $last_eval = $this->getConf()->getVal('repository_size_check_date', 0); | ||||||
|  |         if (!$force and $last_eval > time()-86400) { | ||||||
|  |             return $this->getConf()->getVal('repository_size', -1); | ||||||
|  |         } | ||||||
|  |         $scm = IDF_Scm::get($this); | ||||||
|  |         $this->getConf()->setVal('repository_size', $scm->getRepositorySize()); | ||||||
|  |         $this->getConf()->setVal('repository_size_check_date', time()); | ||||||
|  |         return $this->getConf()->getVal('repository_size', -1); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Get the access url to the repository. | ||||||
|  |      * | ||||||
|  |      * This will return the right url based on the user. | ||||||
|  |      * | ||||||
|  |      * @param Pluf_User The user (null) | ||||||
|  |      */ | ||||||
|  |     public function getSourceAccessUrl($user=null) | ||||||
|  |     { | ||||||
|  |         $right = $this->getConf()->getVal('source_access_rights', 'all'); | ||||||
|  |         if (($user == null or $user->isAnonymous())  | ||||||
|  |             and  $right == 'all' and !$this->private) { | ||||||
|  |             return $this->getRemoteAccessUrl(); | ||||||
|  |         } | ||||||
|  |         return $this->getWriteRemoteAccessUrl($user); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Get the remote access url to the repository. |      * Get the remote access url to the repository. | ||||||
|      * |      * | ||||||
|  |      * This will always return the anonymous access url. | ||||||
|      */ |      */ | ||||||
|     public function getRemoteAccessUrl() |     public function getRemoteAccessUrl() | ||||||
|     { |     { | ||||||
|         $conf = $this->getConf(); |         $conf = $this->getConf(); | ||||||
|         $scm = $conf->getVal('scm', 'git'); |         $scm = $conf->getVal('scm', 'git'); | ||||||
|         $scms = Pluf::f('allowed_scm'); |         $scms = Pluf::f('allowed_scm'); | ||||||
|         return call_user_func(array($scms[$scm], 'getRemoteAccessUrl'), |         Pluf::loadClass($scms[$scm]); | ||||||
|  |         return call_user_func(array($scms[$scm], 'getAnonymousAccessUrl'), | ||||||
|                               $this); |                               $this); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -369,13 +407,13 @@ class IDF_Project extends Pluf_Model | |||||||
|      * same as the one to read. For example, you do a checkout with |      * same as the one to read. For example, you do a checkout with | ||||||
|      * git-daemon and push with SSH. |      * git-daemon and push with SSH. | ||||||
|      */ |      */ | ||||||
|     public function getWriteRemoteAccessUrl() |     public function getWriteRemoteAccessUrl($user) | ||||||
|     { |     { | ||||||
|         $conf = $this->getConf(); |         $conf = $this->getConf(); | ||||||
|         $scm = $conf->getVal('scm', 'git'); |         $scm = $conf->getVal('scm', 'git'); | ||||||
|         $scms = Pluf::f('allowed_scm'); |         $scms = Pluf::f('allowed_scm'); | ||||||
|         return call_user_func(array($scms[$scm], 'getWriteRemoteAccessUrl'), |         return call_user_func(array($scms[$scm], 'getAuthAccessUrl'), | ||||||
|                               $this); |                               $this, $user); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
| @@ -541,4 +579,42 @@ class IDF_Project extends Pluf_Model | |||||||
|         Pluf_Signal::send('IDF_Project::created', |         Pluf_Signal::send('IDF_Project::created', | ||||||
|                           'IDF_Project', $params); |                           'IDF_Project', $params); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * The delete() call do not like circular references and the | ||||||
|  |      * IDF_Tag is creating some. We predelete to solve these issues. | ||||||
|  |      */ | ||||||
|  |     public function preDelete() | ||||||
|  |     { | ||||||
|  |         /** | ||||||
|  |          * [signal] | ||||||
|  |          * | ||||||
|  |          * IDF_Project::preDelete | ||||||
|  |          * | ||||||
|  |          * [sender] | ||||||
|  |          * | ||||||
|  |          * IDF_Project | ||||||
|  |          * | ||||||
|  |          * [description] | ||||||
|  |          * | ||||||
|  |          * This signal allows an application to perform special | ||||||
|  |          * operations at the deletion of a project. | ||||||
|  |          * | ||||||
|  |          * [parameters] | ||||||
|  |          * | ||||||
|  |          * array('project' => $project) | ||||||
|  |          * | ||||||
|  |          */ | ||||||
|  |         $params = array('project' => $this); | ||||||
|  |         Pluf_Signal::send('IDF_Project::preDelete', | ||||||
|  |                           'IDF_Project', $params); | ||||||
|  |         $what = array('IDF_Upload', 'IDF_Review', 'IDF_Issue', | ||||||
|  |                       'IDF_WikiPage', 'IDF_Commit', | ||||||
|  |                       ); | ||||||
|  |         foreach ($what as $m) { | ||||||
|  |             foreach (Pluf::factory($m)->getList(array('filter' => 'project='.(int)$this->id)) as $item) { | ||||||
|  |                 $item->delete(); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										320
									
								
								src/IDF/Scm.php
									
									
									
									
									
								
							
							
						
						
									
										320
									
								
								src/IDF/Scm.php
									
									
									
									
									
								
							| @@ -22,10 +22,55 @@ | |||||||
| # ***** END LICENSE BLOCK ***** */ | # ***** END LICENSE BLOCK ***** */ | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Manage differents SCM systems |  * Manage differents SCM systems. | ||||||
|  |  * | ||||||
|  |  * This is the base class with the different required methods to be | ||||||
|  |  * implemented by the SCMs. Each SCM backend need to extend this | ||||||
|  |  * class. We are not using an interface because this is not really | ||||||
|  |  * needed. | ||||||
|  |  * | ||||||
|  |  * The philosophy behind the interface is not to provide a wrapper | ||||||
|  |  * around the different SCMs but to provide methods to retrieve in the | ||||||
|  |  * most efficient way the informations to be displayed/needed in the | ||||||
|  |  * web interface. This means that each SCM can use the best options, | ||||||
|  |  * including caching to retrieve the informations. | ||||||
|  |  * | ||||||
|  |  * Note on caching: You must not cache ephemeral information like the | ||||||
|  |  * changelog, but you can cache the commit info (except with | ||||||
|  |  * subversion where you can change commit info...). It is ok to do | ||||||
|  |  * some caching for the lifetime of the IDF_Scm object, for example | ||||||
|  |  * not to retrieve several times the list of branches, etc. | ||||||
|  |  * | ||||||
|  |  * All the output of the methods must be serializable. This means that | ||||||
|  |  * if you are parsing XML you need to correctly cast the results as | ||||||
|  |  * string when needed. | ||||||
|  */ |  */ | ||||||
| class IDF_Scm | class IDF_Scm | ||||||
| { | { | ||||||
|  |     /** | ||||||
|  |      * String template for consistent error messages. | ||||||
|  |      */ | ||||||
|  |     public $error_tpl = 'Error command "%s" returns code %d and output: %s'; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Path to the repository. | ||||||
|  |      */ | ||||||
|  |     public $repo = ''; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Corresponding project object. | ||||||
|  |      */ | ||||||
|  |     public $project = null; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Cache storage.  | ||||||
|  |      * | ||||||
|  |      * It must only be used to store data for the lifetime of the | ||||||
|  |      * object. For example if you need to get the list of branches in | ||||||
|  |      * several functions, better to try to get from the cache first. | ||||||
|  |      */ | ||||||
|  |     protected $cache = array(); | ||||||
|  |  | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Returns an instance of the correct scm backend object. |      * Returns an instance of the correct scm backend object. | ||||||
| @@ -33,7 +78,7 @@ class IDF_Scm | |||||||
|      * @param IDF_Project |      * @param IDF_Project | ||||||
|      * @return Object |      * @return Object | ||||||
|      */ |      */ | ||||||
|     public static function get($project=null) |     public static function get($project) | ||||||
|     { |     { | ||||||
|         // Get scm type from project conf ; defaults to git |         // Get scm type from project conf ; defaults to git | ||||||
|         // We will need to cache the factory |         // We will need to cache the factory | ||||||
| @@ -43,46 +88,251 @@ class IDF_Scm | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Equivalent to exec but with caching. |      * Return the size of the repository in bytes. | ||||||
|      * |      * | ||||||
|      * @param string Command |      * @return int Size in byte, -1 if the size cannot be evaluated. | ||||||
|      * @param &array Output |  | ||||||
|      * @param &int Return value |  | ||||||
|      * @return string Last line of the output |  | ||||||
|      */ |      */ | ||||||
|     public static function exec($command, &$output=array(), &$return=0) |     public function getRepositorySize() | ||||||
|     { |     { | ||||||
|         $command = Pluf::f('idf_exec_cmd_prefix', '').$command; |         return -1; | ||||||
|         $key = md5($command); |  | ||||||
|         $cache = Pluf_Cache::factory(); |  | ||||||
|         if (null === ($res=$cache->get($key))) { |  | ||||||
|             $ll = exec($command, $output, $return); |  | ||||||
|             if ($return != 0 and Pluf::f('debug_scm', false)) { |  | ||||||
|                 throw new IDF_Scm_Exception(sprintf('Error when running command: "%s", return code: %d', $command, $return)); |  | ||||||
|             } |  | ||||||
|             $cache->set($key, array($ll, $return, $output)); |  | ||||||
|         } else { |  | ||||||
|             list($ll, $return, $output) = $res; |  | ||||||
|         } |  | ||||||
|         return $ll; |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Equivalent to shell_exec but with caching. |      * Returns the URL of the git daemon. | ||||||
|      * |      * | ||||||
|      * @param string Command |      * @param IDF_Project | ||||||
|      * @return string Output of the command |      * @return string URL | ||||||
|      */ |      */ | ||||||
|     public static function shell_exec($command) |     public static function getAnonymousAccessUrl($project) | ||||||
|     { |     { | ||||||
|         $command = Pluf::f('idf_exec_cmd_prefix', '').$command; |         throw new Pluf_Exception_NotImplemented(); | ||||||
|         $key = md5($command); |  | ||||||
|         $cache = Pluf_Cache::factory(); |  | ||||||
|         if (null === ($res=$cache->get($key))) { |  | ||||||
|             $res = shell_exec($command); |  | ||||||
|             $cache->set($key, $res); |  | ||||||
|     } |     } | ||||||
|         return $res; |  | ||||||
|  |     /** | ||||||
|  |      * Returns the URL for SSH access | ||||||
|  |      * | ||||||
|  |      * @param IDF_Project | ||||||
|  |      * @param Pluf_User | ||||||
|  |      * @return string URL | ||||||
|  |      */ | ||||||
|  |     public static function getAuthAccessUrl($project, $user) | ||||||
|  |     { | ||||||
|  |         throw new Pluf_Exception_NotImplemented(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Check if the backend is available for display. | ||||||
|  |      * | ||||||
|  |      * @return bool Available | ||||||
|  |      */ | ||||||
|  |     public function isAvailable() | ||||||
|  |     { | ||||||
|  |         throw new Pluf_Exception_NotImplemented(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Check if a revision or commit is valid. | ||||||
|  |      * | ||||||
|  |      * @param string Revision or commit | ||||||
|  |      * @return bool  | ||||||
|  |      */ | ||||||
|  |     public function isValidRevision($rev) | ||||||
|  |     { | ||||||
|  |         throw new Pluf_Exception_NotImplemented(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Returns in which branches a commit/path is. | ||||||
|  |      * | ||||||
|  |      * A commit can be in several branches and some of the SCMs are | ||||||
|  |      * managing branches using subfolders (like Subversion). | ||||||
|  |      * | ||||||
|  |      * This means that to know in which branch we are at the moment, | ||||||
|  |      * one needs to have both the path and the commit. | ||||||
|  |      * | ||||||
|  |      * @param string Commit | ||||||
|  |      * @param string Path | ||||||
|  |      * @return array Branches | ||||||
|  |      */ | ||||||
|  |     public function inBranches($commit, $path) | ||||||
|  |     { | ||||||
|  |         throw new Pluf_Exception_NotImplemented(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Returns the list of branches. | ||||||
|  |      * | ||||||
|  |      * The return value must be a branch indexed array with the | ||||||
|  |      * optional path to access the branch as value. For example with | ||||||
|  |      * git you would get (note that some people are using / in the | ||||||
|  |      * name of their git branches): | ||||||
|  |      * | ||||||
|  |      * <pre> | ||||||
|  |      * array('master' => '', | ||||||
|  |      *       'foo-branch' => '', | ||||||
|  |      *       'design/feature1' => '') | ||||||
|  |      * </pre> | ||||||
|  |      * | ||||||
|  |      * But with Subversion, as the branches are managed as subfolder | ||||||
|  |      * with a special folder for trunk, you would get something like: | ||||||
|  |      * | ||||||
|  |      * <pre> | ||||||
|  |      * array('trunk' => 'trunk', | ||||||
|  |      *       'foo-branch' => 'branches/foo-branch',) | ||||||
|  |      * </pre> | ||||||
|  |      * | ||||||
|  |      * @return array Branches  | ||||||
|  |      */ | ||||||
|  |     public function getBranches() | ||||||
|  |     { | ||||||
|  |         throw new Pluf_Exception_NotImplemented(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Returns the list of tags. | ||||||
|  |      * | ||||||
|  |      * The format is the same as for the branches. | ||||||
|  |      * | ||||||
|  |      * @see self::getBranches() | ||||||
|  |      * | ||||||
|  |      * @return array Tags | ||||||
|  |      */ | ||||||
|  |     public function getTags() | ||||||
|  |     { | ||||||
|  |         throw new Pluf_Exception_NotImplemented(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Returns the main branch. | ||||||
|  |      * | ||||||
|  |      * The main branch is the one displayed by default. For example | ||||||
|  |      * master, trunk or tip. | ||||||
|  |      * | ||||||
|  |      * @return string | ||||||
|  |      */ | ||||||
|  |     public function getMainBranch() | ||||||
|  |     { | ||||||
|  |         throw new Pluf_Exception_NotImplemented(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Returns the list of files in a given folder. | ||||||
|  |      * | ||||||
|  |      * The list is an array of standard class objects with attributes | ||||||
|  |      * for each file/directory/external element. | ||||||
|  |      * | ||||||
|  |      * This is the most important method of the SCM backend as this is | ||||||
|  |      * the one conveying the speed feeling of the application. All the | ||||||
|  |      * dirty optimization tricks are allowed there. | ||||||
|  |      * | ||||||
|  |      * @param string Revision or commit | ||||||
|  |      * @param string Folder ('/') | ||||||
|  |      * @param string Branch (null) | ||||||
|  |      * @return array  | ||||||
|  |      */ | ||||||
|  |     public function getTree($rev, $folder='/', $branch=null) | ||||||
|  |     { | ||||||
|  |         throw new Pluf_Exception_NotImplemented(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Get commit details. | ||||||
|  |      * | ||||||
|  |      * @param string Commit or revision number | ||||||
|  |      * @param bool Get commit diff (false) | ||||||
|  |      * @return stdClass | ||||||
|  |      */ | ||||||
|  |     public function getCommit($commit, $getdiff=false) | ||||||
|  |     { | ||||||
|  |         throw new Pluf_Exception_NotImplemented(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Get latest changes. | ||||||
|  |      * | ||||||
|  |      * It default to the main branch. If possible you should code in a | ||||||
|  |      * way to avoid repetitive calls to getCommit. Try to be | ||||||
|  |      * efficient. | ||||||
|  |      * | ||||||
|  |      * @param string Branch (null) | ||||||
|  |      * @param int Number of changes (25) | ||||||
|  |      * @return array List of commits | ||||||
|  |      */ | ||||||
|  |     public function getChangeLog($branch=null, $n=10) | ||||||
|  |     { | ||||||
|  |         throw new Pluf_Exception_NotImplemented(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Given the string describing the author from the log find the | ||||||
|  |      * author in the database. | ||||||
|  |      * | ||||||
|  |      * If the input is an array, it will return an array of results. | ||||||
|  |      * | ||||||
|  |      * @param mixed string/array Author | ||||||
|  |      * @return mixed Pluf_User or null or array | ||||||
|  |      */ | ||||||
|  |     public function findAuthor($author) | ||||||
|  |     { | ||||||
|  |         throw new Pluf_Exception_NotImplemented(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Given a revision and a file path, retrieve the file content. | ||||||
|  |      * | ||||||
|  |      * The $cmd_only parameter is to only request the command that is | ||||||
|  |      * used to get the file content. This is used when downloading a | ||||||
|  |      * file at a given revision as it can be passed to a | ||||||
|  |      * Pluf_HTTP_Response_CommandPassThru reponse. This allows to | ||||||
|  |      * stream a large response without buffering it in memory. | ||||||
|  |      * | ||||||
|  |      * The file definition is coming from getPathInfo(). | ||||||
|  |      * | ||||||
|  |      * @see self::getPathInfo() | ||||||
|  |      * | ||||||
|  |      * @param stdClass File definition | ||||||
|  |      * @param bool Returns command only (false) | ||||||
|  |      * @return string File content | ||||||
|  |      */ | ||||||
|  |     public function getFile($def, $cmd_only=false) | ||||||
|  |     { | ||||||
|  |         throw new Pluf_Exception_NotImplemented(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Get information about a file or a path. | ||||||
|  |      * | ||||||
|  |      * @param string File or path | ||||||
|  |      * @param string Revision (null) | ||||||
|  |      * @return mixed False or stdClass with info | ||||||
|  |      */ | ||||||
|  |     public function getPathInfo($file, $rev=null) | ||||||
|  |     { | ||||||
|  |         throw new Pluf_Exception_NotImplemented(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Given a revision and possible path returns additional properties. | ||||||
|  |      * | ||||||
|  |      * @param string Revision | ||||||
|  |      * @param string Path ('') | ||||||
|  |      * @return mixed null or array of properties | ||||||
|  |      */ | ||||||
|  |     public function getProperties($rev, $path='') | ||||||
|  |     { | ||||||
|  |         return null; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Generate the command to create a zip archive at a given commit. | ||||||
|  |      * | ||||||
|  |      * @param string Commit | ||||||
|  |      * @param string Prefix ('repository/') | ||||||
|  |      * @return string Command | ||||||
|  |      */ | ||||||
|  |     public function getArchiveCommand($commit, $prefix='repository/') | ||||||
|  |     { | ||||||
|  |         throw new Pluf_Exception_NotImplemented(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
| @@ -95,13 +345,13 @@ class IDF_Scm | |||||||
|         $key = 'IDF_Scm:'.$project->shortname.':lastsync';  |         $key = 'IDF_Scm:'.$project->shortname.':lastsync';  | ||||||
|         if (null === ($res=$cache->get($key))) { |         if (null === ($res=$cache->get($key))) { | ||||||
|             $scm = IDF_Scm::get($project); |             $scm = IDF_Scm::get($project); | ||||||
|             foreach ($scm->getBranches() as $branche) { |             if ($scm->isAvailable()) { | ||||||
|                 foreach ($scm->getChangeLog($branche, 25) as $change) { |                 foreach ($scm->getChangeLog($scm->getMainBranch(), 25) as $change) { | ||||||
|                     IDF_Commit::getOrAdd($change, $project); |                     IDF_Commit::getOrAdd($change, $project); | ||||||
|                 } |                 } | ||||||
|             } |  | ||||||
|                 $cache->set($key, true, (int)(Pluf::f('cache_timeout', 300)/2)); |                 $cache->set($key, true, (int)(Pluf::f('cache_timeout', 300)/2)); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										134
									
								
								src/IDF/Scm/Cache/Git.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										134
									
								
								src/IDF/Scm/Cache/Git.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,134 @@ | |||||||
|  | <?php | ||||||
|  | /* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ | ||||||
|  | /* | ||||||
|  | # ***** BEGIN LICENSE BLOCK ***** | ||||||
|  | # This file is part of InDefero, an open source project management application. | ||||||
|  | # Copyright (C) 2008 Céondo Ltd and contributors. | ||||||
|  | # | ||||||
|  | # InDefero is free software; you can redistribute it and/or modify | ||||||
|  | # it under the terms of the GNU General Public License as published by | ||||||
|  | # the Free Software Foundation; either version 2 of the License, or | ||||||
|  | # (at your option) any later version. | ||||||
|  | # | ||||||
|  | # InDefero is distributed in the hope that it will be useful, | ||||||
|  | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  | # GNU General Public License for more details. | ||||||
|  | # | ||||||
|  | # You should have received a copy of the GNU General Public License | ||||||
|  | # along with this program; if not, write to the Free Software | ||||||
|  | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA | ||||||
|  | # | ||||||
|  | # ***** END LICENSE BLOCK ***** */ | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * This class implements the cache storage for the Git commits. | ||||||
|  |  * | ||||||
|  |  * The storage is simple. Each commit is linked to a project to drop | ||||||
|  |  * the cache when the project is dropped. The key is the commit hash | ||||||
|  |  * and the data is the date, author and one line title of information. | ||||||
|  |  * | ||||||
|  |  * A clean interface is available to bulk set/get a series of commit | ||||||
|  |  * info with the minimum of SQL queries. The goal is to be fast. | ||||||
|  |  */ | ||||||
|  | class IDF_Scm_Cache_Git extends Pluf_Model | ||||||
|  | { | ||||||
|  |     public $_model = __CLASS__; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * The current project to limit the search to. | ||||||
|  |      */ | ||||||
|  |     public $_project = null; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Store in the cache blob infos. | ||||||
|  |      * | ||||||
|  |      * The info is an array of stdClasses, with hash, date, title and | ||||||
|  |      * author properties. | ||||||
|  |      * | ||||||
|  |      * @param array Blob infos | ||||||
|  |      */ | ||||||
|  |     public function store($infos) | ||||||
|  |     { | ||||||
|  |         foreach ($infos as $blob) { | ||||||
|  |             $cache = new IDF_Scm_Cache_Git(); | ||||||
|  |             $cache->project = $this->_project; | ||||||
|  |             $cache->githash = $blob->hash; | ||||||
|  |             $blob->title = IDF_Commit::toUTF8($blob->title); | ||||||
|  |             $cache->content = $blob->date.chr(31).$blob->author.chr(31).$blob->title; | ||||||
|  |             $sql = new Pluf_SQL('project=%s AND githash=%s', | ||||||
|  |                                 array($this->_project->id, $blob->hash)); | ||||||
|  |             if (0 == Pluf::factory(__CLASS__)->getCount(array('filter' => $sql->gen()))) { | ||||||
|  |                 $cache->create(); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Get for the given hashes the corresponding date, title and | ||||||
|  |      * author. | ||||||
|  |      * | ||||||
|  |      * It returns an hash indexed array with the info. If an hash is | ||||||
|  |      * not in the db, the key is not set. | ||||||
|  |      * | ||||||
|  |      * Note that the hashes must always come from internal tools. | ||||||
|  |      * | ||||||
|  |      * @param array Hashes to get info | ||||||
|  |      * @return array Blob infos | ||||||
|  |      */ | ||||||
|  |     public function retrieve($hashes) | ||||||
|  |     { | ||||||
|  |         $res = array(); | ||||||
|  |         $db = $this->getDbConnection(); | ||||||
|  |         $hashes = array_map(array($db, 'esc'), $hashes); | ||||||
|  |         $sql = new Pluf_SQL('project=%s AND githash IN ('.implode(', ', $hashes).')',  | ||||||
|  |                             array($this->_project->id)); | ||||||
|  |         foreach (Pluf::factory(__CLASS__)->getList(array('filter' => $sql->gen())) as $blob) { | ||||||
|  |             $tmp = split(chr(31), $blob->content, 3); | ||||||
|  |  | ||||||
|  |             $res[$blob->githash] = (object) array( | ||||||
|  |                                                   'hash' => $blob->githash, | ||||||
|  |                                                   'date' => $tmp[0], | ||||||
|  |                                                   'title' => $tmp[2], | ||||||
|  |                                                   'author' => $tmp[1], | ||||||
|  |                                                   ); | ||||||
|  |         } | ||||||
|  |         return $res; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * The storage is composed of 4 columns, id, project, hash and the | ||||||
|  |      * raw data. | ||||||
|  |      */ | ||||||
|  |     function init() | ||||||
|  |     { | ||||||
|  |         $this->_a['table'] = 'idf_scm_cache_git'; | ||||||
|  |         $this->_a['model'] = __CLASS__; | ||||||
|  |         $this->_a['cols'] = array( | ||||||
|  |                              // It is mandatory to have an "id" column. | ||||||
|  |                             'id' => | ||||||
|  |                             array( | ||||||
|  |                                   'type' => 'Pluf_DB_Field_Sequence', | ||||||
|  |                                   'blank' => true,  | ||||||
|  |                                   ), | ||||||
|  |                             'project' =>  | ||||||
|  |                             array( | ||||||
|  |                                   'type' => 'Pluf_DB_Field_Foreignkey', | ||||||
|  |                                   'model' => 'IDF_Project', | ||||||
|  |                                   'blank' => false, | ||||||
|  |                                   ), | ||||||
|  |                             'githash' => | ||||||
|  |                             array( | ||||||
|  |                                   'type' => 'Pluf_DB_Field_Varchar', | ||||||
|  |                                   'blank' => false, | ||||||
|  |                                   'size' => 40, | ||||||
|  |                                   'index' => true, | ||||||
|  |                                   ), | ||||||
|  |                             'content' => | ||||||
|  |                             array( | ||||||
|  |                                   'type' => 'Pluf_DB_Field_Text', | ||||||
|  |                                   'blank' => false, | ||||||
|  |                                   ), | ||||||
|  |                             ); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -25,14 +25,153 @@ | |||||||
|  * Git utils. |  * Git utils. | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| class IDF_Scm_Git | class IDF_Scm_Git extends IDF_Scm | ||||||
| { | { | ||||||
|     public $repo = ''; |  | ||||||
|     public $mediumtree_fmt = 'commit %H%nAuthor: %an <%ae>%nTree: %T%nDate: %ai%n%n%s%n%n%b'; |     public $mediumtree_fmt = 'commit %H%nAuthor: %an <%ae>%nTree: %T%nDate: %ai%n%n%s%n%n%b'; | ||||||
|      |      | ||||||
|     public function __construct($repo) |     /* ============================================== * | ||||||
|  |      *                                                * | ||||||
|  |      *   Common Methods Implemented By All The SCMs   * | ||||||
|  |      *                                                * | ||||||
|  |      * ============================================== */  | ||||||
|  |  | ||||||
|  |     public function __construct($repo, $project=null) | ||||||
|     { |     { | ||||||
|         $this->repo = $repo; |         $this->repo = $repo; | ||||||
|  |         $this->project = $project; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public function getRepositorySize() | ||||||
|  |     { | ||||||
|  |         $cmd = Pluf::f('idf_exec_cmd_prefix', '').'du -sk ' | ||||||
|  |             .escapeshellarg($this->repo); | ||||||
|  |         $out = split(' ', shell_exec($cmd), 2); | ||||||
|  |         return (int) $out[0]*1024; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public function isAvailable() | ||||||
|  |     { | ||||||
|  |         try { | ||||||
|  |             $branches = $this->getBranches(); | ||||||
|  |         } catch (IDF_Scm_Exception $e) { | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  |         return (count($branches) > 0); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public function getBranches() | ||||||
|  |     { | ||||||
|  |         if (isset($this->cache['branches'])) { | ||||||
|  |             return $this->cache['branches']; | ||||||
|  |         } | ||||||
|  |         $cmd = Pluf::f('idf_exec_cmd_prefix', '') | ||||||
|  |             .sprintf('GIT_DIR=%s '.Pluf::f('git_path', 'git').' branch',  | ||||||
|  |                      escapeshellarg($this->repo)); | ||||||
|  |         exec($cmd, $out, $return); | ||||||
|  |         if ($return != 0) { | ||||||
|  |             throw new IDF_Scm_Exception(sprintf($this->error_tpl, | ||||||
|  |                                                 $cmd, $return,  | ||||||
|  |                                                 implode("\n", $out))); | ||||||
|  |         } | ||||||
|  |         $res = array(); | ||||||
|  |         foreach ($out as $b) { | ||||||
|  |             $b = substr($b, 2); | ||||||
|  |             if (false !== strpos($b, '/')) { | ||||||
|  |                 $res[$this->getCommit($b)->commit] = $b; | ||||||
|  |             } else { | ||||||
|  |                 $res[$b] = ''; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         $this->cache['branches'] = $res; | ||||||
|  |         return $res; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public function getMainBranch() | ||||||
|  |     { | ||||||
|  |         $possible = array('master', 'main', 'trunk', 'local'); | ||||||
|  |         $branches = array_keys($this->getBranches()); | ||||||
|  |         foreach ($possible as $p) { | ||||||
|  |             if (in_array($p, $branches)) { | ||||||
|  |                 return $p; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         return (isset($branches[0])) ? $branches[0] : 'master'; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Note: Running the `git branch --contains $commit` is | ||||||
|  |      * theoritically the best way to do it, until you figure out that | ||||||
|  |      * you cannot cache the result and that it takes several seconds | ||||||
|  |      * to execute on a big tree. | ||||||
|  |      */ | ||||||
|  |     public function inBranches($commit, $path) | ||||||
|  |     { | ||||||
|  |         return (in_array($commit, array_keys($this->getBranches())))  | ||||||
|  |                 ? array($commit) : array(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Git "tree" is not the same as the tree we get here. | ||||||
|  |      * | ||||||
|  |      * With git each commit object stores a related tree object. This | ||||||
|  |      * tree is basically providing what is in the given folder at the | ||||||
|  |      * given commit. It looks something like that: | ||||||
|  |      * | ||||||
|  |      * <pre> | ||||||
|  |      * 100644 blob bcd155e609c51b4651aab9838b270cce964670af	AUTHORS | ||||||
|  |      * 100644 blob 87b44c5c7df3cc90c031317c1ac8efcfd8a13631	COPYING | ||||||
|  |      * 100644 blob 2a0f899cbfe33ea755c343b06a13d7de6c22799f	INSTALL.mdtext | ||||||
|  |      * 040000 tree 2f469c4c5318aa4ad48756874373370f6112f77b	doc | ||||||
|  |      * 040000 tree 911e0bd2706f0069b04744d6ef41353faf06a0a7	logo | ||||||
|  |      * </pre> | ||||||
|  |      * | ||||||
|  |      * You can then follow what is in the given folder (let say doc) | ||||||
|  |      * by using the hash. | ||||||
|  |      * | ||||||
|  |      * This means that you will have not to confuse the git tree and | ||||||
|  |      * the output tree in the following method. | ||||||
|  |      * | ||||||
|  |      * @see http://www.kernel.org/pub/software/scm/git/docs/git-ls-tree.html | ||||||
|  |      * | ||||||
|  |      */ | ||||||
|  |     public function getTree($commit, $folder='/', $branch=null) | ||||||
|  |     { | ||||||
|  |         $folder = ($folder == '/') ? '' : $folder; | ||||||
|  |         // now we grab the info about this commit including its tree. | ||||||
|  |         if (false == ($co = $this->getCommit($commit))) { | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  |         if ($folder) { | ||||||
|  |             // As we are limiting to a given folder, we need to find | ||||||
|  |             // the tree corresponding to this folder. | ||||||
|  |             $tinfo = $this->getTreeInfo($commit, $folder);  | ||||||
|  |             if (isset($tinfo[0]) and $tinfo[0]->type == 'tree') { | ||||||
|  |                 $tree = $tinfo[0]->hash; | ||||||
|  |             } else { | ||||||
|  |                 throw new Exception(sprintf(__('Folder %1$s not found in commit %2$s.'), $folder, $commit)); | ||||||
|  |             } | ||||||
|  |         } else { | ||||||
|  |             $tree = $co->tree; | ||||||
|  |         } | ||||||
|  |         $res = array(); | ||||||
|  |         foreach ($this->getTreeInfo($tree) as $file) { | ||||||
|  |             // Now we grab the files in the current tree with as much | ||||||
|  |             // information as possible. | ||||||
|  |             if ($file->type == 'blob') { | ||||||
|  |                 $file->date = $co->date; | ||||||
|  |                 $file->log = '----';  | ||||||
|  |                 $file->author = 'Unknown'; | ||||||
|  |             } | ||||||
|  |             $file->fullpath = ($folder) ? $folder.'/'.$file->file : $file->file; | ||||||
|  |             if ($file->type == 'commit') { | ||||||
|  |                 // We have a submodule | ||||||
|  |                 $file = $this->getSubmodule($file, $commit); | ||||||
|  |             } | ||||||
|  |             $res[] = $file; | ||||||
|  |         } | ||||||
|  |         // Grab the details for each blob and return the list. | ||||||
|  |         return $this->getTreeDetails($res); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
| @@ -54,25 +193,12 @@ class IDF_Scm_Git | |||||||
|         return ($users->count() > 0) ? $users[0] : null; |         return ($users->count() > 0) ? $users[0] : null; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     public static function getAnonymousAccessUrl($project) | ||||||
|     /** |  | ||||||
|      * Returns the URL of the git daemon. |  | ||||||
|      * |  | ||||||
|      * @param IDF_Project |  | ||||||
|      * @return string URL |  | ||||||
|      */ |  | ||||||
|     public static function getRemoteAccessUrl($project) |  | ||||||
|     { |     { | ||||||
|         return sprintf(Pluf::f('git_remote_url'), $project->shortname); |         return sprintf(Pluf::f('git_remote_url'), $project->shortname); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     public static function getAuthAccessUrl($project, $user) | ||||||
|      * Returns the URL for SSH access |  | ||||||
|      * |  | ||||||
|      * @param IDF_Project |  | ||||||
|      * @return string URL |  | ||||||
|      */ |  | ||||||
|     public static function getWriteRemoteAccessUrl($project) |  | ||||||
|     { |     { | ||||||
|         return sprintf(Pluf::f('git_write_remote_url'), $project->shortname); |         return sprintf(Pluf::f('git_write_remote_url'), $project->shortname); | ||||||
|     } |     } | ||||||
| @@ -86,114 +212,53 @@ class IDF_Scm_Git | |||||||
|     public static function factory($project) |     public static function factory($project) | ||||||
|     { |     { | ||||||
|         $rep = sprintf(Pluf::f('git_repositories'), $project->shortname); |         $rep = sprintf(Pluf::f('git_repositories'), $project->shortname); | ||||||
|         return new IDF_Scm_Git($rep); |         return new IDF_Scm_Git($rep, $project); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     public function isValidRevision($commit) | ||||||
|  |     { | ||||||
|  |         return ('commit' == $this->testHash($commit)); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Test a given object hash. |      * Test a given object hash. | ||||||
|      * |      * | ||||||
|      * @param string Object hash. |      * @param string Object hash. | ||||||
|      * @param null to be svn client compatible |  | ||||||
|      * @return mixed false if not valid or 'blob', 'tree', 'commit' |      * @return mixed false if not valid or 'blob', 'tree', 'commit' | ||||||
|      */ |      */ | ||||||
|     public function testHash($hash, $dummy=null) |     public function testHash($hash) | ||||||
|     { |     { | ||||||
|         $cmd = sprintf('GIT_DIR=%s '.Pluf::f('git_path', 'git').' cat-file -t %s', |         $cmd = sprintf('GIT_DIR=%s '.Pluf::f('git_path', 'git').' cat-file -t %s', | ||||||
|                        escapeshellarg($this->repo), |                        escapeshellarg($this->repo), | ||||||
|                        escapeshellarg($hash)); |                        escapeshellarg($hash)); | ||||||
|         $ret = 0; $out = array(); |         $ret = 0; $out = array(); | ||||||
|         IDF_Scm::exec($cmd, $out, $ret); |         $cmd = Pluf::f('idf_exec_cmd_prefix', '').$cmd; | ||||||
|  |         exec($cmd, $out, $ret); | ||||||
|         if ($ret != 0) return false; |         if ($ret != 0) return false; | ||||||
|         return trim($out[0]); |         return trim($out[0]); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Given a commit hash returns an array of files in it. |  | ||||||
|      * |  | ||||||
|      * A file is a class with the following properties: |  | ||||||
|      * |  | ||||||
|      * 'perm', 'type', 'size', 'hash', 'file' |  | ||||||
|      * |  | ||||||
|      * @param string Commit ('HEAD') |  | ||||||
|      * @param string Base folder ('') |  | ||||||
|      * @return array  |  | ||||||
|      */ |  | ||||||
|     public function filesAtCommit($commit='HEAD', $folder='') |  | ||||||
|     { |  | ||||||
|         // now we grab the info about this commit including its tree. |  | ||||||
|         $co = $this->getCommit($commit); |  | ||||||
|         if ($folder) { |  | ||||||
|             // As we are limiting to a given folder, we need to find |  | ||||||
|             // the tree corresponding to this folder. |  | ||||||
|             $found = false; |  | ||||||
|             foreach ($this->getTreeInfo($co->tree, true, $folder) as $file) { |  | ||||||
|                 if ($file->type == 'tree' and $file->file == $folder) { |  | ||||||
|                     $found = true; |  | ||||||
|                     $tree = $file->hash; |  | ||||||
|                     break; |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|             if (!$found) { |  | ||||||
|                 throw new Exception(sprintf(__('Folder %1$s not found in commit %2$s.'), $folder, $commit)); |  | ||||||
|             } |  | ||||||
|         } else { |  | ||||||
|             $tree = $co->tree; |  | ||||||
|         } |  | ||||||
|         $res = array(); |  | ||||||
|         // get the raw log corresponding to this commit to find the |  | ||||||
|         // origin of each file. |  | ||||||
|         $rawlog = array(); |  | ||||||
|         $cmd = sprintf('GIT_DIR=%s '.Pluf::f('git_path', 'git').' log --raw --abbrev=40 --pretty=oneline -5000 %s', |  | ||||||
|                        escapeshellarg($this->repo), escapeshellarg($commit)); |  | ||||||
|         IDF_Scm::exec($cmd, $rawlog); |  | ||||||
|         // We reverse the log to be able to use a fixed efficient |  | ||||||
|         // regex without back tracking. |  | ||||||
|         $rawlog = implode("\n", array_reverse($rawlog)); |  | ||||||
|         foreach ($this->getTreeInfo($tree, false) as $file) { |  | ||||||
|             // Now we grab the files in the current tree with as much |  | ||||||
|             // information as possible. |  | ||||||
|             $matches = array(); |  | ||||||
|             if ($file->type == 'blob' and preg_match('/^\:\d{6} \d{6} [0-9a-f]{40} '.$file->hash.' .*^([0-9a-f]{40})/msU', |  | ||||||
|                            $rawlog, $matches)) { |  | ||||||
|                 $fc = $this->getCommit($matches[1]); |  | ||||||
|                 $file->date = $fc->date; |  | ||||||
|                 $file->log = $fc->title; |  | ||||||
|                 $file->author = $fc->author; |  | ||||||
|             } else if ($file->type == 'blob') { |  | ||||||
|                 $file->date = $co->date; |  | ||||||
|                 $file->log = '----';  |  | ||||||
|                 $file->author = 'Unknown'; |  | ||||||
|             } |  | ||||||
|             $file->fullpath = ($folder) ? $folder.'/'.$file->file : $file->file; |  | ||||||
|             if ($file->type == 'commit') { |  | ||||||
|                 // We have a submodule |  | ||||||
|                 $file = $this->getSubmodule($file, $commit); |  | ||||||
|             } |  | ||||||
|             $res[] = $file; |  | ||||||
|         } |  | ||||||
|         return $res; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Get the tree info. |      * Get the tree info. | ||||||
|      * |      * | ||||||
|      * @param string Tree hash  |      * @param string Tree hash  | ||||||
|      * @param bool Do we recurse in subtrees (true) |      * @param bool Do we recurse in subtrees (true) | ||||||
|  |      * @param string Folder in which we want to get the info ('') | ||||||
|      * @return array Array of file information. |      * @return array Array of file information. | ||||||
|      */ |      */ | ||||||
|     public function getTreeInfo($tree, $recurse=true, $folder='') |     public function getTreeInfo($tree, $folder='') | ||||||
|     { |     { | ||||||
|         if ('tree' != $this->testHash($tree)) { |         if (!in_array($this->testHash($tree), array('tree', 'commit'))) { | ||||||
|             throw new Exception(sprintf(__('Not a valid tree: %s.'), $tree)); |             throw new Exception(sprintf(__('Not a valid tree: %s.'), $tree)); | ||||||
|         } |         } | ||||||
|         $cmd_tmpl = 'GIT_DIR=%s '.Pluf::f('git_path', 'git').' ls-tree%s -t -l %s %s'; |         $cmd_tmpl = 'GIT_DIR=%s '.Pluf::f('git_path', 'git').' ls-tree -l %s %s'; | ||||||
|         $cmd = sprintf($cmd_tmpl,  |         $cmd = Pluf::f('idf_exec_cmd_prefix', '') | ||||||
|                        escapeshellarg($this->repo),  |             .sprintf($cmd_tmpl, escapeshellarg($this->repo),  | ||||||
|                        ($recurse) ? ' -r' : '', |  | ||||||
|                      escapeshellarg($tree), escapeshellarg($folder)); |                      escapeshellarg($tree), escapeshellarg($folder)); | ||||||
|         $out = array(); |         $out = array(); | ||||||
|         $res = array(); |         $res = array(); | ||||||
|         IDF_Scm::exec($cmd, $out); |         exec($cmd, $out); | ||||||
|         foreach ($out as $line) { |         foreach ($out as $line) { | ||||||
|             list($perm, $type, $hash, $size, $file) = preg_split('/ |\t/', $line, 5, PREG_SPLIT_NO_EMPTY); |             list($perm, $type, $hash, $size, $file) = preg_split('/ |\t/', $line, 5, PREG_SPLIT_NO_EMPTY); | ||||||
|             $res[] = (object) array('perm' => $perm, 'type' => $type,  |             $res[] = (object) array('perm' => $perm, 'type' => $type,  | ||||||
| @@ -211,65 +276,46 @@ class IDF_Scm_Git | |||||||
|      * @param string Commit ('HEAD') |      * @param string Commit ('HEAD') | ||||||
|      * @return false Information |      * @return false Information | ||||||
|      */ |      */ | ||||||
|     public function getFileInfo($totest, $commit='HEAD') |     public function getPathInfo($totest, $commit='HEAD') | ||||||
|     { |     { | ||||||
|         $cmd_tmpl = 'GIT_DIR=%s '.Pluf::f('git_path', 'git').' ls-tree -r -t -l %s'; |         $cmd_tmpl = 'GIT_DIR=%s '.Pluf::f('git_path', 'git').' ls-tree -r -t -l %s'; | ||||||
|         $cmd = sprintf($cmd_tmpl,  |         $cmd = sprintf($cmd_tmpl,  | ||||||
|                        escapeshellarg($this->repo),  |                        escapeshellarg($this->repo),  | ||||||
|                        escapeshellarg($commit)); |                        escapeshellarg($commit)); | ||||||
|         $out = array(); |         $out = array(); | ||||||
|         IDF_Scm::exec($cmd, $out); |         $cmd = Pluf::f('idf_exec_cmd_prefix', '').$cmd; | ||||||
|  |         exec($cmd, $out); | ||||||
|         foreach ($out as $line) { |         foreach ($out as $line) { | ||||||
|             list($perm, $type, $hash, $size, $file) = preg_split('/ |\t/', $line, 5, PREG_SPLIT_NO_EMPTY); |             list($perm, $type, $hash, $size, $file) = preg_split('/ |\t/', $line, 5, PREG_SPLIT_NO_EMPTY); | ||||||
|             if ($totest == $file) { |             if ($totest == $file) { | ||||||
|  |                 $pathinfo = pathinfo($file); | ||||||
|                 return (object) array('perm' => $perm, 'type' => $type,  |                 return (object) array('perm' => $perm, 'type' => $type,  | ||||||
|                                       'size' => $size, 'hash' => $hash,  |                                       'size' => $size, 'hash' => $hash,  | ||||||
|                                       'file' => $file); |                                       'fullpath' => $file, | ||||||
|  |                                       'file' => $pathinfo['basename']); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     public function getFile($def, $cmd_only=false) | ||||||
|      * Get a blob. |  | ||||||
|      * |  | ||||||
|      * @param string request_file_info |  | ||||||
|      * @param null to be svn client compatible |  | ||||||
|      * @return string Raw blob |  | ||||||
|      */ |  | ||||||
|     public function getBlob($request_file_info, $dummy=null) |  | ||||||
|     { |     { | ||||||
|         return shell_exec(sprintf(Pluf::f('idf_exec_cmd_prefix', ''). |         $cmd = sprintf(Pluf::f('idf_exec_cmd_prefix', ''). | ||||||
|                        'GIT_DIR=%s '.Pluf::f('git_path', 'git').' cat-file blob %s', |                        'GIT_DIR=%s '.Pluf::f('git_path', 'git').' cat-file blob %s', | ||||||
|                        escapeshellarg($this->repo),  |                        escapeshellarg($this->repo),  | ||||||
|                                   escapeshellarg($request_file_info->hash))); |                        escapeshellarg($def->hash)); | ||||||
|  |         return ($cmd_only) ? $cmd : shell_exec($cmd); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Get the branches. |  | ||||||
|      * |  | ||||||
|      * @return array Branches. |  | ||||||
|      */ |  | ||||||
|     public function getBranches() |  | ||||||
|     { |  | ||||||
|         $out = array(); |  | ||||||
|         IDF_Scm::exec(sprintf('GIT_DIR=%s '.Pluf::f('git_path', 'git').' branch',  |  | ||||||
|                               escapeshellarg($this->repo)), $out); |  | ||||||
|         $res = array(); |  | ||||||
|         foreach ($out as $b) { |  | ||||||
|             $res[] = substr($b, 2); |  | ||||||
|         } |  | ||||||
|         return $res; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Get commit details. |      * Get commit details. | ||||||
|      * |      * | ||||||
|      * @param string Commit ('HEAD'). |      * @param string Commit | ||||||
|      * @param bool Get commit diff (false). |      * @param bool Get commit diff (false) | ||||||
|      * @return array Changes. |      * @return array Changes | ||||||
|      */ |      */ | ||||||
|     public function getCommit($commit='HEAD', $getdiff=false) |     public function getCommit($commit, $getdiff=false) | ||||||
|     { |     { | ||||||
|         if ($getdiff) { |         if ($getdiff) { | ||||||
|             $cmd = sprintf('GIT_DIR=%s '.Pluf::f('git_path', 'git').' show --date=iso --pretty=format:%s %s', |             $cmd = sprintf('GIT_DIR=%s '.Pluf::f('git_path', 'git').' show --date=iso --pretty=format:%s %s', | ||||||
| @@ -283,7 +329,11 @@ class IDF_Scm_Git | |||||||
|                            escapeshellarg($commit)); |                            escapeshellarg($commit)); | ||||||
|         } |         } | ||||||
|         $out = array(); |         $out = array(); | ||||||
|         IDF_Scm::exec($cmd, $out); |         $cmd = Pluf::f('idf_exec_cmd_prefix', '').$cmd; | ||||||
|  |         exec($cmd, $out, $ret); | ||||||
|  |         if ($ret != 0 or count($out) == 0) { | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|         $log = array(); |         $log = array(); | ||||||
|         $change = array(); |         $change = array(); | ||||||
|         $inchange = false; |         $inchange = false; | ||||||
| @@ -315,7 +365,8 @@ class IDF_Scm_Git | |||||||
|                        "'commit %H%n'",  |                        "'commit %H%n'",  | ||||||
|                        escapeshellarg($commit)); |                        escapeshellarg($commit)); | ||||||
|         $out = array(); |         $out = array(); | ||||||
|         IDF_Scm::exec($cmd, $out); |         $cmd = Pluf::f('idf_exec_cmd_prefix', '').$cmd; | ||||||
|  |         exec($cmd, $out); | ||||||
|         $affected = count($out) - 2; |         $affected = count($out) - 2; | ||||||
|         $added = 0; |         $added = 0; | ||||||
|         $removed = 0; |         $removed = 0; | ||||||
| @@ -347,7 +398,8 @@ class IDF_Scm_Git | |||||||
|                        escapeshellarg($this->repo), $n, $this->mediumtree_fmt,  |                        escapeshellarg($this->repo), $n, $this->mediumtree_fmt,  | ||||||
|                        escapeshellarg($commit)); |                        escapeshellarg($commit)); | ||||||
|         $out = array(); |         $out = array(); | ||||||
|         IDF_Scm::exec($cmd, $out); |         $cmd = Pluf::f('idf_exec_cmd_prefix', '').$cmd; | ||||||
|  |         exec($cmd, $out); | ||||||
|         return self::parseLog($out, 4); |         return self::parseLog($out, 4); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -355,14 +407,12 @@ class IDF_Scm_Git | |||||||
|      * Parse the log lines of a --pretty=medium log output. |      * Parse the log lines of a --pretty=medium log output. | ||||||
|      * |      * | ||||||
|      * @param array Lines. |      * @param array Lines. | ||||||
|      * @param int Number of lines in the headers (3) |  | ||||||
|      * @return array Change log. |      * @return array Change log. | ||||||
|      */ |      */ | ||||||
|     public static function parseLog($lines, $hdrs=3) |     public static function parseLog($lines) | ||||||
|     { |     { | ||||||
|         $res = array(); |         $res = array(); | ||||||
|         $c = array(); |         $c = array(); | ||||||
|         $hdrs += 2; |  | ||||||
|         $inheads = true; |         $inheads = true; | ||||||
|         $next_is_title = false; |         $next_is_title = false; | ||||||
|         foreach ($lines as $line) { |         foreach ($lines as $line) { | ||||||
| @@ -401,19 +451,12 @@ class IDF_Scm_Git | |||||||
|                 continue; |                 continue; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         $c['full_message'] = trim($c['full_message']); |         $c['full_message'] = !empty($c['full_message']) ? trim($c['full_message']) : ''; | ||||||
|         $res[] = (object) $c; |         $res[] = (object) $c; | ||||||
|         return $res; |         return $res; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     public function getArchiveCommand($commit, $prefix='repository/') | ||||||
|      * Generate the command to create a zip archive at a given commit. |  | ||||||
|      * |  | ||||||
|      * @param string Commit |  | ||||||
|      * @param string Prefix ('git-repo-dump') |  | ||||||
|      * @return string Command |  | ||||||
|      */ |  | ||||||
|     public function getArchiveCommand($commit, $prefix='git-repo-dump/') |  | ||||||
|     { |     { | ||||||
|         return sprintf(Pluf::f('idf_exec_cmd_prefix', ''). |         return sprintf(Pluf::f('idf_exec_cmd_prefix', ''). | ||||||
|                        'GIT_DIR=%s '.Pluf::f('git_path', 'git').' archive --format=zip --prefix=%s %s', |                        'GIT_DIR=%s '.Pluf::f('git_path', 'git').' archive --format=zip --prefix=%s %s', | ||||||
| @@ -440,15 +483,232 @@ class IDF_Scm_Git | |||||||
|     public function getSubmodule($file, $commit) |     public function getSubmodule($file, $commit) | ||||||
|     { |     { | ||||||
|         $file->type = 'extern'; |         $file->type = 'extern'; | ||||||
|         $info = $this->getFileInfo('.gitmodules', $commit); |         $file->extern = ''; | ||||||
|  |         $info = $this->getPathInfo('.gitmodules', $commit); | ||||||
|         if ($info == false) { |         if ($info == false) { | ||||||
|             return $file; |             return $file; | ||||||
|         } |         } | ||||||
|         $gitmodules = $this->getBlob($info); |         $gitmodules = $this->getFile($info); | ||||||
|         if (preg_match('#\[submodule\s+\"'.$file->fullpath.'\"\]\s+path\s=\s(\S+)\s+url\s=\s(\S+)#mi', $gitmodules, $matches)) { |         if (preg_match('#\[submodule\s+\"'.$file->fullpath.'\"\]\s+path\s=\s(\S+)\s+url\s=\s(\S+)#mi', $gitmodules, $matches)) { | ||||||
|             $file->extern = $matches[2]; |             $file->extern = $matches[2]; | ||||||
|         } |         } | ||||||
|         return $file; |         return $file; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Foreach file in the tree, find the details. | ||||||
|  |      * | ||||||
|  |      * @param array Tree information | ||||||
|  |      * @return array Updated tree information | ||||||
|  |      */ | ||||||
|  |     public function getTreeDetails($tree) | ||||||
|  |     { | ||||||
|  |         $n = count($tree); | ||||||
|  |         $details = array(); | ||||||
|  |         for ($i=0;$i<$n;$i++) { | ||||||
|  |             if ($tree[$i]->type == 'blob') { | ||||||
|  |                 $details[$tree[$i]->hash] = $i; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         if (!count($details)) { | ||||||
|  |             return $tree; | ||||||
|  |         } | ||||||
|  |         $res = $this->getCachedBlobInfo($details); | ||||||
|  |         $toapp = array(); | ||||||
|  |         foreach ($details as $blob => $idx) { | ||||||
|  |             if (isset($res[$blob])) { | ||||||
|  |                 $tree[$idx]->date = $res[$blob]->date; | ||||||
|  |                 $tree[$idx]->log = $res[$blob]->title; | ||||||
|  |                 $tree[$idx]->author = $res[$blob]->author; | ||||||
|  |             } else { | ||||||
|  |                 $toapp[$blob] = $idx; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         if (count($toapp)) { | ||||||
|  |             $res = $this->appendBlobInfoCache($toapp); | ||||||
|  |             foreach ($details as $blob => $idx) { | ||||||
|  |                 if (isset($res[$blob])) { | ||||||
|  |                     $tree[$idx]->date = $res[$blob]->date; | ||||||
|  |                     $tree[$idx]->log = $res[$blob]->title; | ||||||
|  |                     $tree[$idx]->author = $res[$blob]->author; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         return $tree; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Append build info cache. | ||||||
|  |      * | ||||||
|  |      * The append method tries to get only the necessary details, so | ||||||
|  |      * instead of going through all the commits one at a time, it will | ||||||
|  |      * try to find a smarter way with regex. | ||||||
|  |      * | ||||||
|  |      * @see self::buildBlobInfoCache | ||||||
|  |      * | ||||||
|  |      * @param array The blob for which we need the information | ||||||
|  |      * @return array The information | ||||||
|  |      */ | ||||||
|  |     public function appendBlobInfoCache($blobs) | ||||||
|  |     { | ||||||
|  |         $rawlog = array(); | ||||||
|  |         $cmd = Pluf::f('idf_exec_cmd_prefix', '') | ||||||
|  |             .sprintf('GIT_DIR=%s '.Pluf::f('git_path', 'git').' log --raw --abbrev=40 --pretty=oneline -5000 --skip=%%s', | ||||||
|  |                      escapeshellarg($this->repo)); | ||||||
|  |         $skip = 0; | ||||||
|  |         $res = array(); | ||||||
|  |         exec(sprintf($cmd, $skip), $rawlog); | ||||||
|  |         while (count($rawlog) and count($blobs)) { | ||||||
|  |             $rawlog = implode("\n", array_reverse($rawlog)); | ||||||
|  |             foreach ($blobs as $blob => $idx) { | ||||||
|  |                 if (preg_match('/^\:\d{6} \d{6} [0-9a-f]{40} ' | ||||||
|  |                                .$blob.' .*^([0-9a-f]{40})/msU', | ||||||
|  |                                $rawlog, $matches)) { | ||||||
|  |                     $fc = $this->getCommit($matches[1]); | ||||||
|  |                     $res[$blob] = (object) array('hash' => $blob, | ||||||
|  |                                                  'date' => $fc->date, | ||||||
|  |                                                  'title' => $fc->title, | ||||||
|  |                                                  'author' => $fc->author); | ||||||
|  |                     unset($blobs[$blob]); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             $rawlog = array(); | ||||||
|  |             $skip += 5000; | ||||||
|  |             if ($skip > 20000) { | ||||||
|  |                 // We are in the case of the import of a big old | ||||||
|  |                 // repository, we can store as unknown the commit info | ||||||
|  |                 // not to try to retrieve them each time. | ||||||
|  |                 foreach ($blobs as $blob => $idx) { | ||||||
|  |                     $res[$blob] = (object) array('hash' => $blob, | ||||||
|  |                                                  'date' => '0', | ||||||
|  |                                                  'title' => '----', | ||||||
|  |                                                  'author' => 'Unknown'); | ||||||
|  |                 } | ||||||
|  |                 break; | ||||||
|  |             } | ||||||
|  |             exec(sprintf($cmd, $skip), $rawlog); | ||||||
|  |         } | ||||||
|  |         $this->cacheBlobInfo($res); | ||||||
|  |         return $res; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Build the blob info cache. | ||||||
|  |      * | ||||||
|  |      * We build the blob info cache 500 commits at a time.  | ||||||
|  |      */ | ||||||
|  |     public function buildBlobInfoCache() | ||||||
|  |     { | ||||||
|  |         $rawlog = array(); | ||||||
|  |         $cmd = Pluf::f('idf_exec_cmd_prefix', '') | ||||||
|  |             .sprintf('GIT_DIR=%s '.Pluf::f('git_path', 'git').' log --raw --abbrev=40 --pretty=oneline -500 --skip=%%s', | ||||||
|  |                      escapeshellarg($this->repo)); | ||||||
|  |         $skip = 0; | ||||||
|  |         exec(sprintf($cmd, $skip), $rawlog); | ||||||
|  |         while (count($rawlog)) { | ||||||
|  |             $commit = ''; | ||||||
|  |             $data = array(); | ||||||
|  |             foreach ($rawlog as $line) { | ||||||
|  |                 if (substr($line, 0, 1) != ':') { | ||||||
|  |                     $commit = $this->getCommit(substr($line, 0, 40)); | ||||||
|  |                     continue; | ||||||
|  |                 } | ||||||
|  |                 $blob = substr($line, 56, 40); | ||||||
|  |                 $data[] = (object) array('hash' => $blob, | ||||||
|  |                                          'date' => $commit->date, | ||||||
|  |                                          'title' => $commit->title, | ||||||
|  |                                          'author' => $commit->author); | ||||||
|  |             } | ||||||
|  |             $this->cacheBlobInfo($data); | ||||||
|  |             $rawlog = array(); | ||||||
|  |             $skip += 500; | ||||||
|  |             exec(sprintf($cmd, $skip), $rawlog); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Get blob info. | ||||||
|  |      * | ||||||
|  |      * When we display the tree, we want to know when a given file was | ||||||
|  |      * created, who was the author and at which date. This is a very | ||||||
|  |      * slow operation for git as we need to go through the full | ||||||
|  |      * history, find when then blob was introduced, then grab the | ||||||
|  |      * corresponding commit. This is why we need a cache. | ||||||
|  |      * | ||||||
|  |      * @param array List as keys of blob hashs to get info for | ||||||
|  |      * @return array Hash indexed results, when not found not set | ||||||
|  |      */ | ||||||
|  |     public function getCachedBlobInfo($hashes) | ||||||
|  |     { | ||||||
|  |         $cache = new IDF_Scm_Cache_Git(); | ||||||
|  |         $cache->_project = $this->project; | ||||||
|  |         return $cache->retrieve(array_keys($hashes)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Cache blob info. | ||||||
|  |      *  | ||||||
|  |      * Given a series of blob info, cache them. | ||||||
|  |      * | ||||||
|  |      * @param array Blob info | ||||||
|  |      * @return bool Success | ||||||
|  |      */ | ||||||
|  |     public function cacheBlobInfo($info) | ||||||
|  |     { | ||||||
|  |         $cache = new IDF_Scm_Cache_Git(); | ||||||
|  |         $cache->_project = $this->project; | ||||||
|  |         return $cache->store($info); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public function getFileCachedBlobInfo($hashes) | ||||||
|  |     { | ||||||
|  |         $res = array(); | ||||||
|  |         $cache = Pluf::f('tmp_folder').'/IDF_Scm_Git-'.md5($this->repo).'.cache.db'; | ||||||
|  |         if (!file_exists($cache)) { | ||||||
|  |             return $res; | ||||||
|  |         } | ||||||
|  |         $data = file_get_contents($cache); | ||||||
|  |         if (false === $data) { | ||||||
|  |             return $res; | ||||||
|  |         } | ||||||
|  |         $data = split(chr(30), $data); | ||||||
|  |         foreach ($data as $rec) { | ||||||
|  |             if (isset($hashes[substr($rec, 0, 40)])) { | ||||||
|  |                 $tmp = split(chr(31), substr($rec, 40), 3); | ||||||
|  |                 $res[substr($rec, 0, 40)] =  | ||||||
|  |                     (object) array('hash' => substr($rec, 0, 40), | ||||||
|  |                                    'date' => $tmp[0], | ||||||
|  |                                    'title' => $tmp[2], | ||||||
|  |                                    'author' => $tmp[1]); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         return $res; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * File cache blob info. | ||||||
|  |      *  | ||||||
|  |      * Given a series of blob info, cache them. | ||||||
|  |      * | ||||||
|  |      * @param array Blob info | ||||||
|  |      * @return bool Success | ||||||
|  |      */ | ||||||
|  |     public function fileCacheBlobInfo($info) | ||||||
|  |     { | ||||||
|  |         // Prepare the data | ||||||
|  |         $data = array(); | ||||||
|  |         foreach ($info as $file) { | ||||||
|  |             $data[] = $file->hash.$file->date.chr(31).$file->author.chr(31).$file->title; | ||||||
|  |         } | ||||||
|  |         $data = implode(chr(30), $data).chr(30); | ||||||
|  |         $cache = Pluf::f('tmp_folder').'/IDF_Scm_Git-'.md5($this->repo).'.cache.db'; | ||||||
|  |         $fp = fopen($cache, 'ab');  | ||||||
|  |         if ($fp) { | ||||||
|  |             flock($fp, LOCK_EX);  | ||||||
|  |             fwrite($fp, $data, strlen($data)); | ||||||
|  |             fclose($fp); // releases the lock too | ||||||
|  |             return true; | ||||||
|  |         } | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
| } | } | ||||||
| @@ -25,22 +25,33 @@ | |||||||
|  * Mercurial utils. |  * Mercurial utils. | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| class IDF_Scm_Mercurial | class IDF_Scm_Mercurial extends IDF_Scm | ||||||
| { | { | ||||||
|     public $repo = ''; |     public function __construct($repo, $project=null) | ||||||
|      |  | ||||||
|     public function __construct($repo) |  | ||||||
|     { |     { | ||||||
|         $this->repo = $repo; |         $this->repo = $repo; | ||||||
|  |         $this->project = $project; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public function getRepositorySize() | ||||||
|  |     { | ||||||
|  |         $cmd = Pluf::f('idf_exec_cmd_prefix', '').'du -sk ' | ||||||
|  |             .escapeshellarg($this->repo); | ||||||
|  |         $out = split(' ', shell_exec($cmd), 2); | ||||||
|  |         return (int) $out[0]*1024; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public static function factory($project) | ||||||
|  |     { | ||||||
|  |         $rep = sprintf(Pluf::f('mercurial_repositories'), $project->shortname); | ||||||
|  |         return new IDF_Scm_Mercurial($rep, $project); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public function isAvailable() | ||||||
|  |     { | ||||||
|  |         return true; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Given the string describing the author from the log find the |  | ||||||
|      * author in the database. |  | ||||||
|      * |  | ||||||
|      * @param string Author |  | ||||||
|      * @return mixed Pluf_User or null |  | ||||||
|      */ |  | ||||||
|     public function findAuthor($author) |     public function findAuthor($author) | ||||||
|     { |     { | ||||||
|         // We extract the email. |         // We extract the email. | ||||||
| @@ -53,27 +64,29 @@ class IDF_Scm_Mercurial | |||||||
|         return ($users->count() > 0) ? $users[0] : null; |         return ($users->count() > 0) ? $users[0] : null; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     public function getMainBranch() | ||||||
|      * Returns the URL of the git daemon. |     { | ||||||
|      * |         return 'tip'; | ||||||
|      * @param IDF_Project |     } | ||||||
|      * @return string URL |  | ||||||
|      */ |     public static function getAnonymousAccessUrl($project) | ||||||
|     public static function getRemoteAccessUrl($project) |  | ||||||
|     { |     { | ||||||
|         return sprintf(Pluf::f('mercurial_remote_url'), $project->shortname); |         return sprintf(Pluf::f('mercurial_remote_url'), $project->shortname); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     public static function getAuthAccessUrl($project, $user) | ||||||
|      * Returns this object correctly initialized for the project. |  | ||||||
|      * |  | ||||||
|      * @param IDF_Project |  | ||||||
|      * @return IDF_Scm_Git |  | ||||||
|      */ |  | ||||||
|     public static function factory($project) |  | ||||||
|     { |     { | ||||||
|         $rep = sprintf(Pluf::f('mercurial_repositories'), $project->shortname); |         return sprintf(Pluf::f('mercurial_remote_url'), $project->shortname); | ||||||
|         return new IDF_Scm_Mercurial($rep); |     } | ||||||
|  |  | ||||||
|  |     public function isValidRevision($rev) | ||||||
|  |     { | ||||||
|  |         $cmd = sprintf(Pluf::f('hg_path', 'hg').' log -R %s -r %s', | ||||||
|  |                        escapeshellarg($this->repo), | ||||||
|  |                        escapeshellarg($rev)); | ||||||
|  |         $cmd = Pluf::f('idf_exec_cmd_prefix', '').$cmd; | ||||||
|  |         exec($cmd, $out, $ret); | ||||||
|  |         return ($ret == 0); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
| @@ -90,24 +103,15 @@ class IDF_Scm_Mercurial | |||||||
|                        escapeshellarg($hash)); |                        escapeshellarg($hash)); | ||||||
|         $ret = 0;  |         $ret = 0;  | ||||||
|         $out = array(); |         $out = array(); | ||||||
|         IDF_Scm::exec($cmd, $out, $ret); |         $cmd = Pluf::f('idf_exec_cmd_prefix', '').$cmd; | ||||||
|  |         exec($cmd, $out, $ret); | ||||||
|         return ($ret != 0) ? false : 'commit';  |         return ($ret != 0) ? false : 'commit';  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     public function getTree($commit, $folder='/', $branch=null) | ||||||
|      * Given a commit hash returns an array of files in it. |  | ||||||
|      * |  | ||||||
|      * A file is a class with the following properties: |  | ||||||
|      * |  | ||||||
|      * 'perm', 'type', 'size', 'hash', 'file' |  | ||||||
|      * |  | ||||||
|      * @param string Commit ('HEAD') |  | ||||||
|      * @param string Base folder ('') |  | ||||||
|      * @return array  |  | ||||||
|      */ |  | ||||||
|     public function filesAtCommit($commit='tip', $folder='') |  | ||||||
|     { |     { | ||||||
|         // now we grab the info about this commit including its tree. |         // now we grab the info about this commit including its tree. | ||||||
|  |         $folder = ($folder == '/') ? '' : $folder; | ||||||
|         $co = $this->getCommit($commit); |         $co = $this->getCommit($commit); | ||||||
|         if ($folder) { |         if ($folder) { | ||||||
|             // As we are limiting to a given folder, we need to find |             // As we are limiting to a given folder, we need to find | ||||||
| @@ -143,26 +147,24 @@ class IDF_Scm_Mercurial | |||||||
|         $cmd = sprintf($cmd_tmpl, escapeshellarg($this->repo), $tree, ($recurse) ? '' : '');  |         $cmd = sprintf($cmd_tmpl, escapeshellarg($this->repo), $tree, ($recurse) ? '' : '');  | ||||||
|         $out = array(); |         $out = array(); | ||||||
|         $res = array(); |         $res = array(); | ||||||
|         IDF_Scm::exec($cmd, $out); |         $cmd = Pluf::f('idf_exec_cmd_prefix', '').$cmd; | ||||||
|         $out_hack = array(); |         exec($cmd, $out); | ||||||
|         foreach ($out as $line) { |         $tmp_hack = array(); | ||||||
|  |         while (null !== ($line = array_pop($out))) { | ||||||
|             list($hash, $perm, $exec, $file) = preg_split('/ |\t/', $line, 4); |             list($hash, $perm, $exec, $file) = preg_split('/ |\t/', $line, 4); | ||||||
|             $file = trim($file); |             $file = trim($file); | ||||||
|             $dir = explode('/', $file, -1); |             $dir = explode('/', $file, -1); | ||||||
|             $tmp = ''; |             $tmp = ''; | ||||||
|             for ($i=0; $i < count($dir); $i++) { |             for ($i=0, $n=count($dir); $i<$n; $i++) { | ||||||
|                 if ($i > 0) { |                 if ($i > 0) { | ||||||
|                     $tmp .= '/'; |                     $tmp .= '/'; | ||||||
|                 } |                 } | ||||||
|                 $tmp .= $dir[$i]; |                 $tmp .= $dir[$i]; | ||||||
|                 if (!in_array("empty\t000\t\t$tmp/", $out_hack)) |                 if (!isset($tmp_hack["empty\t000\t\t$tmp/"])) { | ||||||
|                     $out_hack[] = "empty\t000\t\t$tmp/"; |                     $out[] = "empty\t000\t\t$tmp/"; | ||||||
|  |                     $tmp_hack["empty\t000\t\t$tmp/"] = 1; | ||||||
|                 } |                 } | ||||||
|             $out_hack[] = "$hash\t$perm\t$exec\t$file"; |  | ||||||
|             } |             } | ||||||
|         foreach ($out_hack as $line) { |  | ||||||
|             list($hash, $perm, $exec, $file) = preg_split('/ |\t/', $line, 4); |  | ||||||
|             $file = trim($file); |  | ||||||
|             if (preg_match('/^(.*)\/$/', $file, $match)) { |             if (preg_match('/^(.*)\/$/', $file, $match)) { | ||||||
|                 $type = 'tree'; |                 $type = 'tree'; | ||||||
|                 $file = $match[1]; |                 $file = $match[1]; | ||||||
| @@ -187,40 +189,38 @@ class IDF_Scm_Mercurial | |||||||
|         return $res; |         return $res; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     public function getPathInfo($totest, $commit='tip') | ||||||
|      * Get the file info. |  | ||||||
|      * |  | ||||||
|      * @param string Commit ('HEAD') |  | ||||||
|      * @return false Information |  | ||||||
|      */ |  | ||||||
|     public function getFileInfo($totest, $commit='tip') |  | ||||||
|     { |     { | ||||||
|         $cmd_tmpl = Pluf::f('hg_path', 'hg').' manifest -R %s --debug -r %s'; |         $cmd_tmpl = Pluf::f('hg_path', 'hg').' manifest -R %s --debug -r %s'; | ||||||
|         $cmd = sprintf($cmd_tmpl, escapeshellarg($this->repo), $commit);  |         $cmd = sprintf($cmd_tmpl, escapeshellarg($this->repo), $commit);  | ||||||
|         $out = array(); |         $out = array(); | ||||||
|         $res = array(); |         $cmd = Pluf::f('idf_exec_cmd_prefix', '').$cmd; | ||||||
|         IDF_Scm::exec($cmd, $out); |         exec($cmd, $out); | ||||||
|         $out_hack = array(); |         $tmp_hack = array(); | ||||||
|         foreach ($out as $line) { |         while (null !== ($line = array_pop($out))) { | ||||||
|             list($hash, $perm, $exec, $file) = preg_split('/ |\t/', $line, 4); |             list($hash, $perm, $exec, $file) = preg_split('/ |\t/', $line, 4); | ||||||
|             $file = trim($file); |             $file = trim($file); | ||||||
|             $dir = explode('/', $file, -1); |             $dir = explode('/', $file, -1); | ||||||
|             $tmp = ''; |             $tmp = ''; | ||||||
|             for ($i=0; $i < count($dir); $i++) { |             for ($i=0, $n=count($dir); $i<$n; $i++) { | ||||||
|                 if ($i > 0) { |                 if ($i > 0) { | ||||||
|                     $tmp .= '/'; |                     $tmp .= '/'; | ||||||
|                 } |                 } | ||||||
|                 $tmp .= $dir[$i]; |                 $tmp .= $dir[$i]; | ||||||
|                 if (!in_array("empty\t000\t\t$tmp/", $out_hack)) { |                 if ($tmp == $totest) { | ||||||
|                     $out_hack[] = "emtpy\t000\t\t$tmp/"; |                     $pathinfo = pathinfo($totest); | ||||||
|  |                     return (object) array('perm' => '000', 'type' => 'tree',  | ||||||
|  |                                           'hash' => $hash,  | ||||||
|  |                                           'fullpath' => $totest, | ||||||
|  |                                           'file' => $pathinfo['basename'], | ||||||
|  |                                           'commit' => $commit | ||||||
|  |                                           ); | ||||||
|  |                 } | ||||||
|  |                 if (!isset($tmp_hack["empty\t000\t\t$tmp/"])) { | ||||||
|  |                     $out[] = "empty\t000\t\t$tmp/"; | ||||||
|  |                     $tmp_hack["empty\t000\t\t$tmp/"] = 1; | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             $out_hack[] = "$hash\t$perm\t$exec\t$file"; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         foreach ($out_hack as $line) { |  | ||||||
|             list($hash, $perm, $exec, $file) = preg_split('/ |\t/', $line, 4); |  | ||||||
|             $file = trim ($file); |  | ||||||
|             if (preg_match('/^(.*)\/$/', $file, $match)) { |             if (preg_match('/^(.*)\/$/', $file, $match)) { | ||||||
|                 $type = 'tree'; |                 $type = 'tree'; | ||||||
|                 $file = $match[1]; |                 $file = $match[1]; | ||||||
| @@ -228,30 +228,26 @@ class IDF_Scm_Mercurial | |||||||
|                 $type = 'blob'; |                 $type = 'blob'; | ||||||
|             } |             } | ||||||
|             if ($totest == $file) { |             if ($totest == $file) { | ||||||
|  |                 $pathinfo = pathinfo($totest); | ||||||
|                 return (object) array('perm' => $perm, 'type' => $type,  |                 return (object) array('perm' => $perm, 'type' => $type,  | ||||||
|                                       'hash' => $hash,  |                                       'hash' => $hash,  | ||||||
|                                       'file' => $file, |                                       'fullpath' => $totest, | ||||||
|  |                                       'file' => $pathinfo['basename'], | ||||||
|                                       'commit' => $commit |                                       'commit' => $commit | ||||||
|                                       ); |                                       ); | ||||||
|  |  | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
|        |        | ||||||
|     /** |     public function getFile($def, $cmd_only=false) | ||||||
|      * Get a blob. |  | ||||||
|      * |  | ||||||
|      * @param string request_file_info |  | ||||||
|      * @param null to be svn client compatible |  | ||||||
|      * @return string Raw blob |  | ||||||
|      */ |  | ||||||
|     public function getBlob($request_file_info, $dummy=null) |  | ||||||
|     { |     { | ||||||
|         return IDF_Scm::shell_exec(sprintf(Pluf::f('hg_path', 'hg').' cat -R %s -r %s %s', |         $cmd = sprintf(Pluf::f('hg_path', 'hg').' cat -R %s -r %s %s', | ||||||
|                        escapeshellarg($this->repo),  |                        escapeshellarg($this->repo),  | ||||||
|                                            $dummy, |                        escapeshellarg($def->commit),  | ||||||
|                                            escapeshellarg($this->repo . '/' . $request_file_info->file))); |                        escapeshellarg($this->repo.'/'.$def->file)); | ||||||
|  |         $cmd = Pluf::f('idf_exec_cmd_prefix', '').$cmd; | ||||||
|  |         return ($cmd_only) ? $cmd : shell_exec($cmd); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
| @@ -261,17 +257,28 @@ class IDF_Scm_Mercurial | |||||||
|      */ |      */ | ||||||
|     public function getBranches() |     public function getBranches() | ||||||
|     { |     { | ||||||
|  |         if (isset($this->cache['branches'])) { | ||||||
|  |             return $this->cache['branches']; | ||||||
|  |         } | ||||||
|         $out = array(); |         $out = array(); | ||||||
|         IDF_Scm::exec(sprintf(Pluf::f('hg_path', 'hg').' branches -R %s',  |         $cmd = Pluf::f('idf_exec_cmd_prefix', '').$cmd; | ||||||
|  |         exec(sprintf(Pluf::f('hg_path', 'hg').' branches -R %s',  | ||||||
|                               escapeshellarg($this->repo)), $out); |                               escapeshellarg($this->repo)), $out); | ||||||
|         $res = array(); |         $res = array(); | ||||||
|         foreach ($out as $b) { |         foreach ($out as $b) { | ||||||
|             preg_match('/(\S+).*\S+:(\S+)/', $b, $match); |             preg_match('/(\S+).*\S+:(\S+)/', $b, $match); | ||||||
|             $res[] = $match[1]; |             $res[$match[1]] = ''; | ||||||
|         } |         } | ||||||
|  |         $this->cache['branches'] = $res; | ||||||
|         return $res; |         return $res; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     public function inBranches($commit, $path) | ||||||
|  |     { | ||||||
|  |         return (in_array($commit, array_keys($this->getBranches())))  | ||||||
|  |                 ? array($commit) : array(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Get commit details. |      * Get commit details. | ||||||
|      * |      * | ||||||
| @@ -286,7 +293,8 @@ class IDF_Scm_Mercurial | |||||||
|         $cmd = sprintf($tmpl,  |         $cmd = sprintf($tmpl,  | ||||||
|                        escapeshellarg($commit), escapeshellarg($this->repo)); |                        escapeshellarg($commit), escapeshellarg($this->repo)); | ||||||
|         $out = array(); |         $out = array(); | ||||||
|         IDF_Scm::exec($cmd, $out); |         $cmd = Pluf::f('idf_exec_cmd_prefix', '').$cmd; | ||||||
|  |         exec($cmd, $out); | ||||||
|         $log = array(); |         $log = array(); | ||||||
|         $change = array(); |         $change = array(); | ||||||
|         $inchange = false; |         $inchange = false; | ||||||
| @@ -327,7 +335,8 @@ class IDF_Scm_Mercurial | |||||||
|     { |     { | ||||||
|         $cmd = sprintf(Pluf::f('hg_path', 'hg').' log -R %s -l%s ', escapeshellarg($this->repo), $n, $commit); |         $cmd = sprintf(Pluf::f('hg_path', 'hg').' log -R %s -l%s ', escapeshellarg($this->repo), $n, $commit); | ||||||
|         $out = array(); |         $out = array(); | ||||||
|         IDF_Scm::exec($cmd, $out); |         $cmd = Pluf::f('idf_exec_cmd_prefix', '').$cmd; | ||||||
|  |         exec($cmd, $out); | ||||||
|         return self::parseLog($out, 6); |         return self::parseLog($out, 6); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -22,23 +22,44 @@ | |||||||
| # ***** END LICENSE BLOCK ***** */ | # ***** END LICENSE BLOCK ***** */ | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * SVN utils. |  * Subversion backend. | ||||||
|  |  * When a branch is not a branch. | ||||||
|  *  |  *  | ||||||
|  |  * Contrary to most other SCMs, Subversion is using folders to manage | ||||||
|  |  * the branches and so what is either the commit or the branch in | ||||||
|  |  * other SCMs is the revision number with Subversion. So, do not be | ||||||
|  |  * surprised if you have the feeling that the methods are not really | ||||||
|  |  * returning what could be expected from their names. | ||||||
|  */ |  */ | ||||||
| class IDF_Scm_Svn | class IDF_Scm_Svn extends IDF_Scm | ||||||
| { | { | ||||||
|     public $repo = ''; |  | ||||||
|     public $username = ''; |     public $username = ''; | ||||||
|     public $password = ''; |     public $password = ''; | ||||||
|     private $assoc = array('dir' => 'tree', |     private $assoc = array('dir' => 'tree', | ||||||
|                            'file' => 'blob'); |                            'file' => 'blob'); | ||||||
|  |  | ||||||
|  |     public function __construct($repo, $project=null) | ||||||
|     public function __construct($repo, $username='', $password='') |  | ||||||
|     { |     { | ||||||
|         $this->repo = $repo; |         $this->repo = $repo; | ||||||
|         $this->username = $username; |         $this->project = $project; | ||||||
|         $this->password = $password; |         $this->cache['commitmess'] = array(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public function isAvailable() | ||||||
|  |     { | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public function getRepositorySize() | ||||||
|  |     { | ||||||
|  |         if (strpos($this->repo, 'file://') !== 0) { | ||||||
|  |             return -1; | ||||||
|  |         } | ||||||
|  |         $cmd = Pluf::f('idf_exec_cmd_prefix', '').'du -sk ' | ||||||
|  |             .escapeshellarg(substr($this->repo, 7)); | ||||||
|  |         $out = split(' ', shell_exec($cmd), 2); | ||||||
|  |         return (int) $out[0]*1024; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
| @@ -61,7 +82,24 @@ class IDF_Scm_Svn | |||||||
|      * @param IDF_Project |      * @param IDF_Project | ||||||
|      * @return string URL |      * @return string URL | ||||||
|      */ |      */ | ||||||
|     public static function getRemoteAccessUrl($project) |     public static function getAnonymousAccessUrl($project) | ||||||
|  |     { | ||||||
|  |         $conf = $project->getConf(); | ||||||
|  |         if (false !== ($url=$conf->getVal('svn_remote_url', false))  | ||||||
|  |             && !empty($url)) { | ||||||
|  |             // Remote repository | ||||||
|  |             return $url; | ||||||
|  |         } | ||||||
|  |         return sprintf(Pluf::f('svn_remote_url'), $project->shortname); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Returns the URL of the subversion repository. | ||||||
|  |      * | ||||||
|  |      * @param IDF_Project | ||||||
|  |      * @return string URL | ||||||
|  |      */ | ||||||
|  |     public static function getAuthAccessUrl($project, $user) | ||||||
|     { |     { | ||||||
|         $conf = $project->getConf(); |         $conf = $project->getConf(); | ||||||
|         if (false !== ($url=$conf->getVal('svn_remote_url', false))  |         if (false !== ($url=$conf->getVal('svn_remote_url', false))  | ||||||
| @@ -85,15 +123,35 @@ class IDF_Scm_Svn | |||||||
|         if (false !== ($rep=$conf->getVal('svn_remote_url', false))  |         if (false !== ($rep=$conf->getVal('svn_remote_url', false))  | ||||||
|             && !empty($rep)) { |             && !empty($rep)) { | ||||||
|             // Remote repository |             // Remote repository | ||||||
|             return new IDF_Scm_Svn($rep, |             $scm = new IDF_Scm_Svn($rep, $project); | ||||||
|                                    $conf->getVal('svn_username'), |             $scm->username = $conf->getVal('svn_username'); | ||||||
|                                    $conf->getVal('svn_password')); |             $scm->password = $conf->getVal('svn_password'); | ||||||
|  |             return $scm; | ||||||
|         } else { |         } else { | ||||||
|             $rep = sprintf(Pluf::f('svn_repositories'), $project->shortname); |             $rep = sprintf(Pluf::f('svn_repositories'), $project->shortname); | ||||||
|             return new IDF_Scm_Svn($rep); |             return new IDF_Scm_Svn($rep, $project); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Subversion revisions are either a number or 'HEAD'. | ||||||
|  |      */ | ||||||
|  |     public function isValidRevision($rev) | ||||||
|  |     { | ||||||
|  |         if ($rev == 'HEAD') { | ||||||
|  |             return true; | ||||||
|  |         } | ||||||
|  |         $cmd = sprintf(Pluf::f('svn_path', 'svn').' info --username=%s --password=%s %s@%s', | ||||||
|  |                        escapeshellarg($this->username), | ||||||
|  |                        escapeshellarg($this->password), | ||||||
|  |                        escapeshellarg($this->repo), | ||||||
|  |                        escapeshellarg($rev)); | ||||||
|  |         $cmd = Pluf::f('idf_exec_cmd_prefix', '').$cmd; | ||||||
|  |         exec($cmd, $out, $ret); | ||||||
|  |         return (0 == $ret); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Test a given object hash. |      * Test a given object hash. | ||||||
|      * |      * | ||||||
| @@ -113,7 +171,8 @@ class IDF_Scm_Svn | |||||||
|                        escapeshellarg($this->password), |                        escapeshellarg($this->password), | ||||||
|                        escapeshellarg($this->repo.'/'.$path), |                        escapeshellarg($this->repo.'/'.$path), | ||||||
|                        escapeshellarg($rev)); |                        escapeshellarg($rev)); | ||||||
|         $xmlInfo = IDF_Scm::shell_exec($cmd); |         $cmd = Pluf::f('idf_exec_cmd_prefix', '').$cmd; | ||||||
|  |         $xmlInfo = shell_exec($cmd); | ||||||
|  |  | ||||||
|         // If exception is thrown, return false |         // If exception is thrown, return false | ||||||
|         try { |         try { | ||||||
| @@ -132,29 +191,17 @@ class IDF_Scm_Svn | |||||||
|         return 'commit'; |         return 'commit'; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     public function getTree($commit, $folder='/', $branch=null) | ||||||
|     /** |  | ||||||
|      * Given a commit hash returns an array of files in it. |  | ||||||
|      * |  | ||||||
|      * A file is a class with the following properties: |  | ||||||
|      * |  | ||||||
|      * 'perm', 'type', 'size', 'hash', 'file' |  | ||||||
|      * |  | ||||||
|      * @param string Commit ('HEAD') |  | ||||||
|      * @param string Base folder ('') |  | ||||||
|      * @return array |  | ||||||
|      */ |  | ||||||
|     public function filesAtCommit($rev='HEAD', $folder='') |  | ||||||
|     { |     { | ||||||
|         $cmd = sprintf(Pluf::f('svn_path', 'svn').' ls --xml --username=%s --password=%s %s@%s', |         $cmd = sprintf(Pluf::f('svn_path', 'svn').' ls --xml --username=%s --password=%s %s@%s', | ||||||
|                        escapeshellarg($this->username), |                        escapeshellarg($this->username), | ||||||
|                        escapeshellarg($this->password), |                        escapeshellarg($this->password), | ||||||
|                        escapeshellarg($this->repo.'/'.$folder), |                        escapeshellarg($this->repo.'/'.$folder), | ||||||
|                        escapeshellarg($rev)); |                        escapeshellarg($commit)); | ||||||
|         $xmlLs = IDF_Scm::shell_exec($cmd); |         $cmd = Pluf::f('idf_exec_cmd_prefix', '').$cmd; | ||||||
|         $xml = simplexml_load_string($xmlLs); |         $xml = simplexml_load_string(shell_exec($cmd)); | ||||||
|         $res = array(); |         $res = array(); | ||||||
|         $folder = (strlen($folder)) ? $folder.'/' : ''; |         $folder = (strlen($folder) and ($folder != '/')) ? $folder.'/' : ''; | ||||||
|         foreach ($xml->list->entry as $entry) { |         foreach ($xml->list->entry as $entry) { | ||||||
|             $file = array(); |             $file = array(); | ||||||
|             $file['type'] = $this->assoc[(string) $entry['kind']]; |             $file['type'] = $this->assoc[(string) $entry['kind']]; | ||||||
| @@ -163,10 +210,7 @@ class IDF_Scm_Svn | |||||||
|             $file['date'] = gmdate('Y-m-d H:i:s', |             $file['date'] = gmdate('Y-m-d H:i:s', | ||||||
|                                    strtotime((string) $entry->commit->date)); |                                    strtotime((string) $entry->commit->date)); | ||||||
|             $file['rev'] = (string) $entry->commit['revision']; |             $file['rev'] = (string) $entry->commit['revision']; | ||||||
|             // Get commit message |             $file['log'] = $this->getCommitMessage($file['rev']); | ||||||
|             $currentReposFile = $this->repo.'/'.$folder.$file['file']; |  | ||||||
|             $file['log'] = $this->getCommitMessage($currentReposFile, $rev); |  | ||||||
|  |  | ||||||
|             // Get the size if the type is blob |             // Get the size if the type is blob | ||||||
|             if ($file['type'] == 'blob') { |             if ($file['type'] == 'blob') { | ||||||
|                 $file['size'] = (string) $entry->size; |                 $file['size'] = (string) $entry->size; | ||||||
| @@ -175,116 +219,154 @@ class IDF_Scm_Svn | |||||||
|             $file['perm'] = ''; |             $file['perm'] = ''; | ||||||
|             $res[] = (object) $file; |             $res[] = (object) $file; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         return $res; |         return $res; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Get a commit message for given file and revision. |      * Get the commit message of a revision revision. | ||||||
|      * |      * | ||||||
|      * @param string File |  | ||||||
|      * @param string Commit ('HEAD') |      * @param string Commit ('HEAD') | ||||||
|      * |  | ||||||
|      * @return String commit message |      * @return String commit message | ||||||
|      */ |      */ | ||||||
|     private function getCommitMessage($file, $rev='HEAD') |     private function getCommitMessage($rev='HEAD') | ||||||
|     { |     { | ||||||
|  |         if (isset($this->cache['commitmess'][$rev])) { | ||||||
|  |             return $this->cache['commitmess'][$rev]; | ||||||
|  |         } | ||||||
|         $cmd = sprintf(Pluf::f('svn_path', 'svn').' log --xml --limit 1 --username=%s --password=%s %s@%s', |         $cmd = sprintf(Pluf::f('svn_path', 'svn').' log --xml --limit 1 --username=%s --password=%s %s@%s', | ||||||
|                        escapeshellarg($this->username), |                        escapeshellarg($this->username), | ||||||
|                        escapeshellarg($this->password), |                        escapeshellarg($this->password), | ||||||
|                        escapeshellarg($file), |                        escapeshellarg($this->repo), | ||||||
|                        escapeshellarg($rev)); |                        escapeshellarg($rev)); | ||||||
|         $xmlLog = IDF_Scm::shell_exec($cmd); |         $cmd = Pluf::f('idf_exec_cmd_prefix', '').$cmd; | ||||||
|         $xml = simplexml_load_string($xmlLog); |         $xml = simplexml_load_string(shell_exec($cmd)); | ||||||
|         return (string) $xml->logentry->msg; |         $this->cache['commitmess'][$rev] = (string) $xml->logentry->msg; | ||||||
|  |         return $this->cache['commitmess'][$rev]; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     public function getPathInfo($filename, $rev=null) | ||||||
|     /** |  | ||||||
|      * Get the file info. |  | ||||||
|      * |  | ||||||
|      * @param string File |  | ||||||
|      * @param string Commit ('HEAD') |  | ||||||
|      * @return false Information |  | ||||||
|      */ |  | ||||||
|     public function getFileInfo($totest, $rev='HEAD') |  | ||||||
|     { |     { | ||||||
|  |         if ($rev == null) { | ||||||
|  |             $rev = 'HEAD'; | ||||||
|  |         } | ||||||
|         $cmd = sprintf(Pluf::f('svn_path', 'svn').' info --xml --username=%s --password=%s %s@%s', |         $cmd = sprintf(Pluf::f('svn_path', 'svn').' info --xml --username=%s --password=%s %s@%s', | ||||||
|                        escapeshellarg($this->username), |                        escapeshellarg($this->username), | ||||||
|                        escapeshellarg($this->password), |                        escapeshellarg($this->password), | ||||||
|                        escapeshellarg($this->repo.'/'.$totest), |                        escapeshellarg($this->repo.'/'.$filename), | ||||||
|                        escapeshellarg($rev)); |                        escapeshellarg($rev)); | ||||||
|         $xmlInfo = IDF_Scm::shell_exec($cmd); |         $cmd = Pluf::f('idf_exec_cmd_prefix', '').$cmd; | ||||||
|         $xml = simplexml_load_string($xmlInfo); |         $xml = simplexml_load_string(shell_exec($cmd)); | ||||||
|  |         if (!isset($xml->entry)) { | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|         $entry = $xml->entry; |         $entry = $xml->entry; | ||||||
|  |  | ||||||
|         $file = array(); |         $file = array(); | ||||||
|         $file['fullpath'] = $totest; |         $file['fullpath'] = $filename; | ||||||
|         $file['hash'] = (string) $entry->repository->uuid; |         $file['hash'] = (string) $entry->repository->uuid; | ||||||
|         $file['type'] = $this->assoc[(string) $entry['kind']]; |         $file['type'] = $this->assoc[(string) $entry['kind']]; | ||||||
|         $file['file'] = $totest; |         $pathinfo = pathinfo($filename); | ||||||
|         $file['rev'] = (string) $entry->commit['revision']; |         $file['file'] = $pathinfo['basename']; | ||||||
|  |         $file['rev'] = $rev;  | ||||||
|         $file['author'] = (string) $entry->author; |         $file['author'] = (string) $entry->author; | ||||||
|         $file['date'] = gmdate('Y-m-d H:i:s', strtotime((string) $entry->commit->date)); |         $file['date'] = gmdate('Y-m-d H:i:s', strtotime((string) $entry->commit->date)); | ||||||
|         $file['size'] = (string) $entry->size; |         $file['size'] = (string) $entry->size; | ||||||
|         $file['log'] = ''; |         $file['log'] = ''; | ||||||
|  |  | ||||||
|         return (object) $file; |         return (object) $file; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     public function getFile($def, $cmd_only=false) | ||||||
|     /** |  | ||||||
|      * Get a blob. |  | ||||||
|      * |  | ||||||
|      * @param string request_file_info |  | ||||||
|      * @return string Raw blob |  | ||||||
|      */ |  | ||||||
|     public function getBlob($request_file_info, $rev) |  | ||||||
|     { |     { | ||||||
|         $cmd = sprintf(Pluf::f('svn_path', 'svn').' cat --username=%s --password=%s %s@%s', |         $cmd = sprintf(Pluf::f('svn_path', 'svn').' cat --username=%s --password=%s %s@%s', | ||||||
|                        escapeshellarg($this->username), |                        escapeshellarg($this->username), | ||||||
|                        escapeshellarg($this->password), |                        escapeshellarg($this->password), | ||||||
|                        escapeshellarg($this->repo.'/'.$request_file_info->fullpath), |                        escapeshellarg($this->repo.'/'.$def->fullpath), | ||||||
|                        escapeshellarg($rev)); |                        escapeshellarg($def->rev)); | ||||||
|         return IDF_Scm::shell_exec($cmd); |         $cmd = Pluf::f('idf_exec_cmd_prefix', '').$cmd; | ||||||
|  |         return ($cmd_only) ? $cmd : shell_exec($cmd); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Get the branches. |      * Subversion branches are repository based.  | ||||||
|      * |      * | ||||||
|      * @return array Branches. |      * One need to list the folder to know them. | ||||||
|      */ |      */ | ||||||
|     public function getBranches() |     public function getBranches() | ||||||
|     { |     { | ||||||
|         $res = array('HEAD'); |         if (isset($this->cache['branches'])) { | ||||||
|  |             return $this->cache['branches']; | ||||||
|  |         } | ||||||
|  |         $res = array(); | ||||||
|  |         $cmd = sprintf(Pluf::f('svn_path', 'svn').' ls --username=%s --password=%s %s@HEAD', | ||||||
|  |                        escapeshellarg($this->username), | ||||||
|  |                        escapeshellarg($this->password), | ||||||
|  |                        escapeshellarg($this->repo.'/branches')); | ||||||
|  |         $cmd = Pluf::f('idf_exec_cmd_prefix', '').$cmd; | ||||||
|  |         exec($cmd, $out, $ret); | ||||||
|  |         if ($ret == 0) { | ||||||
|  |             foreach ($out as $entry) { | ||||||
|  |                 if (substr(trim($entry), -1) == '/') { | ||||||
|  |                     $branch = substr(trim($entry), 0, -1); | ||||||
|  |                     $res[$branch] = 'branches/'.$branch; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         ksort($res); | ||||||
|  |         $cmd = sprintf(Pluf::f('svn_path', 'svn').' info --username=%s --password=%s %s@HEAD', | ||||||
|  |                        escapeshellarg($this->username), | ||||||
|  |                        escapeshellarg($this->password), | ||||||
|  |                        escapeshellarg($this->repo.'/trunk')); | ||||||
|  |         $cmd = Pluf::f('idf_exec_cmd_prefix', '').$cmd; | ||||||
|  |         exec($cmd, $out, $ret); | ||||||
|  |         if ($ret == 0) { | ||||||
|  |             $res = array('trunk' => 'trunk') + $res; | ||||||
|  |         } | ||||||
|  |         $this->cache['branches'] = $res; | ||||||
|         return $res; |         return $res; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     public function getMainBranch() | ||||||
|  |     { | ||||||
|  |         return 'HEAD'; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public function inBranches($commit, $path) | ||||||
|  |     { | ||||||
|  |         foreach ($this->getBranches() as $branch => $bpath) { | ||||||
|  |             if ($bpath and 0 === strpos($path, $bpath)) { | ||||||
|  |                 return array($branch); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         return array(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Get commit details. |      * Get commit details. | ||||||
|      * |      * | ||||||
|      * @param string Commit ('HEAD') |      * @param string Commit | ||||||
|      * @param bool Get commit diff (false) |      * @param bool Get commit diff (false) | ||||||
|      * @return array Changes |      * @return array Changes | ||||||
|      */ |      */ | ||||||
|     public function getCommit($rev='HEAD', $getdiff=false) |     public function getCommit($commit, $getdiff=false) | ||||||
|     { |     { | ||||||
|  |         if (!$this->isValidRevision($commit)) { | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|         $res = array(); |         $res = array(); | ||||||
|         $cmd = sprintf(Pluf::f('svn_path', 'svn').' log --xml -v --username=%s --password=%s %s@%s', |         $cmd = sprintf(Pluf::f('svn_path', 'svn').' log --xml --limit 1 -v --username=%s --password=%s %s@%s', | ||||||
|                        escapeshellarg($this->username), |                        escapeshellarg($this->username), | ||||||
|                        escapeshellarg($this->password), |                        escapeshellarg($this->password), | ||||||
|                        escapeshellarg($this->repo), |                        escapeshellarg($this->repo), | ||||||
|                        escapeshellarg($rev)); |                        escapeshellarg($commit)); | ||||||
|         $xmlRes = IDF_Scm::shell_exec($cmd); |         $cmd = Pluf::f('idf_exec_cmd_prefix', '').$cmd; | ||||||
|  |         $xmlRes = shell_exec($cmd); | ||||||
|         $xml = simplexml_load_string($xmlRes); |         $xml = simplexml_load_string($xmlRes); | ||||||
|         $res['author'] = (string) $xml->logentry->author; |         $res['author'] = (string) $xml->logentry->author; | ||||||
|         $res['date'] = gmdate('Y-m-d H:i:s', strtotime((string) $xml->logentry->date)); |         $res['date'] = gmdate('Y-m-d H:i:s', strtotime((string) $xml->logentry->date)); | ||||||
|         $res['title'] = (string) $xml->logentry->msg; |         $res['title'] = (string) $xml->logentry->msg; | ||||||
|         $res['commit'] = (string) $xml->logentry['revision']; |         $res['commit'] = (string) $xml->logentry['revision']; | ||||||
|         $res['changes'] = ($getdiff) ? $this->getDiff($rev) : ''; |         $res['changes'] = ($getdiff) ? $this->getDiff($commit) : ''; | ||||||
|         $res['tree'] = ''; |         $res['tree'] = ''; | ||||||
|         return (object) $res; |         return (object) $res; | ||||||
|     } |     } | ||||||
| @@ -306,7 +388,8 @@ class IDF_Scm_Svn | |||||||
|         $cmd = sprintf(Pluf::f('svnlook_path', 'svnlook').' changed -r %s %s', |         $cmd = sprintf(Pluf::f('svnlook_path', 'svnlook').' changed -r %s %s', | ||||||
|                        escapeshellarg($commit), |                        escapeshellarg($commit), | ||||||
|                        escapeshellarg($repo)); |                        escapeshellarg($repo)); | ||||||
|         $out = IDF_Scm::shell_exec($cmd); |         $cmd = Pluf::f('idf_exec_cmd_prefix', '').$cmd; | ||||||
|  |         $out = shell_exec($cmd); | ||||||
|         $lines = preg_split("/\015\012|\015|\012/", $out); |         $lines = preg_split("/\015\012|\015|\012/", $out); | ||||||
|         return (count($lines) > 100); |         return (count($lines) > 100); | ||||||
|     } |     } | ||||||
| @@ -319,60 +402,49 @@ class IDF_Scm_Svn | |||||||
|                        escapeshellarg($this->username), |                        escapeshellarg($this->username), | ||||||
|                        escapeshellarg($this->password), |                        escapeshellarg($this->password), | ||||||
|                        escapeshellarg($this->repo)); |                        escapeshellarg($this->repo)); | ||||||
|         return IDF_Scm::shell_exec($cmd); |         $cmd = Pluf::f('idf_exec_cmd_prefix', '').$cmd; | ||||||
|  |         return shell_exec($cmd); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Get latest changes. |      * Get latest changes. | ||||||
|      * |      * | ||||||
|      * @param string Commit ('HEAD'). |      * @param string Revision or ('HEAD'). | ||||||
|      * @param int Number of changes (10). |      * @param int Number of changes (10). | ||||||
|      * |      * | ||||||
|      * @return array Changes. |      * @return array Changes. | ||||||
|      */ |      */ | ||||||
|     public function getChangeLog($rev='HEAD', $n=10) |     public function getChangeLog($branch=null, $n=10) | ||||||
|     { |     { | ||||||
|  |         if ($branch != 'HEAD' and !preg_match('/^\d+$/', $branch)) { | ||||||
|  |             // we accept only revisions or HEAD | ||||||
|  |             $branch = 'HEAD'; | ||||||
|  |         } | ||||||
|         $res = array(); |         $res = array(); | ||||||
|         $cmd = sprintf(Pluf::f('svn_path', 'svn').' log --xml -v --limit %s --username=%s --password=%s %s@%s', |         $cmd = sprintf(Pluf::f('svn_path', 'svn').' log --xml -v --limit %s --username=%s --password=%s %s@%s', | ||||||
|                        escapeshellarg($n), |                        escapeshellarg($n), | ||||||
|                        escapeshellarg($this->username), |                        escapeshellarg($this->username), | ||||||
|                        escapeshellarg($this->password), |                        escapeshellarg($this->password), | ||||||
|                        escapeshellarg($this->repo), |                        escapeshellarg($this->repo), | ||||||
|                        escapeshellarg($rev)); |                        escapeshellarg($branch)); | ||||||
|         $xmlRes = IDF_Scm::shell_exec($cmd); |         $cmd = Pluf::f('idf_exec_cmd_prefix', '').$cmd; | ||||||
|  |         $xmlRes = shell_exec($cmd); | ||||||
|         $xml = simplexml_load_string($xmlRes); |         $xml = simplexml_load_string($xmlRes); | ||||||
|  |  | ||||||
|         $res = array(); |  | ||||||
|         foreach ($xml->logentry as $entry) { |         foreach ($xml->logentry as $entry) { | ||||||
|             $log = array(); |             $log = array(); | ||||||
|             $log['author'] = (string) $entry->author; |             $log['author'] = (string) $entry->author; | ||||||
|             $log['date'] = gmdate('Y-m-d H:i:s', strtotime((string) $entry->date)); |             $log['date'] = gmdate('Y-m-d H:i:s', strtotime((string) $entry->date)); | ||||||
|             $log['title'] = (string) $entry->msg; |             $split = split("[\n\r]", (string) $entry->msg, 2); | ||||||
|  |             $log['title'] = $split[0]; | ||||||
|             $log['commit'] = (string) $entry['revision']; |             $log['commit'] = (string) $entry['revision']; | ||||||
|             $log['full_message'] = ''; |             $log['full_message'] = (isset($split[1])) ? trim($split[1]) : ''; | ||||||
|  |  | ||||||
|             $res[] = (object) $log; |             $res[] = (object) $log; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         return $res; |         return $res; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Generate the command to create a zip archive at a given commit. |  | ||||||
|      * Unsupported feature in subversion |  | ||||||
|      * |  | ||||||
|      * @param string dummy |  | ||||||
|      * @param string dummy |  | ||||||
|      * @return Exception |  | ||||||
|      */ |  | ||||||
|     public function getArchiveCommand($commit, $prefix='git-repo-dump/') |  | ||||||
|     { |  | ||||||
|         throw new Exception('Unsupported feature.'); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Get additionnals properties on path and revision |      * Get additionnals properties on path and revision | ||||||
|      * |      * | ||||||
| @@ -388,7 +460,8 @@ class IDF_Scm_Svn | |||||||
|                        escapeshellarg($this->password), |                        escapeshellarg($this->password), | ||||||
|                        escapeshellarg($this->repo.'/'.$path), |                        escapeshellarg($this->repo.'/'.$path), | ||||||
|                        escapeshellarg($rev)); |                        escapeshellarg($rev)); | ||||||
|         $xmlProps = IDF_Scm::shell_exec($cmd); |         $cmd = Pluf::f('idf_exec_cmd_prefix', '').$cmd; | ||||||
|  |         $xmlProps = shell_exec($cmd); | ||||||
|         $props = simplexml_load_string($xmlProps); |         $props = simplexml_load_string($xmlProps); | ||||||
|  |  | ||||||
|         // No properties, returns an empty array |         // No properties, returns an empty array | ||||||
| @@ -423,7 +496,8 @@ class IDF_Scm_Svn | |||||||
|                        escapeshellarg($this->password), |                        escapeshellarg($this->password), | ||||||
|                        escapeshellarg($this->repo.'/'.$path), |                        escapeshellarg($this->repo.'/'.$path), | ||||||
|                        escapeshellarg($rev)); |                        escapeshellarg($rev)); | ||||||
|         $xmlProp = IDF_Scm::shell_exec($cmd); |         $cmd = Pluf::f('idf_exec_cmd_prefix', '').$cmd; | ||||||
|  |         $xmlProp = shell_exec($cmd); | ||||||
|         $prop = simplexml_load_string($xmlProp); |         $prop = simplexml_load_string($xmlProp); | ||||||
|  |  | ||||||
|         return (string) $prop->target->property; |         return (string) $prop->target->property; | ||||||
| @@ -445,7 +519,8 @@ class IDF_Scm_Svn | |||||||
|                        escapeshellarg($this->password), |                        escapeshellarg($this->password), | ||||||
|                        escapeshellarg($this->repo), |                        escapeshellarg($this->repo), | ||||||
|                        escapeshellarg($rev)); |                        escapeshellarg($rev)); | ||||||
|         $xmlInfo = IDF_Scm::shell_exec($cmd); |         $cmd = Pluf::f('idf_exec_cmd_prefix', '').$cmd; | ||||||
|  |         $xmlInfo = shell_exec($cmd); | ||||||
|  |  | ||||||
|         $xml = simplexml_load_string($xmlInfo); |         $xml = simplexml_load_string($xmlInfo); | ||||||
|         return (string) $xml->entry->commit['revision']; |         return (string) $xml->entry->commit['revision']; | ||||||
|   | |||||||
| @@ -37,22 +37,22 @@ class IDF_Template_IssueComment extends Pluf_Template_Tag | |||||||
|         $this->project = $request->project; |         $this->project = $request->project; | ||||||
|         $this->request = $request; |         $this->request = $request; | ||||||
|         $this->scm = IDF_Scm::get($request->project); |         $this->scm = IDF_Scm::get($request->project); | ||||||
|         if ($wordwrap) $text = wordwrap($text, 69, "\n", true); |  | ||||||
|         if ($esc) $text = Pluf_esc($text); |         if ($esc) $text = Pluf_esc($text); | ||||||
|         if ($autolink) { |         if ($autolink) { | ||||||
|             $text = preg_replace('#([a-z]+://[^\s\(\)]+)#i', |             $text = preg_replace('#([a-z]+://[^\s\(\)]+)#i', | ||||||
|                                  '<a href="\1">\1</a>', $text); |                                  '<a href="\1">\1</a>', $text); | ||||||
|         } |         } | ||||||
|         if ($request->rights['hasIssuesAccess']) { |         if ($request->rights['hasIssuesAccess']) { | ||||||
|             $text = preg_replace_callback('#(issues?|bugs?|tickets?)\s+(\d+)((\s+and|\s+or|,)\s+(\d+)){0,}#im', |             $text = preg_replace_callback('#(issues?|bugs?|tickets?)\s+(\d+)(\#ic\d*){0,1}((\s+and|\s+or|,)\s+(\d+)(\#ic\d*){0,1}){0,}#im', | ||||||
|                                           array($this, 'callbackIssues'), $text); |                                           array($this, 'callbackIssues'), $text); | ||||||
|         } |         } | ||||||
|         if ($request->rights['hasSourceAccess']) { |         if ($request->rights['hasSourceAccess']) { | ||||||
|             $text = preg_replace_callback('#(commit\s+)([0-9a-f]{1,40})#im', |             $text = preg_replace_callback('#(commits?\s+)([0-9a-f]{1,40}(?:(?:\s+and|\s+or|,)\s+[0-9a-f]{1,40})*)\b#i', | ||||||
|                                           array($this, 'callbackCommit'), $text); |                                           array($this, 'callbackCommits'), $text); | ||||||
|             $text = preg_replace_callback('#(src:)([^\s\(\)]+)#im', |             $text = preg_replace_callback('#(src:)([^\s\(\)]+)#im', | ||||||
|                                           array($this, 'callbackSource'), $text); |                                           array($this, 'callbackSource'), $text); | ||||||
|         } |         } | ||||||
|  |         if ($wordwrap) $text = Pluf_Text::wrapHtml($text, 69, "\n"); | ||||||
|         if ($nl2br) $text = nl2br($text); |         if ($nl2br) $text = nl2br($text); | ||||||
|         if ($echo) { |         if ($echo) { | ||||||
|             echo $text; |             echo $text; | ||||||
| @@ -66,10 +66,14 @@ class IDF_Template_IssueComment extends Pluf_Template_Tag | |||||||
|      */ |      */ | ||||||
|     function callbackIssues($m) |     function callbackIssues($m) | ||||||
|     { |     { | ||||||
|         if (count($m) == 3) { |         if (count($m) == 3 || count($m) == 4) { | ||||||
|             $issue = new IDF_Issue($m[2]); |             $issue = new IDF_Issue($m[2]); | ||||||
|             if ($issue->id > 0 and $issue->project == $this->project->id) { |             if ($issue->id > 0 and $issue->project == $this->project->id) { | ||||||
|  |                 if (count($m) == 3) { | ||||||
|                 	return $this->linkIssue($issue, $m[1].' '.$m[2]); |                 	return $this->linkIssue($issue, $m[1].' '.$m[2]); | ||||||
|  |                 } else { | ||||||
|  |                     return $this->linkIssue($issue, $m[1].' '.$m[2], $m[3]); | ||||||
|  |                 } | ||||||
|             } else { |             } else { | ||||||
|                 return $m[0]; // not existing issue. |                 return $m[0]; // not existing issue. | ||||||
|             } |             } | ||||||
| @@ -96,29 +100,55 @@ class IDF_Template_IssueComment extends Pluf_Template_Tag | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     function callbackCommit($m) |      /** | ||||||
|  |       * General call back to convert commits to HTML links. | ||||||
|  |       * | ||||||
|  |       * @param array $m Single regex match. | ||||||
|  |       * @return string Content with converted commits. | ||||||
|  |       */ | ||||||
|  |     function callbackCommits($m) | ||||||
|     { |     { | ||||||
|         if ($this->scm->testHash($m[2]) != 'commit') { |         $keyword = rtrim($m[1]); | ||||||
|  |         if ('commits' === $keyword) { | ||||||
|  |             // Multiple commits like 'commits 6e030e6, a25bfc1 and | ||||||
|  |             // 3c094f8'. | ||||||
|  |             return $m[1].preg_replace_callback('#\b[0-9a-f]{4,40}\b#i', array($this, 'callbackCommit'), $m[2]); | ||||||
|  |         } else if ('commit' === $keyword) { | ||||||
|  |             // Single commit like 'commit 6e030e6'. | ||||||
|  |             return $m[1].call_user_func(array($this, 'callbackCommit'), array($m[2])); | ||||||
|  |         } | ||||||
|         return $m[0]; |         return $m[0]; | ||||||
|     } |     } | ||||||
|         $co = $this->scm->getCommit($m[2]); |  | ||||||
|         return '<a href="'.Pluf_HTTP_URL_urlForView('IDF_Views_Source::commit', array($this->project->shortname, $co->commit)).'">'.$m[1].$m[2].'</a>'; |     /** | ||||||
|  |      * Convert plaintext commit to HTML link. Called from callbackCommits. | ||||||
|  |      * | ||||||
|  |      * Regex callback for {@link IDF_Template_IssueComment::callbackCommits()}. | ||||||
|  |      * | ||||||
|  |      * @param array Single regex match. | ||||||
|  |      * @return string HTML A element with commit. | ||||||
|  |      */ | ||||||
|  |     function callbackCommit($m) | ||||||
|  |     { | ||||||
|  |         $co = $this->scm->getCommit($m[0]); | ||||||
|  |         if (!$co) { | ||||||
|  |             return $m[0]; // not a commit. | ||||||
|  |         } | ||||||
|  |         return '<a href="' | ||||||
|  |             .Pluf_HTTP_URL_urlForView('IDF_Views_Source::commit', array($this->project->shortname, $co->commit)) | ||||||
|  |             .'">'.$m[0].'</a>'; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     function callbackSource($m) |     function callbackSource($m) | ||||||
|     { |     { | ||||||
|         $branches = $this->scm->getBranches(); |         if (!$this->scm->isAvailable()) return $m[0]; | ||||||
|         if (count($branches) == 0) return $m[0]; |  | ||||||
|         $file = $m[2]; |         $file = $m[2]; | ||||||
|         if ('commit' != $this->scm->testHash($branches[0], $file)) { |         $request_file_info = $this->scm->getPathInfo($file); | ||||||
|             return $m[0]; |  | ||||||
|         } |  | ||||||
|         $request_file_info = $this->scm->getFileInfo($file, $branches[0]); |  | ||||||
|         if (!$request_file_info) { |         if (!$request_file_info) { | ||||||
|             return $m[0]; |             return $m[0]; | ||||||
|         } |         } | ||||||
|         if ($request_file_info->type != 'tree') { |         if ($request_file_info->type != 'tree') { | ||||||
|             return $m[1].'<a href="'.Pluf_HTTP_URL_urlForView('IDF_Views_Source::tree', array($this->project->shortname, $branches[0], $file)).'">'.$m[2].'</a>'; |             return $m[1].'<a href="'.Pluf_HTTP_URL_urlForView('IDF_Views_Source::tree', array($this->project->shortname, $this->scm->getMainBranch(), $file)).'">'.$m[2].'</a>'; | ||||||
|         } |         } | ||||||
|         return $m[0]; |         return $m[0]; | ||||||
|     } |     } | ||||||
| @@ -130,10 +160,10 @@ class IDF_Template_IssueComment extends Pluf_Template_Tag | |||||||
|      * @param string Name of the link. |      * @param string Name of the link. | ||||||
|      * @return string Linked issue. |      * @return string Linked issue. | ||||||
|      */ |      */ | ||||||
|     public function linkIssue($issue, $title) |     public function linkIssue($issue, $title, $anchor='') | ||||||
|     { |     { | ||||||
|         $ic = (in_array($issue->status, $this->project->getTagIdsByStatus('closed'))) ? 'issue-c' : 'issue-o'; |         $ic = (in_array($issue->status, $this->project->getTagIdsByStatus('closed'))) ? 'issue-c' : 'issue-o'; | ||||||
|         return '<a href="'.Pluf_HTTP_URL_urlForView('IDF_Views_Issue::view',  |         return '<a href="'.Pluf_HTTP_URL_urlForView('IDF_Views_Issue::view',  | ||||||
|                                                     array($this->project->shortname, $issue->id)).'" class="'.$ic.'" title="'.Pluf_esc($issue->summary).'">'.Pluf_esc($title).'</a>'; |                                                     array($this->project->shortname, $issue->id)).$anchor.'" class="'.$ic.'" title="'.Pluf_esc($issue->summary).'">'.Pluf_esc($title).'</a>'; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -91,6 +91,7 @@ class IDF_Template_MarkdownPrefilter extends Pluf_Text_HTML_Filter | |||||||
|  |  | ||||||
|     public $allowed = array( |     public $allowed = array( | ||||||
|                             'a' => array('href', 'title', 'rel'), |                             'a' => array('href', 'title', 'rel'), | ||||||
|  |                             'abbr' => array('title'), | ||||||
|                             'address' => array(), |                             'address' => array(), | ||||||
|                             'b' => array(), |                             'b' => array(), | ||||||
|                             'blockquote' => array(), |                             'blockquote' => array(), | ||||||
| @@ -102,9 +103,12 @@ class IDF_Template_MarkdownPrefilter extends Pluf_Text_HTML_Filter | |||||||
|                             'dl' => array(), |                             'dl' => array(), | ||||||
|                             'dt' => array(), |                             'dt' => array(), | ||||||
|                             'em' => array(), |                             'em' => array(), | ||||||
|                             'h1' => array(), |                             'h1' => array('id'), | ||||||
|                             'h2' => array(), |                             'h2' => array('id'), | ||||||
|                             'h3' => array(), |                             'h3' => array('id'), | ||||||
|  |                             'h4' => array('id'), | ||||||
|  |                             'h5' => array('id'), | ||||||
|  |                             'h6' => array('id'), | ||||||
|                             'hr' => array(), |                             'hr' => array(), | ||||||
|                             'i' => array(), |                             'i' => array(), | ||||||
|                             'img' => array('src', 'class', 'alt', 'height', 'width', 'style'), |                             'img' => array('src', 'class', 'alt', 'height', 'width', 'style'), | ||||||
|   | |||||||
| @@ -39,4 +39,23 @@ class IDF_Tests_TestGit extends UnitTestCase | |||||||
|         $this->assertEqual('Fixed the middleware to correctly return a 404 error if the project is', $log[0]->title); |         $this->assertEqual('Fixed the middleware to correctly return a 404 error if the project is', $log[0]->title); | ||||||
|  |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * parse a log encoded in iso 8859-1 | ||||||
|  |      */ | ||||||
|  |     public function testParseIsoLog() | ||||||
|  |     { | ||||||
|  |         $log_lines = preg_split("/\015\012|\015|\012/", file_get_contents(dirname(__FILE__).'/data/git-log-iso-8859-1.txt')); | ||||||
|  |         $log = IDF_Scm_Git::parseLog($log_lines); | ||||||
|  |         $titles = array( | ||||||
|  |                         'Quick Profiler entfernt', | ||||||
|  |                         'Anwendungsmenu Divider eingefügt', | ||||||
|  |                         'Anwendungen aufäumen' | ||||||
|  |                         ); | ||||||
|  |         foreach ($log as $change) { | ||||||
|  |             $this->assertEqual(array_shift($titles), | ||||||
|  |                                IDF_Commit::toUTF8($change->title)); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |     } | ||||||
| } | } | ||||||
							
								
								
									
										19
									
								
								src/IDF/Tests/data/git-log-iso-8859-1.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								src/IDF/Tests/data/git-log-iso-8859-1.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | |||||||
|  | commit 11531a9dbc64a65150f2f38fbea7cef9d478a123 | ||||||
|  | Author: unknown <a@(none)> | ||||||
|  | Date:   Fri Jul 3 01:44:11 2009 +0200 | ||||||
|  |  | ||||||
|  |     Quick Profiler entfernt | ||||||
|  |  | ||||||
|  | commit 11531a9dbc64a65150f2f38fbea7cef9d478a123 | ||||||
|  | Author: unknown <a@(none)> | ||||||
|  | Date:   Wed Jul 1 15:51:22 2009 +0200 | ||||||
|  |  | ||||||
|  |     Anwendungsmenu Divider eingef<65>gt | ||||||
|  |  | ||||||
|  | commit 11531a9dbc64a65150f2f38fbea7cef9d478a123 | ||||||
|  | Author: unknown <a@(none)> | ||||||
|  | Date:   Wed Jul 1 15:05:41 2009 +0200 | ||||||
|  |  | ||||||
|  |     Anwendungen auf<75>umen | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -56,6 +56,12 @@ class IDF_Upload extends Pluf_Model | |||||||
|                                   'size' => 250, |                                   'size' => 250, | ||||||
|                                   'verbose' => __('summary'), |                                   'verbose' => __('summary'), | ||||||
|                                   ), |                                   ), | ||||||
|  |                             'changelog' => | ||||||
|  |                             array( | ||||||
|  |                                   'type' => 'Pluf_DB_Field_Text', | ||||||
|  |                                   'blank' => true, | ||||||
|  |                                   'verbose' => __('changes'), | ||||||
|  |                                   ), | ||||||
|                             'file' => |                             'file' => | ||||||
|                             array( |                             array( | ||||||
|                                   'type' => 'Pluf_DB_Field_File', |                                   'type' => 'Pluf_DB_Field_File', | ||||||
| @@ -160,6 +166,7 @@ class IDF_Upload extends Pluf_Model | |||||||
|     function preDelete() |     function preDelete() | ||||||
|     { |     { | ||||||
|         IDF_Timeline::remove($this); |         IDF_Timeline::remove($this); | ||||||
|  |         @unlink(Pluf::f('upload_path').'/'.$this->project->shortname.'/files/'.$this->file); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
| @@ -182,7 +189,7 @@ class IDF_Upload extends Pluf_Model | |||||||
|         $out .= sprintf(__('<a href="%1$s" title="View download">Download %2$d</a>, %3$s'), $url, $this->id, Pluf_esc($this->summary)).'</td>'; |         $out .= sprintf(__('<a href="%1$s" title="View download">Download %2$d</a>, %3$s'), $url, $this->id, Pluf_esc($this->summary)).'</td>'; | ||||||
|         $out .= '</tr>'; |         $out .= '</tr>'; | ||||||
|         $out .= "\n".'<tr class="extra"><td colspan="2"> |         $out .= "\n".'<tr class="extra"><td colspan="2"> | ||||||
| <div class="helptext right">'.sprintf(__('Addition of <a href="%s">download %d</a>'), $url, $this->id).', '.__('by').' '.$user.'</div></td></tr>';  | <div class="helptext right">'.sprintf(__('Addition of <a href="%s">download %d</a>, by %s'), $url, $this->id, $user).'</div></td></tr>';  | ||||||
|         return Pluf_Template::markSafe($out); |         return Pluf_Template::markSafe($out); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -64,9 +64,11 @@ class IDF_Views_Admin | |||||||
|         $list_display = array( |         $list_display = array( | ||||||
|              'shortname' => __('Short Name'), |              'shortname' => __('Short Name'), | ||||||
|              'name' => __('Name'), |              'name' => __('Name'), | ||||||
|  |              array('id', 'IDF_Views_Admin_projectSize', __('Repository Size')), | ||||||
|                               ); |                               ); | ||||||
|         $pag->configure($list_display, array(),  |         $pag->configure($list_display, array(),  | ||||||
|                         array('shortname')); |                         array('shortname')); | ||||||
|  |         $pag->extra_classes = array('', '', 'right'); | ||||||
|         $pag->items_per_page = 25; |         $pag->items_per_page = 25; | ||||||
|         $pag->no_results_text = __('No projects were found.'); |         $pag->no_results_text = __('No projects were found.'); | ||||||
|         $pag->setFromRequest($request); |         $pag->setFromRequest($request); | ||||||
| @@ -74,6 +76,7 @@ class IDF_Views_Admin | |||||||
|                                                array( |                                                array( | ||||||
|                                                      'page_title' => $title, |                                                      'page_title' => $title, | ||||||
|                                                      'projects' => $pag, |                                                      'projects' => $pag, | ||||||
|  |                                                      'size' => IDF_Views_Admin_getForgeSize(), | ||||||
|                                                      ), |                                                      ), | ||||||
|                                                $request); |                                                $request); | ||||||
|     } |     } | ||||||
| @@ -284,3 +287,88 @@ function IDF_Views_Admin_bool($field, $item) | |||||||
|     $text = ($item->$field) ? __('Yes') : __('No'); |     $text = ($item->$field) ? __('Yes') : __('No'); | ||||||
|     return sprintf('<img src="'.Pluf::f('url_media').'/idf/img/%s.png" alt="%s" /> ', $img, $text); |     return sprintf('<img src="'.Pluf::f('url_media').'/idf/img/%s.png" alt="%s" /> ', $img, $text); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Display the size of the project. | ||||||
|  |  * | ||||||
|  |  * @param string Field  | ||||||
|  |  * @param IDF_Project | ||||||
|  |  * @return string | ||||||
|  |  */ | ||||||
|  | function IDF_Views_Admin_projectSize($field, $project) | ||||||
|  | { | ||||||
|  |     $size = $project->getRepositorySize(); | ||||||
|  |     if ($size == -1) { | ||||||
|  |         return ''; | ||||||
|  |     } | ||||||
|  |     return Pluf_Utils::prettySize($size); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Get a forge size. | ||||||
|  |  * | ||||||
|  |  * @return array Associative array with the size of each element | ||||||
|  |  */ | ||||||
|  | function IDF_Views_Admin_getForgeSize() | ||||||
|  | { | ||||||
|  |     $res = array(); | ||||||
|  |     $res['repositories'] = 0; | ||||||
|  |     foreach (Pluf::factory('IDF_Project')->getList() as $prj) { | ||||||
|  |         $size = $prj->getRepositorySize(); | ||||||
|  |         if ($size != -1) { | ||||||
|  |             $res['repositories'] += $size; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     $cmd = Pluf::f('idf_exec_cmd_prefix', '').'du -sk ' | ||||||
|  |         .escapeshellarg(Pluf::f('upload_path')); | ||||||
|  |     $out = split(' ', shell_exec($cmd), 2); | ||||||
|  |     $res['downloads'] = $out[0]*1024; | ||||||
|  |     $cmd = Pluf::f('idf_exec_cmd_prefix', '').'du -sk ' | ||||||
|  |         .escapeshellarg(Pluf::f('upload_issue_path')); | ||||||
|  |     $out = split(' ', shell_exec($cmd), 2); | ||||||
|  |     $res['attachments'] = $out[0]*1024; | ||||||
|  |     $res['database'] = IDF_Views_Admin_getForgeDbSize(); | ||||||
|  |     $res['total'] = $res['repositories'] + $res['downloads'] + $res['attachments'] + $res['database']; | ||||||
|  |     return $res; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Get the database size as given by the database. | ||||||
|  |  * | ||||||
|  |  * @return int Database size | ||||||
|  |  */ | ||||||
|  | function IDF_Views_Admin_getForgeDbSize() | ||||||
|  | { | ||||||
|  |     $db = Pluf::db(); | ||||||
|  |     if (Pluf::f('db_engine') == 'SQLite') { | ||||||
|  |         return filesize(Pluf::f('db_database')); | ||||||
|  |     } | ||||||
|  |     switch (Pluf::f('db_engine')) { | ||||||
|  |     case 'PostgreSQL': | ||||||
|  |         $sql = 'SELECT relname, pg_total_relation_size(relname) AS size FROM pg_class AS pgc, pg_namespace AS pgn  | ||||||
|  |      WHERE pg_table_is_visible(pgc.oid) IS TRUE AND relkind = \'r\' | ||||||
|  |      AND pgc.relnamespace = pgn.oid | ||||||
|  |      AND pgn.nspname NOT IN (\'information_schema\', \'pg_catalog\')'; | ||||||
|  |         break; | ||||||
|  |     case 'MySQL': | ||||||
|  |     default: | ||||||
|  |         $sql = 'SHOW TABLE STATUS FROM '.Pluf::f('db_database'); | ||||||
|  |         break; | ||||||
|  |     } | ||||||
|  |     $rs = $db->select($sql); | ||||||
|  |     $total = 0; | ||||||
|  |     switch (Pluf::f('db_engine')) { | ||||||
|  |     case 'PostgreSQL': | ||||||
|  |         foreach ($rs as $table) { | ||||||
|  |             $total += $table['size']; | ||||||
|  |         } | ||||||
|  |         break; | ||||||
|  |     case 'MySQL': | ||||||
|  |     default: | ||||||
|  |         foreach ($rs as $table) { | ||||||
|  |             $total += $table['Data_length'] + $table['Index_length']; | ||||||
|  |         } | ||||||
|  |         break; | ||||||
|  |     } | ||||||
|  |     return $total; | ||||||
|  | } | ||||||
|   | |||||||
| @@ -226,7 +226,7 @@ class IDF_Views_Download | |||||||
|         $conf = new IDF_Conf(); |         $conf = new IDF_Conf(); | ||||||
|         $conf->setProject($project); |         $conf->setProject($project); | ||||||
|         $st = preg_split("/\015\012|\015|\012/",  |         $st = preg_split("/\015\012|\015|\012/",  | ||||||
|                          $conf->getVal('labels_downloads_predefined', IDF_Form_UploadConf::init_predefined), -1, PREG_SPLIT_NO_EMPTY); |                          $conf->getVal('labels_download_predefined', IDF_Form_UploadConf::init_predefined), -1, PREG_SPLIT_NO_EMPTY); | ||||||
|         $auto = ''; |         $auto = ''; | ||||||
|         foreach ($st as $s) { |         foreach ($st as $s) { | ||||||
|             $v = ''; |             $v = ''; | ||||||
| @@ -298,7 +298,7 @@ class IDF_Views_Download | |||||||
|      */ |      */ | ||||||
|     public static function getDownloadTags($project) |     public static function getDownloadTags($project) | ||||||
|     { |     { | ||||||
|         return $project->getTagsFromConfig('labels_downloads_predefined', |         return $project->getTagsFromConfig('labels_download_predefined', | ||||||
|                                            IDF_Form_UploadConf::init_predefined); |                                            IDF_Form_UploadConf::init_predefined); | ||||||
|  |  | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -55,6 +55,7 @@ class IDF_Views_Issue | |||||||
|         $pag->action = array('IDF_Views_Issue::index', array($prj->shortname)); |         $pag->action = array('IDF_Views_Issue::index', array($prj->shortname)); | ||||||
|         $pag->sort_order = array('modif_dtime', 'ASC'); // will be reverted |         $pag->sort_order = array('modif_dtime', 'ASC'); // will be reverted | ||||||
|         $pag->sort_reverse_order = array('modif_dtime'); |         $pag->sort_reverse_order = array('modif_dtime'); | ||||||
|  |         $pag->sort_link_title = true; | ||||||
|         $pag->extra_classes = array('a-c', '', 'a-c', ''); |         $pag->extra_classes = array('a-c', '', 'a-c', ''); | ||||||
|         $list_display = array( |         $list_display = array( | ||||||
|              'id' => __('Id'), |              'id' => __('Id'), | ||||||
| @@ -62,7 +63,7 @@ class IDF_Views_Issue | |||||||
|              array('status', 'IDF_Views_Issue_ShowStatus', __('Status')), |              array('status', 'IDF_Views_Issue_ShowStatus', __('Status')), | ||||||
|              array('modif_dtime', 'Pluf_Paginator_DateAgo', __('Last Updated')), |              array('modif_dtime', 'Pluf_Paginator_DateAgo', __('Last Updated')), | ||||||
|                               ); |                               ); | ||||||
|         $pag->configure($list_display, array(), array('status', 'modif_dtime')); |         $pag->configure($list_display, array(), array('id', 'status', 'modif_dtime')); | ||||||
|         $pag->items_per_page = 10; |         $pag->items_per_page = 10; | ||||||
|         $pag->no_results_text = __('No issues were found.'); |         $pag->no_results_text = __('No issues were found.'); | ||||||
|         $pag->setFromRequest($request); |         $pag->setFromRequest($request); | ||||||
| @@ -131,6 +132,7 @@ class IDF_Views_Issue | |||||||
|         $pag->action = array('IDF_Views_Issue::myIssues', array($prj->shortname, $match[2])); |         $pag->action = array('IDF_Views_Issue::myIssues', array($prj->shortname, $match[2])); | ||||||
|         $pag->sort_order = array('modif_dtime', 'ASC'); // will be reverted |         $pag->sort_order = array('modif_dtime', 'ASC'); // will be reverted | ||||||
|         $pag->sort_reverse_order = array('modif_dtime'); |         $pag->sort_reverse_order = array('modif_dtime'); | ||||||
|  |         $pag->sort_link_title = true; | ||||||
|         $pag->extra_classes = array('a-c', '', 'a-c', ''); |         $pag->extra_classes = array('a-c', '', 'a-c', ''); | ||||||
|         $list_display = array( |         $list_display = array( | ||||||
|              'id' => __('Id'), |              'id' => __('Id'), | ||||||
| @@ -138,7 +140,7 @@ class IDF_Views_Issue | |||||||
|              array('status', 'IDF_Views_Issue_ShowStatus', __('Status')), |              array('status', 'IDF_Views_Issue_ShowStatus', __('Status')), | ||||||
|              array('modif_dtime', 'Pluf_Paginator_DateAgo', __('Last Updated')), |              array('modif_dtime', 'Pluf_Paginator_DateAgo', __('Last Updated')), | ||||||
|                               ); |                               ); | ||||||
|         $pag->configure($list_display, array(), array('status', 'modif_dtime')); |         $pag->configure($list_display, array(), array('id', 'status', 'modif_dtime')); | ||||||
|         $pag->items_per_page = 10; |         $pag->items_per_page = 10; | ||||||
|         $pag->no_results_text = __('No issues were found.'); |         $pag->no_results_text = __('No issues were found.'); | ||||||
|         $pag->setFromRequest($request); |         $pag->setFromRequest($request); | ||||||
| @@ -171,11 +173,8 @@ class IDF_Views_Issue | |||||||
|                                              $params); |                                              $params); | ||||||
|             if (!isset($request->POST['preview']) and $form->isValid()) { |             if (!isset($request->POST['preview']) and $form->isValid()) { | ||||||
|                 $issue = $form->save(); |                 $issue = $form->save(); | ||||||
|                 $url = Pluf_HTTP_URL_urlForView('IDF_Views_Issue::index', |                 $url = Pluf_HTTP_URL_urlForView('IDF_Views_Issue::view', | ||||||
|                                                 array($prj->shortname)); |  | ||||||
|                 $urlissue = Pluf_HTTP_URL_urlForView('IDF_Views_Issue::view', |  | ||||||
|                                                 array($prj->shortname, $issue->id)); |                                                 array($prj->shortname, $issue->id)); | ||||||
|                 $request->user->setMessage(sprintf(__('<a href="%s">Issue %d</a> has been created.'), $urlissue, $issue->id)); |  | ||||||
|                 $to_emails = array(); |                 $to_emails = array(); | ||||||
|                 if (null != $issue->get_owner() and $issue->owner != $issue->submitter) { |                 if (null != $issue->get_owner() and $issue->owner != $issue->submitter) { | ||||||
|                     $to_emails[] = $issue->get_owner()->email; |                     $to_emails[] = $issue->get_owner()->email; | ||||||
| @@ -201,6 +200,7 @@ class IDF_Views_Issue | |||||||
|                     $email->sendMail(); |                     $email->sendMail(); | ||||||
|                 } |                 } | ||||||
|                 if ($api) return $issue; |                 if ($api) return $issue; | ||||||
|  |                 $request->user->setMessage(sprintf(__('<a href="%s">Issue %d</a> has been created.'), $url, $issue->id)); | ||||||
|                 return new Pluf_HTTP_Response_Redirect($url); |                 return new Pluf_HTTP_Response_Redirect($url); | ||||||
|             } |             } | ||||||
|         } else { |         } else { | ||||||
| @@ -291,11 +291,8 @@ class IDF_Views_Issue | |||||||
|                                                  $params); |                                                  $params); | ||||||
|                 if (!isset($request->POST['preview']) && $form->isValid()) { |                 if (!isset($request->POST['preview']) && $form->isValid()) { | ||||||
|                     $issue = $form->save(); |                     $issue = $form->save(); | ||||||
|                     $url = Pluf_HTTP_URL_urlForView('IDF_Views_Issue::index', |                     $comments = $issue->get_comments_list(array('order' => 'id DESC')); | ||||||
|                                                     array($prj->shortname)); |                     $url .= '#ic' . $comments[0]->id; | ||||||
|                     $urlissue = Pluf_HTTP_URL_urlForView('IDF_Views_Issue::view', |  | ||||||
|                                                          array($prj->shortname, $issue->id)); |  | ||||||
|                     $request->user->setMessage(sprintf(__('<a href="%s">Issue %d</a> has been updated.'), $urlissue, $issue->id)); |  | ||||||
|                     // Get the list of interested person + owner + submitter |                     // Get the list of interested person + owner + submitter | ||||||
|                     if (!Pluf_Model_InArray($issue->get_submitter(), $interested)) { |                     if (!Pluf_Model_InArray($issue->get_submitter(), $interested)) { | ||||||
|                         $interested[] = $issue->get_submitter(); |                         $interested[] = $issue->get_submitter(); | ||||||
| @@ -304,15 +301,13 @@ class IDF_Views_Issue | |||||||
|                         !Pluf_Model_InArray($issue->get_owner(), $interested)) { |                         !Pluf_Model_InArray($issue->get_owner(), $interested)) { | ||||||
|                         $interested[] = $issue->get_owner(); |                         $interested[] = $issue->get_owner(); | ||||||
|                     } |                     } | ||||||
|                     $comments = $issue->get_comments_list(array('order' => 'id DESC')); |  | ||||||
|                     $context = new Pluf_Template_Context( |                     $context = new Pluf_Template_Context( | ||||||
|                             array( |                             array( | ||||||
|                                   'issue' => $issue, |                                   'issue' => $issue, | ||||||
|                                   'comments' => $comments, |                                   'comments' => $comments, | ||||||
|                                   'project' => $prj, |                                   'project' => $prj, | ||||||
|                                   'url_base' => Pluf::f('url_base'), |                                   'url_base' => Pluf::f('url_base'), | ||||||
|                                   ) |                                   )); | ||||||
|                                                          ); |  | ||||||
|                     $tmpl = new Pluf_Template('idf/issues/issue-updated-email.txt'); |                     $tmpl = new Pluf_Template('idf/issues/issue-updated-email.txt'); | ||||||
|                     $text_email = $tmpl->render($context); |                     $text_email = $tmpl->render($context); | ||||||
|                     $email = new Pluf_Mail_Batch(Pluf::f('from_email')); |                     $email = new Pluf_Mail_Batch(Pluf::f('from_email')); | ||||||
| @@ -334,6 +329,7 @@ class IDF_Views_Issue | |||||||
|                         $email->sendMail(); |                         $email->sendMail(); | ||||||
|                     } |                     } | ||||||
|                     $email->close(); |                     $email->close(); | ||||||
|  |                     $request->user->setMessage(sprintf(__('<a href="%s">Issue %d</a> has been updated.'), $url, $issue->id)); | ||||||
|                     return new Pluf_HTTP_Response_Redirect($url); |                     return new Pluf_HTTP_Response_Redirect($url); | ||||||
|                 } |                 } | ||||||
|             } else { |             } else { | ||||||
| @@ -436,6 +432,7 @@ class IDF_Views_Issue | |||||||
|         $pag->action = array('IDF_Views_Issue::listStatus', array($prj->shortname, $status)); |         $pag->action = array('IDF_Views_Issue::listStatus', array($prj->shortname, $status)); | ||||||
|         $pag->sort_order = array('modif_dtime', 'ASC'); // will be reverted |         $pag->sort_order = array('modif_dtime', 'ASC'); // will be reverted | ||||||
|         $pag->sort_reverse_order = array('modif_dtime'); |         $pag->sort_reverse_order = array('modif_dtime'); | ||||||
|  |         $pag->sort_link_title = true; | ||||||
|         $pag->extra_classes = array('a-c', '', 'a-c', ''); |         $pag->extra_classes = array('a-c', '', 'a-c', ''); | ||||||
|         $list_display = array( |         $list_display = array( | ||||||
|              'id' => __('Id'), |              'id' => __('Id'), | ||||||
| @@ -443,7 +440,7 @@ class IDF_Views_Issue | |||||||
|              array('status', 'IDF_Views_Issue_ShowStatus', __('Status')), |              array('status', 'IDF_Views_Issue_ShowStatus', __('Status')), | ||||||
|              array('modif_dtime', 'Pluf_Paginator_DateAgo', __('Last Updated')), |              array('modif_dtime', 'Pluf_Paginator_DateAgo', __('Last Updated')), | ||||||
|                               ); |                               ); | ||||||
|         $pag->configure($list_display, array(), array('status', 'modif_dtime')); |         $pag->configure($list_display, array(), array('id', 'status', 'modif_dtime')); | ||||||
|         $pag->items_per_page = 10; |         $pag->items_per_page = 10; | ||||||
|         $pag->no_results_text = __('No issues were found.'); |         $pag->no_results_text = __('No issues were found.'); | ||||||
|         $pag->setFromRequest($request); |         $pag->setFromRequest($request); | ||||||
| @@ -494,6 +491,7 @@ class IDF_Views_Issue | |||||||
|         $pag->action = array('IDF_Views_Issue::listLabel', array($prj->shortname, $tag->id, $status)); |         $pag->action = array('IDF_Views_Issue::listLabel', array($prj->shortname, $tag->id, $status)); | ||||||
|         $pag->sort_order = array('modif_dtime', 'ASC'); // will be reverted |         $pag->sort_order = array('modif_dtime', 'ASC'); // will be reverted | ||||||
|         $pag->sort_reverse_order = array('modif_dtime'); |         $pag->sort_reverse_order = array('modif_dtime'); | ||||||
|  |         $pag->sort_link_title = true; | ||||||
|         $pag->extra_classes = array('a-c', '', 'a-c', ''); |         $pag->extra_classes = array('a-c', '', 'a-c', ''); | ||||||
|         $list_display = array( |         $list_display = array( | ||||||
|              'id' => __('Id'), |              'id' => __('Id'), | ||||||
| @@ -501,7 +499,7 @@ class IDF_Views_Issue | |||||||
|              array('status', 'IDF_Views_Issue_ShowStatus', __('Status')), |              array('status', 'IDF_Views_Issue_ShowStatus', __('Status')), | ||||||
|              array('modif_dtime', 'Pluf_Paginator_DateAgo', __('Last Updated')), |              array('modif_dtime', 'Pluf_Paginator_DateAgo', __('Last Updated')), | ||||||
|                               ); |                               ); | ||||||
|         $pag->configure($list_display, array(), array('status', 'modif_dtime')); |         $pag->configure($list_display, array(), array('id', 'status', 'modif_dtime')); | ||||||
|         $pag->items_per_page = 10; |         $pag->items_per_page = 10; | ||||||
|         $pag->no_results_text = __('No issues were found.'); |         $pag->no_results_text = __('No issues were found.'); | ||||||
|         $pag->setFromRequest($request); |         $pag->setFromRequest($request); | ||||||
|   | |||||||
| @@ -342,7 +342,7 @@ class IDF_Views_Project | |||||||
|                     $conf->setVal($key, $val); |                     $conf->setVal($key, $val); | ||||||
|                 } |                 } | ||||||
|                 $request->user->setMessage(__('The documentation configuration has been saved.')); |                 $request->user->setMessage(__('The documentation configuration has been saved.')); | ||||||
|                 $url = Pluf_HTTP_URL_urlForView('IDF_Views_Project::adminDownloads', |                 $url = Pluf_HTTP_URL_urlForView('IDF_Views_Project::adminWiki', | ||||||
|                                                 array($prj->shortname)); |                                                 array($prj->shortname)); | ||||||
|                 return new Pluf_HTTP_Response_Redirect($url); |                 return new Pluf_HTTP_Response_Redirect($url); | ||||||
|             } |             } | ||||||
| @@ -510,6 +510,7 @@ class IDF_Views_Project | |||||||
|                                                      'remote_svn' => $remote_svn, |                                                      'remote_svn' => $remote_svn, | ||||||
|                                                      'repository_access' => $prj->getRemoteAccessUrl(), |                                                      'repository_access' => $prj->getRemoteAccessUrl(), | ||||||
|                                                      'repository_type' => $repository_type, |                                                      'repository_type' => $repository_type, | ||||||
|  |                                                      'repository_size' => $prj->getRepositorySize(), | ||||||
|                                                      'page_title' => $title, |                                                      'page_title' => $title, | ||||||
|                                                      'form' => $form, |                                                      'form' => $form, | ||||||
|                                                      ), |                                                      ), | ||||||
|   | |||||||
| @@ -207,7 +207,7 @@ class IDF_Views_Review | |||||||
|         $files = array(); |         $files = array(); | ||||||
|         $reviewers = array(); |         $reviewers = array(); | ||||||
|         foreach ($diff->files as $filename => $def) { |         foreach ($diff->files as $filename => $def) { | ||||||
|             $fileinfo = $scm->getFileInfo($filename, $patch->get_commit()->scm_id); |             $fileinfo = $scm->getPathInfo($filename, $patch->get_commit()->scm_id); | ||||||
|             $sql = new Pluf_SQL('cfile=%s', array($filename)); |             $sql = new Pluf_SQL('cfile=%s', array($filename)); | ||||||
|             $cts = $patch->get_filecomments_list(array('filter'=>$sql->gen(), |             $cts = $patch->get_filecomments_list(array('filter'=>$sql->gen(), | ||||||
|                                                 'order'=>'creation_dtime ASC')); |                                                 'order'=>'creation_dtime ASC')); | ||||||
| @@ -215,7 +215,7 @@ class IDF_Views_Review | |||||||
|                 $reviewers[] = $ct->get_submitter(); |                 $reviewers[] = $ct->get_submitter(); | ||||||
|             } |             } | ||||||
|             if (count($def['chunks'])) {  |             if (count($def['chunks'])) {  | ||||||
|                 $orig_file = ($fileinfo) ? $scm->getBlob($fileinfo) : ''; |                 $orig_file = ($fileinfo) ? $scm->getFile($fileinfo) : ''; | ||||||
|                 $files[$filename] = array( |                 $files[$filename] = array( | ||||||
|                                           $diff->fileCompare($orig_file, $def, $filename), |                                           $diff->fileCompare($orig_file, $def, $filename), | ||||||
|                                           $form->f->{md5($filename)}, |                                           $form->f->{md5($filename)}, | ||||||
|   | |||||||
| @@ -27,15 +27,19 @@ Pluf::loadFunction('Pluf_Shortcuts_GetObjectOr404'); | |||||||
| Pluf::loadFunction('Pluf_Shortcuts_GetFormForModel'); | Pluf::loadFunction('Pluf_Shortcuts_GetFormForModel'); | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * View git repository. |  * View SCM repository. | ||||||
|  */ |  */ | ||||||
| class IDF_Views_Source | class IDF_Views_Source | ||||||
| { | { | ||||||
|  |     /** | ||||||
|  |      * Extension supported by the syntax highlighter. | ||||||
|  |      */ | ||||||
|     public static $supportedExtenstions = array('c', 'cc', 'cpp', 'cs', 'css',  |     public static $supportedExtenstions = array('c', 'cc', 'cpp', 'cs', 'css',  | ||||||
|                                                 'cyc', 'java', 'bsh', 'csh',  |                                                 'cyc', 'java', 'bsh', 'csh',  | ||||||
|                                                 'sh', 'cv', 'py', 'perl', 'php', |                                                 'sh', 'cv', 'py', 'perl', 'php', | ||||||
|                                                 'pl', 'pm', 'rb', 'js', 'html', |                                                 'pl', 'pm', 'rb', 'js', 'html', | ||||||
|                                                 'html', 'xhtml', 'xml', 'xsl'); |                                                 'html', 'vala', 'xhtml', 'xml', | ||||||
|  |                                                 'xsl'); | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Display help on how to checkout etc. |      * Display help on how to checkout etc. | ||||||
| @@ -61,9 +65,14 @@ class IDF_Views_Source | |||||||
|         $title = sprintf(__('%1$s %2$s Change Log'), (string) $request->project, |         $title = sprintf(__('%1$s %2$s Change Log'), (string) $request->project, | ||||||
|                          $this->getScmType($request)); |                          $this->getScmType($request)); | ||||||
|         $scm = IDF_Scm::get($request->project); |         $scm = IDF_Scm::get($request->project); | ||||||
|  |         if (!$scm->isAvailable()) { | ||||||
|  |             $url = Pluf_HTTP_URL_urlForView('IDF_Views_Source::help', | ||||||
|  |                                             array($request->project->shortname)); | ||||||
|  |             return new Pluf_HTTP_Response_Redirect($url); | ||||||
|  |         } | ||||||
|         $branches = $scm->getBranches(); |         $branches = $scm->getBranches(); | ||||||
|         $commit = $match[2]; |         $commit = $match[2]; | ||||||
|         if ('commit' != $scm->testHash($commit)) { |         if (!$scm->isValidRevision($commit)) { | ||||||
|             if (count($branches) == 0) { |             if (count($branches) == 0) { | ||||||
|                 // Redirect to the project source help |                 // Redirect to the project source help | ||||||
|                 $url = Pluf_HTTP_URL_urlForView('IDF_Views_Source::help', |                 $url = Pluf_HTTP_URL_urlForView('IDF_Views_Source::help', | ||||||
| @@ -73,7 +82,7 @@ class IDF_Views_Source | |||||||
|             // Redirect to the first branch |             // Redirect to the first branch | ||||||
|             $url = Pluf_HTTP_URL_urlForView('IDF_Views_Source::changeLog', |             $url = Pluf_HTTP_URL_urlForView('IDF_Views_Source::changeLog', | ||||||
|                                             array($request->project->shortname, |                                             array($request->project->shortname, | ||||||
|                                                   $branches[0])); |                                                   $scm->getMainBranch())); | ||||||
|             return new Pluf_HTTP_Response_Redirect($url); |             return new Pluf_HTTP_Response_Redirect($url); | ||||||
|         } |         } | ||||||
|         $changes = $scm->getChangeLog($commit, 25); |         $changes = $scm->getChangeLog($commit, 25); | ||||||
| @@ -84,13 +93,15 @@ class IDF_Views_Source | |||||||
|         } |         } | ||||||
|         $rchanges = new Pluf_Template_ContextVars($rchanges); |         $rchanges = new Pluf_Template_ContextVars($rchanges); | ||||||
|         $scmConf = $request->conf->getVal('scm', 'git'); |         $scmConf = $request->conf->getVal('scm', 'git'); | ||||||
|         return Pluf_Shortcuts_RenderToResponse('idf/source/changelog.html', |         $in_branches = $scm->inBranches($commit, ''); | ||||||
|  |         return Pluf_Shortcuts_RenderToResponse('idf/source/'.$scmConf.'/changelog.html', | ||||||
|                                                array( |                                                array( | ||||||
|                                                      'page_title' => $title, |                                                      'page_title' => $title, | ||||||
|                                                      'title' => $title, |                                                      'title' => $title, | ||||||
|                                                      'changes' => $rchanges, |                                                      'changes' => $rchanges, | ||||||
|                                                      'commit' => $commit, |                                                      'commit' => $commit, | ||||||
|                                                      'branches' => $branches, |                                                      'branches' => $branches, | ||||||
|  |                                                      'tree_in' => $in_branches, | ||||||
|                                                      'scm' => $scmConf, |                                                      'scm' => $scmConf, | ||||||
|                                                      ), |                                                      ), | ||||||
|                                                $request); |                                                $request); | ||||||
| @@ -99,38 +110,33 @@ class IDF_Views_Source | |||||||
|     public $treeBase_precond = array('IDF_Precondition::accessSource'); |     public $treeBase_precond = array('IDF_Precondition::accessSource'); | ||||||
|     public function treeBase($request, $match) |     public function treeBase($request, $match) | ||||||
|     { |     { | ||||||
|         $title = sprintf(__('%1$s %2$s Source Tree'), (string) $request->project, |         $title = sprintf(__('%1$s %2$s Source Tree'), | ||||||
|                          $this->getScmType($request)); |                          $request->project, $this->getScmType($request)); | ||||||
|         $scm = IDF_Scm::get($request->project); |         $scm = IDF_Scm::get($request->project); | ||||||
|         $commit = $match[2]; |         if (!$scm->isAvailable()) { | ||||||
|         $branches = $scm->getBranches(); |  | ||||||
|         if (count($branches) == 0) { |  | ||||||
|             // Redirect to the project home |  | ||||||
|             $url = Pluf_HTTP_URL_urlForView('IDF_Views_Source::help', |             $url = Pluf_HTTP_URL_urlForView('IDF_Views_Source::help', | ||||||
|                                             array($request->project->shortname)); |                                             array($request->project->shortname)); | ||||||
|             return new Pluf_HTTP_Response_Redirect($url); |             return new Pluf_HTTP_Response_Redirect($url); | ||||||
|         } |         } | ||||||
|         if ('commit' != $scm->testHash($commit)) { |         $commit = $match[2]; | ||||||
|             // Redirect to the first branch |         $cobject = $scm->getCommit($commit); | ||||||
|  |         if (!$cobject) { | ||||||
|             $url = Pluf_HTTP_URL_urlForView('IDF_Views_Source::treeBase', |             $url = Pluf_HTTP_URL_urlForView('IDF_Views_Source::treeBase', | ||||||
|                                             array($request->project->shortname, |                                             array($request->project->shortname, | ||||||
|                                                   $branches[0])); |                                                   $scm->getMainBranch())); | ||||||
|             return new Pluf_HTTP_Response_Redirect($url); |             return new Pluf_HTTP_Response_Redirect($url); | ||||||
|         } |         } | ||||||
|  |         $branches = $scm->getBranches(); | ||||||
|  |         $in_branches = $scm->inBranches($commit, ''); | ||||||
|         $cache = Pluf_Cache::factory(); |         $cache = Pluf_Cache::factory(); | ||||||
|         $key = sprintf('Project:%s::IDF_Views_Source::treeBase:%s::', |         $key = sprintf('Project:%s::IDF_Views_Source::treeBase:%s::', | ||||||
|                        $request->project->id, $commit); |                        $request->project->id, $commit); | ||||||
|         if (null === ($res=$cache->get($key))) { |         if (null === ($res=$cache->get($key))) { | ||||||
|             $res = new Pluf_Template_ContextVars($scm->filesAtCommit($commit)); |             $res = new Pluf_Template_ContextVars($scm->getTree($commit)); | ||||||
|             $cache->set($key, $res); |             $cache->set($key, $res); | ||||||
|         } |         } | ||||||
|         $cobject = $scm->getCommit($commit); |  | ||||||
|         $tree_in = in_array($commit, $branches); |  | ||||||
|         $scmConf = $request->conf->getVal('scm', 'git'); |         $scmConf = $request->conf->getVal('scm', 'git'); | ||||||
|         $props = null; |  | ||||||
|         if ($scmConf === 'svn') { |  | ||||||
|         $props = $scm->getProperties($commit); |         $props = $scm->getProperties($commit); | ||||||
|         } |  | ||||||
|         return Pluf_Shortcuts_RenderToResponse('idf/source/'.$scmConf.'/tree.html', |         return Pluf_Shortcuts_RenderToResponse('idf/source/'.$scmConf.'/tree.html', | ||||||
|                                                array( |                                                array( | ||||||
|                                                      'page_title' => $title, |                                                      'page_title' => $title, | ||||||
| @@ -138,7 +144,7 @@ class IDF_Views_Source | |||||||
|                                                      'files' => $res, |                                                      'files' => $res, | ||||||
|                                                      'cobject' => $cobject, |                                                      'cobject' => $cobject, | ||||||
|                                                      'commit' => $commit, |                                                      'commit' => $commit, | ||||||
|                                                      'tree_in' => $tree_in, |                                                      'tree_in' => $in_branches, | ||||||
|                                                      'branches' => $branches, |                                                      'branches' => $branches, | ||||||
|                                                      'props' => $props, |                                                      'props' => $props, | ||||||
|                                                      ), |                                                      ), | ||||||
| @@ -148,15 +154,21 @@ class IDF_Views_Source | |||||||
|     public $tree_precond = array('IDF_Precondition::accessSource'); |     public $tree_precond = array('IDF_Precondition::accessSource'); | ||||||
|     public function tree($request, $match) |     public function tree($request, $match) | ||||||
|     { |     { | ||||||
|         $title = sprintf(__('%1$s %2$s Source Tree'), (string) $request->project, |         $title = sprintf(__('%1$s %2$s Source Tree'),  | ||||||
|                          $this->getScmType($request)); |                          $request->project, $this->getScmType($request)); | ||||||
|         $scm = IDF_Scm::get($request->project); |         $scm = IDF_Scm::get($request->project); | ||||||
|         $branches = $scm->getBranches(); |  | ||||||
|         $commit = $match[2]; |         $commit = $match[2]; | ||||||
|         $request_file = $match[3]; |         $request_file = $match[3]; | ||||||
|  |  | ||||||
|  |         if (!$scm->isAvailable()) { | ||||||
|  |             $url = Pluf_HTTP_URL_urlForView('IDF_Views_Source::help', | ||||||
|  |                                             array($request->project->shortname)); | ||||||
|  |             return new Pluf_HTTP_Response_Redirect($url); | ||||||
|  |         } | ||||||
|  |         $branches = $scm->getBranches(); | ||||||
|         $fburl = Pluf_HTTP_URL_urlForView('IDF_Views_Source::treeBase', |         $fburl = Pluf_HTTP_URL_urlForView('IDF_Views_Source::treeBase', | ||||||
|                                           array($request->project->shortname, |                                           array($request->project->shortname, | ||||||
|                                                 $branches[0])); |                                                 $scm->getMainBranch())); | ||||||
|         if (substr($request_file, -1) == '/') { |         if (substr($request_file, -1) == '/') { | ||||||
|             $request_file = substr($request_file, 0, -1); |             $request_file = substr($request_file, 0, -1); | ||||||
|             $url = Pluf_HTTP_URL_urlForView('IDF_Views_Source::tree', |             $url = Pluf_HTTP_URL_urlForView('IDF_Views_Source::tree', | ||||||
| @@ -164,11 +176,11 @@ class IDF_Views_Source | |||||||
|                                                   $request_file)); |                                                   $request_file)); | ||||||
|             return new Pluf_HTTP_Response_Redirect($url, 301); |             return new Pluf_HTTP_Response_Redirect($url, 301); | ||||||
|         } |         } | ||||||
|         if ('commit' != $scm->testHash($commit, $request_file)) { |         if (!$scm->isValidRevision($commit, $request_file)) { | ||||||
|             // Redirect to the first branch |             // Redirect to the first branch | ||||||
|             return new Pluf_HTTP_Response_Redirect($fburl); |             return new Pluf_HTTP_Response_Redirect($fburl); | ||||||
|         } |         } | ||||||
|         $request_file_info = $scm->getFileInfo($request_file, $commit); |         $request_file_info = $scm->getPathInfo($request_file, $commit); | ||||||
|         if (!$request_file_info) { |         if (!$request_file_info) { | ||||||
|             // Redirect to the first branch |             // Redirect to the first branch | ||||||
|             return new Pluf_HTTP_Response_Redirect($fburl); |             return new Pluf_HTTP_Response_Redirect($fburl); | ||||||
| @@ -177,7 +189,8 @@ class IDF_Views_Source | |||||||
|             $info = self::getRequestedFileMimeType($request_file_info,  |             $info = self::getRequestedFileMimeType($request_file_info,  | ||||||
|                                                    $commit, $scm); |                                                    $commit, $scm); | ||||||
|             if (!self::isText($info)) { |             if (!self::isText($info)) { | ||||||
|                 $rep = new Pluf_HTTP_Response($scm->getBlob($request_file_info, $commit), |  | ||||||
|  |                 $rep = new Pluf_HTTP_Response($scm->getFile($request_file_info), | ||||||
|                                               $info[0]); |                                               $info[0]); | ||||||
|                 $rep->headers['Content-Disposition'] = 'attachment; filename="'.$info[1].'"'; |                 $rep->headers['Content-Disposition'] = 'attachment; filename="'.$info[1].'"'; | ||||||
|                 return $rep; |                 return $rep; | ||||||
| @@ -192,30 +205,25 @@ class IDF_Views_Source | |||||||
|                 return $this->viewFile($request, $match, $extra); |                 return $this->viewFile($request, $match, $extra); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         $bc = self::makeBreadCrumb($request->project, $commit, $request_file_info->file); |  | ||||||
|  |         $bc = self::makeBreadCrumb($request->project, $commit, $request_file_info->fullpath); | ||||||
|  |  | ||||||
|         $page_title = $bc.' - '.$title; |         $page_title = $bc.' - '.$title; | ||||||
|         $cobject = $scm->getCommit($commit); |         $cobject = $scm->getCommit($commit); | ||||||
|         $tree_in = in_array($commit, $branches); |         $in_branches = $scm->inBranches($commit, $request_file); | ||||||
|         try { |  | ||||||
|         $cache = Pluf_Cache::factory(); |         $cache = Pluf_Cache::factory(); | ||||||
|         $key = sprintf('Project:%s::IDF_Views_Source::tree:%s::%s', |         $key = sprintf('Project:%s::IDF_Views_Source::tree:%s::%s', | ||||||
|                        $request->project->id, $commit, $request_file); |                        $request->project->id, $commit, $request_file); | ||||||
|         if (null === ($res=$cache->get($key))) { |         if (null === ($res=$cache->get($key))) { | ||||||
|                 $res = new Pluf_Template_ContextVars($scm->filesAtCommit($commit, $request_file)); |             $res = new Pluf_Template_ContextVars($scm->getTree($commit, $request_file)); | ||||||
|             $cache->set($key, $res); |             $cache->set($key, $res); | ||||||
|         } |         } | ||||||
|         } catch (Exception $e) { |  | ||||||
|             return new Pluf_HTTP_Response_Redirect($fburl); |  | ||||||
|         } |  | ||||||
|         // try to find the previous level if it exists. |         // try to find the previous level if it exists. | ||||||
|         $prev = split('/', $request_file); |         $prev = split('/', $request_file); | ||||||
|         $l = array_pop($prev); |         $l = array_pop($prev); | ||||||
|         $previous = substr($request_file, 0, -strlen($l.' ')); |         $previous = substr($request_file, 0, -strlen($l.' ')); | ||||||
|         $scmConf = $request->conf->getVal('scm', 'git'); |         $scmConf = $request->conf->getVal('scm', 'git'); | ||||||
|         $props = null; |  | ||||||
|         if ($scmConf === 'svn') { |  | ||||||
|         $props = $scm->getProperties($commit, $request_file); |         $props = $scm->getProperties($commit, $request_file); | ||||||
|         } |  | ||||||
|         return Pluf_Shortcuts_RenderToResponse('idf/source/'.$scmConf.'/tree.html', |         return Pluf_Shortcuts_RenderToResponse('idf/source/'.$scmConf.'/tree.html', | ||||||
|                                                array( |                                                array( | ||||||
|                                                      'page_title' => $page_title, |                                                      'page_title' => $page_title, | ||||||
| @@ -226,7 +234,7 @@ class IDF_Views_Source | |||||||
|                                                      'cobject' => $cobject, |                                                      'cobject' => $cobject, | ||||||
|                                                      'base' => $request_file_info->file, |                                                      'base' => $request_file_info->file, | ||||||
|                                                      'prev' => $previous, |                                                      'prev' => $previous, | ||||||
|                                                      'tree_in' => $tree_in, |                                                      'tree_in' => $in_branches, | ||||||
|                                                      'branches' => $branches, |                                                      'branches' => $branches, | ||||||
|                                                      'props' => $props, |                                                      'props' => $props, | ||||||
|                                                      ), |                                                      ), | ||||||
| @@ -256,21 +264,29 @@ class IDF_Views_Source | |||||||
|         $scm = IDF_Scm::get($request->project); |         $scm = IDF_Scm::get($request->project); | ||||||
|         $commit = $match[2]; |         $commit = $match[2]; | ||||||
|         $branches = $scm->getBranches(); |         $branches = $scm->getBranches(); | ||||||
|         if ('commit' != $scm->testHash($commit)) { |         if (!$scm->isValidRevision($commit)) { | ||||||
|             // Redirect to the first branch |             // Redirect to the first branch | ||||||
|             $url = Pluf_HTTP_URL_urlForView('IDF_Views_Source::treeBase', |             $url = Pluf_HTTP_URL_urlForView('IDF_Views_Source::treeBase', | ||||||
|                                             array($request->project->shortname, |                                             array($request->project->shortname, | ||||||
|                                                   $branches[0])); |                                                   $scm->getMainBranch())); | ||||||
|  |             return new Pluf_HTTP_Response_Redirect($url); | ||||||
|  |         } | ||||||
|  |         $large = $scm->isCommitLarge($commit); | ||||||
|  |         $cobject = $scm->getCommit($commit, !$large); | ||||||
|  |         if (!$cobject) { | ||||||
|  |             // Redirect to the first branch | ||||||
|  |             $url = Pluf_HTTP_URL_urlForView('IDF_Views_Source::treeBase', | ||||||
|  |                                             array($request->project->shortname, | ||||||
|  |                                                   $scm->getMainBranch())); | ||||||
|             return new Pluf_HTTP_Response_Redirect($url); |             return new Pluf_HTTP_Response_Redirect($url); | ||||||
|         } |         } | ||||||
|         $title = sprintf(__('%s Commit Details'), (string) $request->project); |         $title = sprintf(__('%s Commit Details'), (string) $request->project); | ||||||
|         $page_title = sprintf(__('%s Commit Details - %s'), (string) $request->project, $commit); |         $page_title = sprintf(__('%s Commit Details - %s'), (string) $request->project, $commit); | ||||||
|         $large = $scm->isCommitLarge($commit); |  | ||||||
|         $cobject = $scm->getCommit($commit, !$large); |  | ||||||
|         $rcommit = IDF_Commit::getOrAdd($cobject, $request->project); |         $rcommit = IDF_Commit::getOrAdd($cobject, $request->project); | ||||||
|         $diff = new IDF_Diff($cobject->changes); |         $diff = new IDF_Diff($cobject->changes); | ||||||
|         $diff->parse(); |         $diff->parse(); | ||||||
|         $scmConf = $request->conf->getVal('scm', 'git'); |         $scmConf = $request->conf->getVal('scm', 'git'); | ||||||
|  |         $in_branches = $scm->inBranches($commit, ''); | ||||||
|         return Pluf_Shortcuts_RenderToResponse('idf/source/commit.html', |         return Pluf_Shortcuts_RenderToResponse('idf/source/commit.html', | ||||||
|                                                array( |                                                array( | ||||||
|                                                      'page_title' => $page_title, |                                                      'page_title' => $page_title, | ||||||
| @@ -279,6 +295,7 @@ class IDF_Views_Source | |||||||
|                                                      'cobject' => $cobject, |                                                      'cobject' => $cobject, | ||||||
|                                                      'commit' => $commit, |                                                      'commit' => $commit, | ||||||
|                                                      'branches' => $branches, |                                                      'branches' => $branches, | ||||||
|  |                                                      'tree_in' => $in_branches, | ||||||
|                                                      'scm' => $scmConf, |                                                      'scm' => $scmConf, | ||||||
|                                                      'rcommit' => $rcommit, |                                                      'rcommit' => $rcommit, | ||||||
|                                                      'large_commit' => $large, |                                                      'large_commit' => $large, | ||||||
| @@ -292,11 +309,11 @@ class IDF_Views_Source | |||||||
|         $scm = IDF_Scm::get($request->project); |         $scm = IDF_Scm::get($request->project); | ||||||
|         $commit = $match[2]; |         $commit = $match[2]; | ||||||
|         $branches = $scm->getBranches(); |         $branches = $scm->getBranches(); | ||||||
|         if ('commit' != $scm->testHash($commit)) { |         if (!$scm->isValidRevision($commit)) { | ||||||
|             // Redirect to the first branch |             // Redirect to the first branch | ||||||
|             $url = Pluf_HTTP_URL_urlForView('IDF_Views_Source::treeBase', |             $url = Pluf_HTTP_URL_urlForView('IDF_Views_Source::treeBase', | ||||||
|                                             array($request->project->shortname, |                                             array($request->project->shortname, | ||||||
|                                                   $branches[0])); |                                                   $scm->getMainBranch())); | ||||||
|             return new Pluf_HTTP_Response_Redirect($url); |             return new Pluf_HTTP_Response_Redirect($url); | ||||||
|         } |         } | ||||||
|         $cobject = $scm->getCommit($commit, true); |         $cobject = $scm->getCommit($commit, true); | ||||||
| @@ -317,20 +334,17 @@ class IDF_Views_Source | |||||||
|         $commit = $extra['commit']; |         $commit = $extra['commit']; | ||||||
|         $request_file = $extra['request_file']; |         $request_file = $extra['request_file']; | ||||||
|         $request_file_info = $extra['request_file_info']; |         $request_file_info = $extra['request_file_info']; | ||||||
|         $bc = self::makeBreadCrumb($request->project, $commit, $request_file_info->file); |         $bc = self::makeBreadCrumb($request->project, $commit, $request_file_info->fullpath); | ||||||
|         $page_title = $bc.' - '.$title; |         $page_title = $bc.' - '.$title; | ||||||
|         $cobject = $scm->getCommit($commit); |         $cobject = $scm->getCommit($commit); | ||||||
|         $tree_in = in_array($commit, $branches); |         $in_branches = $scm->inBranches($commit, $request_file); | ||||||
|         // try to find the previous level if it exists. |         // try to find the previous level if it exists. | ||||||
|         $prev = split('/', $request_file); |         $prev = split('/', $request_file); | ||||||
|         $l = array_pop($prev); |         $l = array_pop($prev); | ||||||
|         $previous = substr($request_file, 0, -strlen($l.' ')); |         $previous = substr($request_file, 0, -strlen($l.' ')); | ||||||
|         $scmConf = $request->conf->getVal('scm', 'git'); |         $scmConf = $request->conf->getVal('scm', 'git'); | ||||||
|         $props = null; |  | ||||||
|         if ($scmConf === 'svn') { |  | ||||||
|         $props = $scm->getProperties($commit, $request_file); |         $props = $scm->getProperties($commit, $request_file); | ||||||
|         } |         $content = self::highLight($extra['mime'], $scm->getFile($request_file_info)); | ||||||
|         $content = self::highLight($extra['mime'], $scm->getBlob($request_file_info, $commit)); |  | ||||||
|         return Pluf_Shortcuts_RenderToResponse('idf/source/'.$scmConf.'/file.html', |         return Pluf_Shortcuts_RenderToResponse('idf/source/'.$scmConf.'/file.html', | ||||||
|                                                array( |                                                array( | ||||||
|                                                      'page_title' => $page_title, |                                                      'page_title' => $page_title, | ||||||
| @@ -342,7 +356,7 @@ class IDF_Views_Source | |||||||
|                                                      'fullpath' => $request_file, |                                                      'fullpath' => $request_file, | ||||||
|                                                      'base' => $request_file_info->file, |                                                      'base' => $request_file_info->file, | ||||||
|                                                      'prev' => $previous, |                                                      'prev' => $previous, | ||||||
|                                                      'tree_in' => $tree_in, |                                                      'tree_in' => $in_branches, | ||||||
|                                                      'branches' => $branches, |                                                      'branches' => $branches, | ||||||
|                                                      'props' => $props, |                                                      'props' => $props, | ||||||
|                                                      ), |                                                      ), | ||||||
| @@ -360,24 +374,24 @@ class IDF_Views_Source | |||||||
|         $branches = $scm->getBranches(); |         $branches = $scm->getBranches(); | ||||||
|         $commit = $match[2]; |         $commit = $match[2]; | ||||||
|         $request_file = $match[3]; |         $request_file = $match[3]; | ||||||
|         if ('commit' != $scm->testHash($commit, $request_file)) { |         if (!$scm->isValidRevision($commit)) { | ||||||
|             // Redirect to the first branch |             // Redirect to the first branch | ||||||
|             $url = Pluf_HTTP_URL_urlForView('IDF_Views_Source::treeBase', |             $url = Pluf_HTTP_URL_urlForView('IDF_Views_Source::treeBase', | ||||||
|                                             array($request->project->shortname, |                                             array($request->project->shortname, | ||||||
|                                                   $branches[0])); |                                                   $scm->getMainBranch())); | ||||||
|             return new Pluf_HTTP_Response_Redirect($url); |             return new Pluf_HTTP_Response_Redirect($url); | ||||||
|         } |         } | ||||||
|         $request_file_info = $scm->getFileInfo($request_file, $commit); |         $request_file_info = $scm->getPathInfo($request_file, $commit); | ||||||
|         if (!$request_file_info or $request_file_info->type == 'tree') { |         if (!$request_file_info or $request_file_info->type == 'tree') { | ||||||
|             // Redirect to the first branch |             // Redirect to the first branch | ||||||
|             $url = Pluf_HTTP_URL_urlForView('IDF_Views_Source::treeBase', |             $url = Pluf_HTTP_URL_urlForView('IDF_Views_Source::treeBase', | ||||||
|                                             array($request->project->shortname, |                                             array($request->project->shortname, | ||||||
|                                                   $branches[0])); |                                                   $scm->getMainBranch())); | ||||||
|             return new Pluf_HTTP_Response_Redirect($url); |             return new Pluf_HTTP_Response_Redirect($url); | ||||||
|         } |         } | ||||||
|         $info = self::getRequestedFileMimeType($request_file_info,  |         $info = self::getRequestedFileMimeType($request_file_info,  | ||||||
|                                                    $commit, $scm); |                                                    $commit, $scm); | ||||||
|         $rep = new Pluf_HTTP_Response($scm->getBlob($request_file_info, $commit), |         $rep = new Pluf_HTTP_Response($scm->getFile($request_file_info), | ||||||
|                                       $info[0]); |                                       $info[0]); | ||||||
|         $rep->headers['Content-Disposition'] = 'attachment; filename="'.$info[1].'"'; |         $rep->headers['Content-Disposition'] = 'attachment; filename="'.$info[1].'"'; | ||||||
|         return $rep; |         return $rep; | ||||||
| @@ -393,11 +407,11 @@ class IDF_Views_Source | |||||||
|         $commit = trim($match[2]); |         $commit = trim($match[2]); | ||||||
|         $scm = IDF_Scm::get($request->project); |         $scm = IDF_Scm::get($request->project); | ||||||
|         $branches = $scm->getBranches(); |         $branches = $scm->getBranches(); | ||||||
|         if ('commit' != $scm->testHash($commit)) { |         if (!$scm->isValidRevision($commit)) { | ||||||
|             // Redirect to the first branch |             // Redirect to the first branch | ||||||
|             $url = Pluf_HTTP_URL_urlForView('IDF_Views_Source::treeBase', |             $url = Pluf_HTTP_URL_urlForView('IDF_Views_Source::treeBase', | ||||||
|                                             array($request->project->shortname, |                                             array($request->project->shortname, | ||||||
|                                                   $branches[0])); |                                                   $scm->getMainBranch())); | ||||||
|             return new Pluf_HTTP_Response_Redirect($url); |             return new Pluf_HTTP_Response_Redirect($url); | ||||||
|         } |         } | ||||||
|         $base = $request->project->shortname.'-'.$commit; |         $base = $request->project->shortname.'-'.$commit; | ||||||
| @@ -424,7 +438,7 @@ class IDF_Views_Source | |||||||
|             return $mime; |             return $mime; | ||||||
|         } |         } | ||||||
|         return self::getMimeTypeFromContent($file_info->file, |         return self::getMimeTypeFromContent($file_info->file, | ||||||
|                                             $scm->getBlob($file_info, $commit)); |                                             $scm->getFile($file_info)); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|      /** |      /** | ||||||
| @@ -502,15 +516,16 @@ class IDF_Views_Source | |||||||
|         if (0 === strpos($fileinfo[0], 'text/')) { |         if (0 === strpos($fileinfo[0], 'text/')) { | ||||||
|             return true; |             return true; | ||||||
|         } |         } | ||||||
|         $ext = 'mdtext php js cpp php-dist h gitignore sh py pl rb diff patch' |         $ext = 'mdtext php-dist h gitignore diff patch' | ||||||
|             .Pluf::f('idf_extra_text_ext', ''); |             .Pluf::f('idf_extra_text_ext', ''); | ||||||
|         return (in_array($fileinfo[2], explode(' ', $ext))); |         $ext = array_merge(self::$supportedExtenstions, explode(' ' , $ext)); | ||||||
|  |         return (in_array($fileinfo[2], $ext)); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public static function highLight($fileinfo, $content) |     public static function highLight($fileinfo, $content) | ||||||
|     { |     { | ||||||
|         $pretty = ''; |         $pretty = ''; | ||||||
|         if (IDF_Views_Source::isSupportedExtension($fileinfo[2])) { |         if (self::isSupportedExtension($fileinfo[2])) { | ||||||
|             $pretty = ' prettyprint'; |             $pretty = ' prettyprint'; | ||||||
|         } |         } | ||||||
|         $table = array(); |         $table = array(); | ||||||
| @@ -524,13 +539,14 @@ class IDF_Views_Source | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * @param string the extension to test |      * Test if an extension is supported by the syntax highlighter. | ||||||
|      * |      * | ||||||
|      * @return  |      * @param string The extension to test | ||||||
|  |      * @return bool | ||||||
|      */ |      */ | ||||||
|     public static function isSupportedExtension($extension) |     public static function isSupportedExtension($extension) | ||||||
|     { |     { | ||||||
|         return in_array($extension, IDF_Views_Source::$supportedExtenstions); |         return in_array($extension, self::$supportedExtenstions); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|   | |||||||
| @@ -124,7 +124,7 @@ class IDF_Views_User | |||||||
|         } |         } | ||||||
|         $keys = $request->user->get_idf_key_list(); |         $keys = $request->user->get_idf_key_list(); | ||||||
|         if ($keys->count() > 0 and strlen($keys[0]->content) > 30) { |         if ($keys->count() > 0 and strlen($keys[0]->content) > 30) { | ||||||
|             $ssh_key = Pluf_Template::markSafe('<span class="mono">'.Pluf_esc(substr($keys[0]->content, 0, 30)).'...</span><br /><span class="helptext">'.__('Troncated for security reasons.').'</span>'); |             $ssh_key = Pluf_Template::markSafe('<span class="mono">'.Pluf_esc(substr($keys[0]->content, 0, 30)).'...</span><br /><span class="helptext">'.__('Truncated for security reasons.').'</span>'); | ||||||
|         } else { |         } else { | ||||||
|             $ssh_key = __('You have not upload your public SSH key yet.'); |             $ssh_key = __('You have not upload your public SSH key yet.'); | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -222,7 +222,7 @@ class IDF_Views_Wiki | |||||||
|                             array($prj->id, $match[2])); |                             array($prj->id, $match[2])); | ||||||
|         $pages = Pluf::factory('IDF_WikiPage')->getList(array('filter'=>$sql->gen())); |         $pages = Pluf::factory('IDF_WikiPage')->getList(array('filter'=>$sql->gen())); | ||||||
|         if ($pages->count() != 1) { |         if ($pages->count() != 1) { | ||||||
|             throw new Pluf_HTTP_Response_NotFound($request); |             return new Pluf_HTTP_Response_NotFound($request); | ||||||
|         } |         } | ||||||
|         $page = $pages[0]; |         $page = $pages[0]; | ||||||
|         $oldrev = false; |         $oldrev = false; | ||||||
| @@ -231,7 +231,7 @@ class IDF_Views_Wiki | |||||||
|             $oldrev = Pluf_Shortcuts_GetObjectOr404('IDF_WikiRevision', |             $oldrev = Pluf_Shortcuts_GetObjectOr404('IDF_WikiRevision', | ||||||
|                                                     $request->GET['rev']); |                                                     $request->GET['rev']); | ||||||
|             if ($oldrev->wikipage != $page->id or $oldrev->is_head == true) { |             if ($oldrev->wikipage != $page->id or $oldrev->is_head == true) { | ||||||
|                 throw new Pluf_HTTP_Response_NotFound($request); |                 return new Pluf_HTTP_Response_NotFound($request); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         $ptags = self::getWikiTags($prj); |         $ptags = self::getWikiTags($prj); | ||||||
| @@ -269,7 +269,7 @@ class IDF_Views_Wiki | |||||||
|         $page = $oldrev->get_wikipage(); |         $page = $oldrev->get_wikipage(); | ||||||
|         $prj->inOr404($page); |         $prj->inOr404($page); | ||||||
|         if ($oldrev->is_head == true) { |         if ($oldrev->is_head == true) { | ||||||
|             throw new Pluf_HTTP_Error404($request); |             return new Pluf_HTTP_Response_NotFound($request); | ||||||
|         } |         } | ||||||
|         if ($request->method == 'POST') { |         if ($request->method == 'POST') { | ||||||
|             $oldrev->delete(); |             $oldrev->delete(); | ||||||
| @@ -310,7 +310,7 @@ class IDF_Views_Wiki | |||||||
|                             array($prj->id, $match[2])); |                             array($prj->id, $match[2])); | ||||||
|         $pages = Pluf::factory('IDF_WikiPage')->getList(array('filter'=>$sql->gen())); |         $pages = Pluf::factory('IDF_WikiPage')->getList(array('filter'=>$sql->gen())); | ||||||
|         if ($pages->count() != 1) { |         if ($pages->count() != 1) { | ||||||
|             throw new Pluf_HTTP_Error404($request); |             return new Pluf_HTTP_Response_NotFound($request); | ||||||
|         } |         } | ||||||
|         $page = $pages[0]; |         $page = $pages[0]; | ||||||
|         $title = sprintf(__('Update %s'), $page->title); |         $title = sprintf(__('Update %s'), $page->title); | ||||||
|   | |||||||
| @@ -196,7 +196,7 @@ class IDF_WikiPage extends Pluf_Model | |||||||
|         $user = $stag->start($this->get_submitter(), $request, '', false); |         $user = $stag->start($this->get_submitter(), $request, '', false); | ||||||
|         $out .= sprintf(__('<a href="%1$s" title="View page">%2$s</a>, %3$s'), $url, Pluf_esc($this->title), Pluf_esc($this->summary)).'</td>'; |         $out .= sprintf(__('<a href="%1$s" title="View page">%2$s</a>, %3$s'), $url, Pluf_esc($this->title), Pluf_esc($this->summary)).'</td>'; | ||||||
|         $out .= "\n".'<tr class="extra"><td colspan="2"> |         $out .= "\n".'<tr class="extra"><td colspan="2"> | ||||||
| <div class="helptext right">'.sprintf(__('Creation of <a href="%s">page %s</a>'), $url, Pluf_esc($this->title)).', '.__('by').' '.$user.'</div></td></tr>';  | <div class="helptext right">'.sprintf(__('Creation of <a href="%s">page %s</a>, by %s'), $url, Pluf_esc($this->title), $user).'</div></td></tr>';  | ||||||
|         return Pluf_Template::markSafe($out); |         return Pluf_Template::markSafe($out); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -186,7 +186,7 @@ class IDF_WikiRevision extends Pluf_Model | |||||||
|         } |         } | ||||||
|         $out .= '</td></tr>'; |         $out .= '</td></tr>'; | ||||||
|         $out .= "\n".'<tr class="extra"><td colspan="2"> |         $out .= "\n".'<tr class="extra"><td colspan="2"> | ||||||
| <div class="helptext right">'.sprintf(__('Change of <a href="%s">%s</a>'), $url, Pluf_esc($page->title)).', '.__('by').' '.$user.'</div></td></tr>';  | <div class="helptext right">'.sprintf(__('Change of <a href="%s">%s</a>, by %s'), $url, Pluf_esc($page->title), $user).'</div></td></tr>';  | ||||||
|         return Pluf_Template::markSafe($out); |         return Pluf_Template::markSafe($out); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -161,13 +161,19 @@ $cfg['db_database'] = 'website'; # put absolute path to the db if you | |||||||
|                                  # are using SQLite.  |                                  # are using SQLite.  | ||||||
| # | # | ||||||
| # The extension of the downloads are limited. You can add extra | # The extension of the downloads are limited. You can add extra | ||||||
| # extensions here. It must start with a space. | # extensions here. The list must start with a space. | ||||||
| # $cfg['idf_extra_upload_ext'] = ' ext1 ext2'; | # $cfg['idf_extra_upload_ext'] = ' ext1 ext2'; | ||||||
| # | # | ||||||
| # By default, the size of the downloads is limited to 2MB. | # By default, the size of the downloads is limited to 2MB. | ||||||
| # $cfg['max_upload_size'] = 2097152; // Size in bytes | # $cfg['max_upload_size'] = 2097152; // Size in bytes | ||||||
|  |  | ||||||
| # -- From this point you should not need to update anything. -- | # | ||||||
|  | # Time zone | ||||||
|  | # http://www.php.net/manual/en/timezones.php | ||||||
|  | # | ||||||
|  | # $cfg['time_zone'] = 'Europe/Berlin'; | ||||||
|  |  | ||||||
|  |  | ||||||
| $cfg['pear_path'] = '/usr/share/php'; | $cfg['pear_path'] = '/usr/share/php'; | ||||||
|  |  | ||||||
| $cfg['login_success_url'] = $cfg['url_base'].$cfg['idf_base']; | $cfg['login_success_url'] = $cfg['url_base'].$cfg['idf_base']; | ||||||
|   | |||||||
| @@ -26,33 +26,28 @@ $base = Pluf::f('idf_base'); | |||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/$#', | $ctl[] = array('regex' => '#^/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views', |                'model' => 'IDF_Views', | ||||||
|                'method' => 'index'); |                'method' => 'index'); | ||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/login/$#', | $ctl[] = array('regex' => '#^/login/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views', |                'model' => 'IDF_Views', | ||||||
|                'method' => 'login', |                'method' => 'login', | ||||||
|                'name' => 'login_view'); |                'name' => 'login_view'); | ||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/preferences/$#', | $ctl[] = array('regex' => '#^/preferences/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views_User', |                'model' => 'IDF_Views_User', | ||||||
|                'method' => 'myAccount'); |                'method' => 'myAccount'); | ||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/dashboard/$#', | $ctl[] = array('regex' => '#^/dashboard/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views_User', |                'model' => 'IDF_Views_User', | ||||||
|                'method' => 'dashboard', |                'method' => 'dashboard', | ||||||
|                'name' => 'idf_dashboard'); |                'name' => 'idf_dashboard'); | ||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/dashboard/submitted/$#', | $ctl[] = array('regex' => '#^/dashboard/submitted/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views_User', |                'model' => 'IDF_Views_User', | ||||||
|                'method' => 'dashboard', |                'method' => 'dashboard', | ||||||
|                'params' => false, |                'params' => false, | ||||||
| @@ -60,105 +55,88 @@ $ctl[] = array('regex' => '#^/dashboard/submitted/$#', | |||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/u/(.*)/$#', | $ctl[] = array('regex' => '#^/u/(.*)/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views_User', |                'model' => 'IDF_Views_User', | ||||||
|                'method' => 'view'); |                'method' => 'view'); | ||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/logout/$#', | $ctl[] = array('regex' => '#^/logout/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views', |                'model' => 'IDF_Views', | ||||||
|                'method' => 'logout'); |                'method' => 'logout'); | ||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/help/$#', | $ctl[] = array('regex' => '#^/help/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views', |                'model' => 'IDF_Views', | ||||||
|                'method' => 'faq'); |                'method' => 'faq'); | ||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/p/([\-\w]+)/$#', | $ctl[] = array('regex' => '#^/p/([\-\w]+)/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views_Project', |                'model' => 'IDF_Views_Project', | ||||||
|                'method' => 'home'); |                'method' => 'home'); | ||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/p/([\-\w]+)/timeline/$#', | $ctl[] = array('regex' => '#^/p/([\-\w]+)/timeline/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views_Project', |                'model' => 'IDF_Views_Project', | ||||||
|                'method' => 'timeline'); |                'method' => 'timeline'); | ||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/p/([\-\w]+)/feed/timeline/$#', | $ctl[] = array('regex' => '#^/p/([\-\w]+)/feed/timeline/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views_Project', |                'model' => 'IDF_Views_Project', | ||||||
|                'method' => 'timelineFeed', |                'method' => 'timelineFeed', | ||||||
|                'name' => 'idf_project_timeline_feed'); |                'name' => 'idf_project_timeline_feed'); | ||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/p/([\-\w]+)/feed/timeline/token/(.*)/$#', | $ctl[] = array('regex' => '#^/p/([\-\w]+)/feed/timeline/token/(.*)/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views_Project', |                'model' => 'IDF_Views_Project', | ||||||
|                'method' => 'timelineFeed', |                'method' => 'timelineFeed', | ||||||
|                'name' => 'idf_project_timeline_feed_auth'); |                'name' => 'idf_project_timeline_feed_auth'); | ||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/p/([\-\w]+)/issues/$#', | $ctl[] = array('regex' => '#^/p/([\-\w]+)/issues/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views_Issue', |                'model' => 'IDF_Views_Issue', | ||||||
|                'method' => 'index'); |                'method' => 'index'); | ||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/p/([\-\w]+)/issues/search/$#', | $ctl[] = array('regex' => '#^/p/([\-\w]+)/issues/search/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views_Issue', |                'model' => 'IDF_Views_Issue', | ||||||
|                'method' => 'search'); |                'method' => 'search'); | ||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/p/([\-\w]+)/issues/(\d+)/$#', | $ctl[] = array('regex' => '#^/p/([\-\w]+)/issues/(\d+)/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views_Issue', |                'model' => 'IDF_Views_Issue', | ||||||
|                'method' => 'view'); |                'method' => 'view'); | ||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/p/([\-\w]+)/issues/(\d+)/star/$#', | $ctl[] = array('regex' => '#^/p/([\-\w]+)/issues/(\d+)/star/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views_Issue', |                'model' => 'IDF_Views_Issue', | ||||||
|                'method' => 'star'); |                'method' => 'star'); | ||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/p/([\-\w]+)/issues/status/(\w+)/$#', | $ctl[] = array('regex' => '#^/p/([\-\w]+)/issues/status/(\w+)/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views_Issue', |                'model' => 'IDF_Views_Issue', | ||||||
|                'method' => 'listStatus'); |                'method' => 'listStatus'); | ||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/p/([\-\w]+)/issues/label/(\d+)/(\w+)/$#', | $ctl[] = array('regex' => '#^/p/([\-\w]+)/issues/label/(\d+)/(\w+)/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views_Issue', |                'model' => 'IDF_Views_Issue', | ||||||
|                'method' => 'listLabel'); |                'method' => 'listLabel'); | ||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/p/([\-\w]+)/issues/create/$#', | $ctl[] = array('regex' => '#^/p/([\-\w]+)/issues/create/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views_Issue', |                'model' => 'IDF_Views_Issue', | ||||||
|                'method' => 'create'); |                'method' => 'create'); | ||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/p/([\-\w]+)/issues/my/(\w+)/$#', | $ctl[] = array('regex' => '#^/p/([\-\w]+)/issues/my/(\w+)/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views_Issue', |                'model' => 'IDF_Views_Issue', | ||||||
|                'method' => 'myIssues'); |                'method' => 'myIssues'); | ||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/p/([\-\w]+)/issues/attachment/(\d+)/(.*)$#', | $ctl[] = array('regex' => '#^/p/([\-\w]+)/issues/attachment/(\d+)/(.*)$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views_Issue', |                'model' => 'IDF_Views_Issue', | ||||||
|                'method' => 'getAttachment'); |                'method' => 'getAttachment'); | ||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/p/([\-\w]+)/issues/view/attachment/(\d+)/(.*)$#', | $ctl[] = array('regex' => '#^/p/([\-\w]+)/issues/view/attachment/(\d+)/(.*)$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views_Issue', |                'model' => 'IDF_Views_Issue', | ||||||
|                'method' => 'viewAttachment'); |                'method' => 'viewAttachment'); | ||||||
|  |  | ||||||
| @@ -166,61 +144,51 @@ $ctl[] = array('regex' => '#^/p/([\-\w]+)/issues/view/attachment/(\d+)/(.*)$#', | |||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/p/([\-\w]+)/source/help/$#', | $ctl[] = array('regex' => '#^/p/([\-\w]+)/source/help/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views_Source', |                'model' => 'IDF_Views_Source', | ||||||
|                'method' => 'help'); |                'method' => 'help'); | ||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/p/([\-\w]+)/source/tree/([^/]+)/$#', | $ctl[] = array('regex' => '#^/p/([\-\w]+)/source/tree/([^/]+)/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views_Source', |                'model' => 'IDF_Views_Source', | ||||||
|                'method' => 'treeBase'); |                'method' => 'treeBase'); | ||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/p/([\-\w]+)/source/tree/([^/]+)/(.*)$#', | $ctl[] = array('regex' => '#^/p/([\-\w]+)/source/tree/([^/]+)/(.*)$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views_Source', |                'model' => 'IDF_Views_Source', | ||||||
|                'method' => 'tree'); |                'method' => 'tree'); | ||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/p/([\-\w]+)/source/changes/([^/]+)/$#', | $ctl[] = array('regex' => '#^/p/([\-\w]+)/source/changes/([^/]+)/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views_Source', |                'model' => 'IDF_Views_Source', | ||||||
|                'method' => 'changeLog'); |                'method' => 'changeLog'); | ||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/p/([\-\w]+)/source/commit/([^/]+)/$#', | $ctl[] = array('regex' => '#^/p/([\-\w]+)/source/commit/([^/]+)/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views_Source', |                'model' => 'IDF_Views_Source', | ||||||
|                'method' => 'commit'); |                'method' => 'commit'); | ||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/p/([\-\w]+)/source/ddiff/([^/]+)/$#', | $ctl[] = array('regex' => '#^/p/([\-\w]+)/source/ddiff/([^/]+)/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views_Source', |                'model' => 'IDF_Views_Source', | ||||||
|                'method' => 'downloadDiff'); |                'method' => 'downloadDiff'); | ||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/p/([\-\w]+)/source/download/([^/]+)/$#', | $ctl[] = array('regex' => '#^/p/([\-\w]+)/source/download/([^/]+)/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views_Source', |                'model' => 'IDF_Views_Source', | ||||||
|                'method' => 'download'); |                'method' => 'download'); | ||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/p/([\-\w]+)/source/file/([^/]+)/(.*)$#', | $ctl[] = array('regex' => '#^/p/([\-\w]+)/source/file/([^/]+)/(.*)$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views_Source', |                'model' => 'IDF_Views_Source', | ||||||
|                'method' => 'getFile'); |                'method' => 'getFile'); | ||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/p/([\-\w]+)/source/treerev/$#', | $ctl[] = array('regex' => '#^/p/([\-\w]+)/source/treerev/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views_Source_Svn', |                'model' => 'IDF_Views_Source_Svn', | ||||||
|                'method' => 'treeRev'); |                'method' => 'treeRev'); | ||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/p/([\-\w]+)/source/changesrev/$#', | $ctl[] = array('regex' => '#^/p/([\-\w]+)/source/changesrev/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views_Source_Svn', |                'model' => 'IDF_Views_Source_Svn', | ||||||
|                'method' => 'changelogRev'); |                'method' => 'changelogRev'); | ||||||
|  |  | ||||||
| @@ -228,43 +196,36 @@ $ctl[] = array('regex' => '#^/p/([\-\w]+)/source/changesrev/$#', | |||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/p/([\-\w]+)/doc/$#', | $ctl[] = array('regex' => '#^/p/([\-\w]+)/doc/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views_Wiki', |                'model' => 'IDF_Views_Wiki', | ||||||
|                'method' => 'index'); |                'method' => 'index'); | ||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/p/([\-\w]+)/doc/create/$#', | $ctl[] = array('regex' => '#^/p/([\-\w]+)/doc/create/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views_Wiki', |                'model' => 'IDF_Views_Wiki', | ||||||
|                'method' => 'create'); |                'method' => 'create'); | ||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/p/([\-\w]+)/doc/search/$#', | $ctl[] = array('regex' => '#^/p/([\-\w]+)/doc/search/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views_Wiki', |                'model' => 'IDF_Views_Wiki', | ||||||
|                'method' => 'search'); |                'method' => 'search'); | ||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/p/([\-\w]+)/doc/label/(\d+)/$#', | $ctl[] = array('regex' => '#^/p/([\-\w]+)/doc/label/(\d+)/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views_Wiki', |                'model' => 'IDF_Views_Wiki', | ||||||
|                'method' => 'listLabel'); |                'method' => 'listLabel'); | ||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/p/([\-\w]+)/doc/update/(.*)/$#', | $ctl[] = array('regex' => '#^/p/([\-\w]+)/doc/update/(.*)/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views_Wiki', |                'model' => 'IDF_Views_Wiki', | ||||||
|                'method' => 'update'); |                'method' => 'update'); | ||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/p/([\-\w]+)/doc/delrev/(\d+)/$#', | $ctl[] = array('regex' => '#^/p/([\-\w]+)/doc/delrev/(\d+)/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views_Wiki', |                'model' => 'IDF_Views_Wiki', | ||||||
|                'method' => 'deleteRev'); |                'method' => 'deleteRev'); | ||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/p/([\-\w]+)/page/(.*)/$#', | $ctl[] = array('regex' => '#^/p/([\-\w]+)/page/(.*)/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views_Wiki', |                'model' => 'IDF_Views_Wiki', | ||||||
|                'method' => 'view'); |                'method' => 'view'); | ||||||
|  |  | ||||||
| @@ -272,37 +233,31 @@ $ctl[] = array('regex' => '#^/p/([\-\w]+)/page/(.*)/$#', | |||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/p/([\-\w]+)/downloads/$#', | $ctl[] = array('regex' => '#^/p/([\-\w]+)/downloads/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views_Download', |                'model' => 'IDF_Views_Download', | ||||||
|                'method' => 'index'); |                'method' => 'index'); | ||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/p/([\-\w]+)/downloads/label/(\d+)/$#', | $ctl[] = array('regex' => '#^/p/([\-\w]+)/downloads/label/(\d+)/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views_Download', |                'model' => 'IDF_Views_Download', | ||||||
|                'method' => 'listLabel'); |                'method' => 'listLabel'); | ||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/p/([\-\w]+)/downloads/(\d+)/$#', | $ctl[] = array('regex' => '#^/p/([\-\w]+)/downloads/(\d+)/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views_Download', |                'model' => 'IDF_Views_Download', | ||||||
|                'method' => 'view'); |                'method' => 'view'); | ||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/p/([\-\w]+)/downloads/(\d+)/get/$#', | $ctl[] = array('regex' => '#^/p/([\-\w]+)/downloads/(\d+)/get/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views_Download', |                'model' => 'IDF_Views_Download', | ||||||
|                'method' => 'download'); |                'method' => 'download'); | ||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/p/([\-\w]+)/downloads/create/$#', | $ctl[] = array('regex' => '#^/p/([\-\w]+)/downloads/create/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views_Download', |                'model' => 'IDF_Views_Download', | ||||||
|                'method' => 'submit'); |                'method' => 'submit'); | ||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/p/([\-\w]+)/downloads/(\d+)/delete/$#', | $ctl[] = array('regex' => '#^/p/([\-\w]+)/downloads/(\d+)/delete/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views_Download', |                'model' => 'IDF_Views_Download', | ||||||
|                'method' => 'delete'); |                'method' => 'delete'); | ||||||
|  |  | ||||||
| @@ -310,25 +265,21 @@ $ctl[] = array('regex' => '#^/p/([\-\w]+)/downloads/(\d+)/delete/$#', | |||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/p/([\-\w]+)/review/$#', | $ctl[] = array('regex' => '#^/p/([\-\w]+)/review/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views_Review', |                'model' => 'IDF_Views_Review', | ||||||
|                'method' => 'index'); |                'method' => 'index'); | ||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/p/([\-\w]+)/review/(\d+)/$#', | $ctl[] = array('regex' => '#^/p/([\-\w]+)/review/(\d+)/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views_Review', |                'model' => 'IDF_Views_Review', | ||||||
|                'method' => 'view'); |                'method' => 'view'); | ||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/p/([\-\w]+)/review/create/$#', | $ctl[] = array('regex' => '#^/p/([\-\w]+)/review/create/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views_Review', |                'model' => 'IDF_Views_Review', | ||||||
|                'method' => 'create'); |                'method' => 'create'); | ||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/p/([\-\w]+)/review/getpatch/(\d+)/$#', | $ctl[] = array('regex' => '#^/p/([\-\w]+)/review/getpatch/(\d+)/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views_Review', |                'model' => 'IDF_Views_Review', | ||||||
|                'method' => 'getPatch'); |                'method' => 'getPatch'); | ||||||
|  |  | ||||||
| @@ -337,43 +288,36 @@ $ctl[] = array('regex' => '#^/p/([\-\w]+)/review/getpatch/(\d+)/$#', | |||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/p/([\-\w]+)/admin/$#', | $ctl[] = array('regex' => '#^/p/([\-\w]+)/admin/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views_Project', |                'model' => 'IDF_Views_Project', | ||||||
|                'method' => 'admin'); |                'method' => 'admin'); | ||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/p/([\-\w]+)/admin/issues/$#', | $ctl[] = array('regex' => '#^/p/([\-\w]+)/admin/issues/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views_Project', |                'model' => 'IDF_Views_Project', | ||||||
|                'method' => 'adminIssues'); |                'method' => 'adminIssues'); | ||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/p/([\-\w]+)/admin/downloads/$#', | $ctl[] = array('regex' => '#^/p/([\-\w]+)/admin/downloads/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views_Project', |                'model' => 'IDF_Views_Project', | ||||||
|                'method' => 'adminDownloads'); |                'method' => 'adminDownloads'); | ||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/p/([\-\w]+)/admin/wiki/$#', | $ctl[] = array('regex' => '#^/p/([\-\w]+)/admin/wiki/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views_Project', |                'model' => 'IDF_Views_Project', | ||||||
|                'method' => 'adminWiki'); |                'method' => 'adminWiki'); | ||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/p/([\-\w]+)/admin/source/$#', | $ctl[] = array('regex' => '#^/p/([\-\w]+)/admin/source/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views_Project', |                'model' => 'IDF_Views_Project', | ||||||
|                'method' => 'adminSource'); |                'method' => 'adminSource'); | ||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/p/([\-\w]+)/admin/members/$#', | $ctl[] = array('regex' => '#^/p/([\-\w]+)/admin/members/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views_Project', |                'model' => 'IDF_Views_Project', | ||||||
|                'method' => 'adminMembers'); |                'method' => 'adminMembers'); | ||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/p/([\-\w]+)/admin/tabs/$#', | $ctl[] = array('regex' => '#^/p/([\-\w]+)/admin/tabs/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views_Project', |                'model' => 'IDF_Views_Project', | ||||||
|                'method' => 'adminTabs'); |                'method' => 'adminTabs'); | ||||||
|  |  | ||||||
| @@ -381,19 +325,16 @@ $ctl[] = array('regex' => '#^/p/([\-\w]+)/admin/tabs/$#', | |||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/help/api/$#', | $ctl[] = array('regex' => '#^/help/api/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views', |                'model' => 'IDF_Views', | ||||||
|                'method' => 'faqApi'); |                'method' => 'faqApi'); | ||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/api/p/([\-\w]+)/issues/$#', | $ctl[] = array('regex' => '#^/api/p/([\-\w]+)/issues/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views_Api', |                'model' => 'IDF_Views_Api', | ||||||
|                'method' => 'issuesIndex'); |                'method' => 'issuesIndex'); | ||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/api/p/([\-\w]+)/issues/create/$#', | $ctl[] = array('regex' => '#^/api/p/([\-\w]+)/issues/create/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views_Api', |                'model' => 'IDF_Views_Api', | ||||||
|                'method' => 'issueCreate'); |                'method' => 'issueCreate'); | ||||||
|  |  | ||||||
| @@ -401,43 +342,36 @@ $ctl[] = array('regex' => '#^/api/p/([\-\w]+)/issues/create/$#', | |||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/admin/projects/$#', | $ctl[] = array('regex' => '#^/admin/projects/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views_Admin', |                'model' => 'IDF_Views_Admin', | ||||||
|                'method' => 'projects'); |                'method' => 'projects'); | ||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/admin/projects/(\d+)/$#', | $ctl[] = array('regex' => '#^/admin/projects/(\d+)/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views_Admin', |                'model' => 'IDF_Views_Admin', | ||||||
|                'method' => 'projectUpdate'); |                'method' => 'projectUpdate'); | ||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/admin/projects/create/$#', | $ctl[] = array('regex' => '#^/admin/projects/create/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views_Admin', |                'model' => 'IDF_Views_Admin', | ||||||
|                'method' => 'projectCreate'); |                'method' => 'projectCreate'); | ||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/admin/projects/(\d+)/delete/$#', | $ctl[] = array('regex' => '#^/admin/projects/(\d+)/delete/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views_Admin', |                'model' => 'IDF_Views_Admin', | ||||||
|                'method' => 'projectDelete'); |                'method' => 'projectDelete'); | ||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/admin/users/$#', | $ctl[] = array('regex' => '#^/admin/users/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views_Admin', |                'model' => 'IDF_Views_Admin', | ||||||
|                'method' => 'users'); |                'method' => 'users'); | ||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/admin/users/notvalid/$#', | $ctl[] = array('regex' => '#^/admin/users/notvalid/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views_Admin', |                'model' => 'IDF_Views_Admin', | ||||||
|                'method' => 'usersNotValidated'); |                'method' => 'usersNotValidated'); | ||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/admin/users/(\d+)/$#', | $ctl[] = array('regex' => '#^/admin/users/(\d+)/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views_Admin', |                'model' => 'IDF_Views_Admin', | ||||||
|                'method' => 'userUpdate'); |                'method' => 'userUpdate'); | ||||||
|  |  | ||||||
| @@ -445,53 +379,42 @@ $ctl[] = array('regex' => '#^/admin/users/(\d+)/$#', | |||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/register/$#', | $ctl[] = array('regex' => '#^/register/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views', |                'model' => 'IDF_Views', | ||||||
|                'method' => 'register'); |                'method' => 'register'); | ||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/register/k/(.*)/$#', | $ctl[] = array('regex' => '#^/register/k/(.*)/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views', |                'model' => 'IDF_Views', | ||||||
|                'method' => 'registerConfirmation'); |                'method' => 'registerConfirmation'); | ||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/register/ik/$#', | $ctl[] = array('regex' => '#^/register/ik/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views', |                'model' => 'IDF_Views', | ||||||
|                'method' => 'registerInputKey'); |                'method' => 'registerInputKey'); | ||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/password/$#', | $ctl[] = array('regex' => '#^/password/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views', |                'model' => 'IDF_Views', | ||||||
|                'method' => 'passwordRecoveryAsk'); |                'method' => 'passwordRecoveryAsk'); | ||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/password/ik/$#', | $ctl[] = array('regex' => '#^/password/ik/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views', |                'model' => 'IDF_Views', | ||||||
|                'method' => 'passwordRecoveryInputCode'); |                'method' => 'passwordRecoveryInputCode'); | ||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/password/k/(.*)/$#', | $ctl[] = array('regex' => '#^/password/k/(.*)/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views', |                'model' => 'IDF_Views', | ||||||
|                'method' => 'passwordRecovery'); |                'method' => 'passwordRecovery'); | ||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/preferences/email/ik/$#', | $ctl[] = array('regex' => '#^/preferences/email/ik/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views_User', |                'model' => 'IDF_Views_User', | ||||||
|                'method' => 'changeEmailInputKey'); |                'method' => 'changeEmailInputKey'); | ||||||
|  |  | ||||||
| $ctl[] = array('regex' => '#^/preferences/email/ak/(.*)/$#', | $ctl[] = array('regex' => '#^/preferences/email/ak/(.*)/$#', | ||||||
|                'base' => $base, |                'base' => $base, | ||||||
|                'priority' => 4, |  | ||||||
|                'model' => 'IDF_Views_User', |                'model' => 'IDF_Views_User', | ||||||
|                'method' => 'changeEmailDo'); |                'method' => 'changeEmailDo'); | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| return $ctl; | return $ctl; | ||||||
|   | |||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -8,7 +8,7 @@ msgid "" | |||||||
| msgstr "" | msgstr "" | ||||||
| "Project-Id-Version: PACKAGE VERSION\n" | "Project-Id-Version: PACKAGE VERSION\n" | ||||||
| "Report-Msgid-Bugs-To: \n" | "Report-Msgid-Bugs-To: \n" | ||||||
| "POT-Creation-Date: 2009-02-27 15:21+0100\n" | "POT-Creation-Date: 2009-06-22 21:06+0200\n" | ||||||
| "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" | ||||||
| "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" | "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" | ||||||
| "Language-Team: LANGUAGE <LL@li.org>\n" | "Language-Team: LANGUAGE <LL@li.org>\n" | ||||||
| @@ -24,8 +24,9 @@ msgid "project" | |||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Commit.php:62 IDF/IssueComment.php:65 IDF/IssueFile.php:57 | #: IDF/Commit.php:62 IDF/IssueComment.php:65 IDF/IssueFile.php:57 | ||||||
| #: IDF/Issue.php:67 IDF/Review.php:71 IDF/Upload.php:79 IDF/WikiPage.php:78 | #: IDF/Issue.php:67 IDF/Review.php:71 IDF/Upload.php:85 IDF/WikiPage.php:78 | ||||||
| #: IDF/WikiRevision.php:79 IDF/Review/FileComment.php:69 | #: IDF/WikiRevision.php:79 IDF/Review/Comment.php:69 | ||||||
|  | #: IDF/Review/FileComment.php:69 | ||||||
| msgid "submitter" | msgid "submitter" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| @@ -39,29 +40,28 @@ msgid "changelog" | |||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Commit.php:99 IDF/IssueComment.php:79 IDF/IssueFile.php:96 | #: IDF/Commit.php:99 IDF/IssueComment.php:79 IDF/IssueFile.php:96 | ||||||
| #: IDF/Issue.php:105 IDF/Review.php:99 IDF/Upload.php:100 IDF/WikiPage.php:100 | #: IDF/Issue.php:105 IDF/Review.php:99 IDF/Upload.php:106 IDF/WikiPage.php:100 | ||||||
| #: IDF/WikiRevision.php:92 IDF/Review/Patch.php:83 | #: IDF/WikiRevision.php:92 IDF/Review/Patch.php:83 IDF/Review/Comment.php:83 | ||||||
| #: IDF/Review/FileComment.php:76 | #: IDF/Review/FileComment.php:76 | ||||||
| msgid "creation date" | msgid "creation date" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Commit.php:170 | #: IDF/Commit.php:172 | ||||||
| #, php-format | #, php-format | ||||||
| msgid "New Commit %s - %s (%s)" | msgid "New Commit %s - %s (%s)" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Commit.php:205 IDF/Commit.php:232 IDF/Form/ReviewCreate.php:72 | #: IDF/Commit.php:239 | ||||||
|  | #, php-format | ||||||
|  | msgid "Commit %s, by %s" | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
|  | #: IDF/Commit.php:266 IDF/Form/ReviewCreate.php:74 | ||||||
| #: IDF/gettexttemplates/idf/source/base.html.php:5 | #: IDF/gettexttemplates/idf/source/base.html.php:5 | ||||||
| #: IDF/gettexttemplates/idf/source/changelog.html.php:5 | #: IDF/gettexttemplates/idf/source/changelog.html.php:5 | ||||||
| msgid "Commit" | msgid "Commit" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Commit.php:205 IDF/IssueComment.php:173 IDF/Issue.php:196 |  | ||||||
| #: IDF/Upload.php:185 IDF/WikiPage.php:199 IDF/WikiRevision.php:189 |  | ||||||
| #: IDF/gettexttemplates/idf/source/changelog.html.php:6 |  | ||||||
| msgid "by" |  | ||||||
| msgstr "" |  | ||||||
|  |  | ||||||
| #: IDF/Conf.php:61 IDF/Conf.php:61 | #: IDF/Conf.php:61 IDF/Conf.php:61 | ||||||
| msgid "key" | msgid "key" | ||||||
| msgstr "" | msgstr "" | ||||||
| @@ -70,29 +70,32 @@ msgstr "" | |||||||
| msgid "value" | msgid "value" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/IssueComment.php:51 | #: IDF/IssueComment.php:51 IDF/Review/Comment.php:55 | ||||||
| msgid "issue" | msgid "issue" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/IssueComment.php:58 IDF/IssueFile.php:49 IDF/Review/FileComment.php:62 | #: IDF/IssueComment.php:58 IDF/IssueFile.php:49 IDF/Review/Comment.php:62 | ||||||
|  | #: IDF/Review/FileComment.php:62 | ||||||
| msgid "comment" | msgid "comment" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/IssueComment.php:72 IDF/WikiRevision.php:85 | #: IDF/IssueComment.php:72 IDF/Upload.php:63 IDF/WikiRevision.php:85 | ||||||
|  | #: IDF/Review/Comment.php:76 | ||||||
| msgid "changes" | msgid "changes" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/IssueComment.php:73 | #: IDF/IssueComment.php:73 IDF/Review/Comment.php:77 | ||||||
| msgid "Serialized array of the changes in the issue." | msgid "Serialized array of the changes in the issue." | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/IssueComment.php:143 IDF/Issue.php:194 | #: IDF/IssueComment.php:143 IDF/Issue.php:194 IDF/Review/Comment.php:147 | ||||||
| #, php-format | #, php-format | ||||||
| msgid "" | msgid "" | ||||||
| "<a href=\"%1$s\" class=\"%2$s\" title=\"View issue\">Issue %3$d</a>, %4$s" | "<a href=\"%1$s\" class=\"%2$s\" title=\"View issue\">Issue %3$d</a>, %4$s" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/IssueComment.php:151 IDF/IssueComment.php:207 | #: IDF/IssueComment.php:151 IDF/IssueComment.php:207 | ||||||
|  | #: IDF/Review/Comment.php:155 IDF/Review/Comment.php:211 | ||||||
| #: IDF/gettexttemplates/idf/wiki/wiki-updated-email.txt.php:6 | #: IDF/gettexttemplates/idf/wiki/wiki-updated-email.txt.php:6 | ||||||
| #: IDF/gettexttemplates/idf/wiki/wiki-updated-email.txt.php:11 | #: IDF/gettexttemplates/idf/wiki/wiki-updated-email.txt.php:11 | ||||||
| #: IDF/gettexttemplates/idf/issues/issue-updated-email.txt.php:13 | #: IDF/gettexttemplates/idf/issues/issue-updated-email.txt.php:13 | ||||||
| @@ -101,6 +104,7 @@ msgid "Summary:" | |||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/IssueComment.php:153 IDF/IssueComment.php:209 | #: IDF/IssueComment.php:153 IDF/IssueComment.php:209 | ||||||
|  | #: IDF/Review/Comment.php:157 IDF/Review/Comment.php:213 | ||||||
| #: IDF/gettexttemplates/idf/review/review-created-email.txt.php:6 | #: IDF/gettexttemplates/idf/review/review-created-email.txt.php:6 | ||||||
| #: IDF/gettexttemplates/idf/review/review-updated-email.txt.php:9 | #: IDF/gettexttemplates/idf/review/review-updated-email.txt.php:9 | ||||||
| #: IDF/gettexttemplates/idf/issues/issue-updated-email.txt.php:7 | #: IDF/gettexttemplates/idf/issues/issue-updated-email.txt.php:7 | ||||||
| @@ -112,6 +116,7 @@ msgid "Status:" | |||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/IssueComment.php:155 IDF/IssueComment.php:211 | #: IDF/IssueComment.php:155 IDF/IssueComment.php:211 | ||||||
|  | #: IDF/Review/Comment.php:159 IDF/Review/Comment.php:215 | ||||||
| #: IDF/gettexttemplates/idf/issues/issue-updated-email.txt.php:15 | #: IDF/gettexttemplates/idf/issues/issue-updated-email.txt.php:15 | ||||||
| #: IDF/gettexttemplates/idf/issues/view.html.php:12 | #: IDF/gettexttemplates/idf/issues/view.html.php:12 | ||||||
| #: IDF/gettexttemplates/idf/issues/view.html.php:22 | #: IDF/gettexttemplates/idf/issues/view.html.php:22 | ||||||
| @@ -119,6 +124,7 @@ msgid "Owner:" | |||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/IssueComment.php:157 IDF/IssueComment.php:213 IDF/WikiRevision.php:175 | #: IDF/IssueComment.php:157 IDF/IssueComment.php:213 IDF/WikiRevision.php:175 | ||||||
|  | #: IDF/Review/Comment.php:161 IDF/Review/Comment.php:217 | ||||||
| #: IDF/gettexttemplates/idf/wiki/view.html.php:15 | #: IDF/gettexttemplates/idf/wiki/view.html.php:15 | ||||||
| #: IDF/gettexttemplates/idf/wiki/wiki-created-email.txt.php:7 | #: IDF/gettexttemplates/idf/wiki/wiki-created-email.txt.php:7 | ||||||
| #: IDF/gettexttemplates/idf/wiki/delete.html.php:13 | #: IDF/gettexttemplates/idf/wiki/delete.html.php:13 | ||||||
| @@ -131,7 +137,7 @@ msgstr "" | |||||||
| #: IDF/gettexttemplates/idf/issues/view.html.php:13 | #: IDF/gettexttemplates/idf/issues/view.html.php:13 | ||||||
| #: IDF/gettexttemplates/idf/issues/view.html.php:24 | #: IDF/gettexttemplates/idf/issues/view.html.php:24 | ||||||
| #: IDF/gettexttemplates/idf/issues/issue-created-email.txt.php:9 | #: IDF/gettexttemplates/idf/issues/issue-created-email.txt.php:9 | ||||||
| #: IDF/gettexttemplates/idf/downloads/view.html.php:15 | #: IDF/gettexttemplates/idf/downloads/view.html.php:16 | ||||||
| #: IDF/gettexttemplates/idf/downloads/delete.html.php:11 | #: IDF/gettexttemplates/idf/downloads/delete.html.php:11 | ||||||
| #: IDF/gettexttemplates/idf/downloads/download-created-email.txt.php:7 | #: IDF/gettexttemplates/idf/downloads/download-created-email.txt.php:7 | ||||||
| msgid "Labels:" | msgid "Labels:" | ||||||
| @@ -139,10 +145,10 @@ msgstr "" | |||||||
|  |  | ||||||
| #: IDF/IssueComment.php:173 | #: IDF/IssueComment.php:173 | ||||||
| #, php-format | #, php-format | ||||||
| msgid "Comment on <a href=\"%s\" class=\"%s\">issue %d</a>" | msgid "Comment on <a href=\"%s\" class=\"%s\">issue %d</a>, by %s" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/IssueComment.php:195 | #: IDF/IssueComment.php:195 IDF/Review/Comment.php:199 | ||||||
| #, php-format | #, php-format | ||||||
| msgid "%s: Comment on issue %d - %s" | msgid "%s: Comment on issue %d - %s" | ||||||
| msgstr "" | msgstr "" | ||||||
| @@ -172,7 +178,7 @@ msgid "Other" | |||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/IssueFile.php:102 IDF/Issue.php:111 IDF/Review.php:105 | #: IDF/IssueFile.php:102 IDF/Issue.php:111 IDF/Review.php:105 | ||||||
| #: IDF/Upload.php:106 IDF/WikiPage.php:106 | #: IDF/Upload.php:112 IDF/WikiPage.php:106 | ||||||
| msgid "modification date" | msgid "modification date" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| @@ -189,7 +195,7 @@ msgid "" | |||||||
| "Interested users will get an email notification when the issue is changed." | "Interested users will get an email notification when the issue is changed." | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Issue.php:92 IDF/Review.php:86 IDF/Upload.php:87 IDF/WikiPage.php:94 | #: IDF/Issue.php:92 IDF/Review.php:86 IDF/Upload.php:93 IDF/WikiPage.php:94 | ||||||
| msgid "labels" | msgid "labels" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| @@ -199,7 +205,7 @@ msgstr "" | |||||||
|  |  | ||||||
| #: IDF/Issue.php:196 | #: IDF/Issue.php:196 | ||||||
| #, php-format | #, php-format | ||||||
| msgid "Creation of <a href=\"%s\" class=\"%s\">issue %d</a>" | msgid "Creation of <a href=\"%s\" class=\"%s\">issue %d</a>, by %s" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Issue.php:215 | #: IDF/Issue.php:215 | ||||||
| @@ -270,33 +276,33 @@ msgstr "" | |||||||
| msgid "Lower case version of the name for fast searching." | msgid "Lower case version of the name for fast searching." | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Upload.php:64 | #: IDF/Upload.php:70 | ||||||
| msgid "file" | msgid "file" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Upload.php:65 | #: IDF/Upload.php:71 | ||||||
| msgid "The path is relative to the upload path." | msgid "The path is relative to the upload path." | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Upload.php:72 | #: IDF/Upload.php:78 | ||||||
| msgid "file size in bytes" | msgid "file size in bytes" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Upload.php:94 | #: IDF/Upload.php:100 | ||||||
| msgid "number of downloads" | msgid "number of downloads" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Upload.php:182 | #: IDF/Upload.php:189 | ||||||
| #, php-format | #, php-format | ||||||
| msgid "<a href=\"%1$s\" title=\"View download\">Download %2$d</a>, %3$s" | msgid "<a href=\"%1$s\" title=\"View download\">Download %2$d</a>, %3$s" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Upload.php:185 | #: IDF/Upload.php:192 | ||||||
| #, php-format | #, php-format | ||||||
| msgid "Addition of <a href=\"%s\">download %d</a>" | msgid "Addition of <a href=\"%s\">download %d</a>, by %s" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Upload.php:203 | #: IDF/Upload.php:210 | ||||||
| #, php-format | #, php-format | ||||||
| msgid "%s: Download %d added - %s" | msgid "%s: Download %d added - %s" | ||||||
| msgstr "" | msgstr "" | ||||||
| @@ -361,7 +367,7 @@ msgstr "" | |||||||
|  |  | ||||||
| #: IDF/WikiPage.php:199 | #: IDF/WikiPage.php:199 | ||||||
| #, php-format | #, php-format | ||||||
| msgid "Creation of <a href=\"%s\">page %s</a>" | msgid "Creation of <a href=\"%s\">page %s</a>, by %s" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/WikiPage.php:218 | #: IDF/WikiPage.php:218 | ||||||
| @@ -383,7 +389,7 @@ msgstr "" | |||||||
|  |  | ||||||
| #: IDF/WikiRevision.php:189 | #: IDF/WikiRevision.php:189 | ||||||
| #, php-format | #, php-format | ||||||
| msgid "Change of <a href=\"%s\">%s</a>" | msgid "Change of <a href=\"%s\">%s</a>, by %s" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/WikiRevision.php:209 | #: IDF/WikiRevision.php:209 | ||||||
| @@ -427,6 +433,16 @@ msgstr "" | |||||||
| msgid "patch" | msgid "patch" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
|  | #: IDF/Review/Comment.php:177 | ||||||
|  | #, php-format | ||||||
|  | msgid "Comment on <a href=\"%s\" class=\"%s\">issue %d</a>" | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
|  | #: IDF/Review/Comment.php:177 | ||||||
|  | #: IDF/gettexttemplates/idf/source/changelog.html.php:6 | ||||||
|  | msgid "by" | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Plugin/SyncSvn.php:75 IDF/Plugin/SyncMercurial.php:75 | #: IDF/Plugin/SyncSvn.php:75 IDF/Plugin/SyncMercurial.php:75 | ||||||
| #, php-format | #, php-format | ||||||
| msgid "The repository %s already exists." | msgid "The repository %s already exists." | ||||||
| @@ -452,8 +468,8 @@ msgstr "" | |||||||
|  |  | ||||||
| #: IDF/Views/Wiki.php:62 IDF/Views/Wiki.php:109 IDF/Views/Wiki.php:150 | #: IDF/Views/Wiki.php:62 IDF/Views/Wiki.php:109 IDF/Views/Wiki.php:150 | ||||||
| #: IDF/Views/Review.php:58 IDF/Views/User.php:83 IDF/Views/Issue.php:61 | #: IDF/Views/Review.php:58 IDF/Views/User.php:83 IDF/Views/Issue.php:61 | ||||||
| #: IDF/Views/Issue.php:137 IDF/Views/Issue.php:249 IDF/Views/Issue.php:442 | #: IDF/Views/Issue.php:137 IDF/Views/Issue.php:247 IDF/Views/Issue.php:436 | ||||||
| #: IDF/Views/Issue.php:500 IDF/Views/Download.php:65 | #: IDF/Views/Issue.php:494 IDF/Views/Download.php:65 | ||||||
| #: IDF/Views/Download.php:272 IDF/Form/Upload.php:40 | #: IDF/Views/Download.php:272 IDF/Form/Upload.php:40 | ||||||
| #: IDF/Form/UpdateUpload.php:42 IDF/Form/IssueCreate.php:50 | #: IDF/Form/UpdateUpload.php:42 IDF/Form/IssueCreate.php:50 | ||||||
| #: IDF/Form/IssueUpdate.php:45 IDF/Form/ReviewCreate.php:45 | #: IDF/Form/IssueUpdate.php:45 IDF/Form/ReviewCreate.php:45 | ||||||
| @@ -511,7 +527,7 @@ msgstr "" | |||||||
| msgid "Delete Old Revision of %s" | msgid "Delete Old Revision of %s" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Views/Wiki.php:316 IDF/Views/Admin.php:90 IDF/Views/Admin.php:242 | #: IDF/Views/Wiki.php:316 IDF/Views/Admin.php:93 IDF/Views/Admin.php:245 | ||||||
| #, php-format | #, php-format | ||||||
| msgid "Update %s" | msgid "Update %s" | ||||||
| msgstr "" | msgstr "" | ||||||
| @@ -555,7 +571,7 @@ msgstr "" | |||||||
| msgid "%s Project Summary" | msgid "%s Project Summary" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Views/Project.php:221 IDF/Views/Admin.php:98 | #: IDF/Views/Project.php:221 IDF/Views/Admin.php:101 | ||||||
| msgid "The project has been updated." | msgid "The project has been updated." | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| @@ -635,21 +651,21 @@ msgid "This table shows the latest reviews." | |||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Views/Review.php:57 IDF/Views/User.php:81 IDF/Views/Issue.php:60 | #: IDF/Views/Review.php:57 IDF/Views/User.php:81 IDF/Views/Issue.php:60 | ||||||
| #: IDF/Views/Issue.php:136 IDF/Views/Issue.php:248 IDF/Views/Issue.php:441 | #: IDF/Views/Issue.php:136 IDF/Views/Issue.php:246 IDF/Views/Issue.php:435 | ||||||
| #: IDF/Views/Issue.php:499 | #: IDF/Views/Issue.php:493 | ||||||
| msgid "Id" | msgid "Id" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Views/Review.php:59 IDF/Views/User.php:84 IDF/Views/Issue.php:62 | #: IDF/Views/Review.php:59 IDF/Views/User.php:84 IDF/Views/Issue.php:62 | ||||||
| #: IDF/Views/Issue.php:138 IDF/Views/Issue.php:250 IDF/Views/Issue.php:443 | #: IDF/Views/Issue.php:138 IDF/Views/Issue.php:248 IDF/Views/Issue.php:437 | ||||||
| #: IDF/Views/Issue.php:501 IDF/Form/IssueCreate.php:92 | #: IDF/Views/Issue.php:495 IDF/Form/IssueCreate.php:92 | ||||||
| #: IDF/Form/IssueUpdate.php:88 IDF/Form/ReviewCreate.php:101 | #: IDF/Form/IssueUpdate.php:88 IDF/Form/ReviewCreate.php:103 | ||||||
| msgid "Status" | msgid "Status" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Views/Review.php:60 IDF/Views/User.php:85 IDF/Views/Issue.php:63 | #: IDF/Views/Review.php:60 IDF/Views/User.php:85 IDF/Views/Issue.php:63 | ||||||
| #: IDF/Views/Issue.php:139 IDF/Views/Issue.php:251 IDF/Views/Issue.php:444 | #: IDF/Views/Issue.php:139 IDF/Views/Issue.php:249 IDF/Views/Issue.php:438 | ||||||
| #: IDF/Views/Issue.php:502 | #: IDF/Views/Issue.php:496 | ||||||
| msgid "Last Updated" | msgid "Last Updated" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| @@ -732,27 +748,27 @@ msgstr "" | |||||||
| msgid "Your new email address \"%s\" has been validated. Thank you!" | msgid "Your new email address \"%s\" has been validated. Thank you!" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Views/Source.php:46 | #: IDF/Views/Source.php:50 | ||||||
| #, php-format | #, php-format | ||||||
| msgid "%s Source Help" | msgid "%s Source Help" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Views/Source.php:61 | #: IDF/Views/Source.php:65 | ||||||
| #, php-format | #, php-format | ||||||
| msgid "%1$s %2$s Change Log" | msgid "%1$s %2$s Change Log" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Views/Source.php:102 IDF/Views/Source.php:151 IDF/Views/Source.php:312 | #: IDF/Views/Source.php:108 IDF/Views/Source.php:152 IDF/Views/Source.php:318 | ||||||
| #, php-format | #, php-format | ||||||
| msgid "%1$s %2$s Source Tree" | msgid "%1$s %2$s Source Tree" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Views/Source.php:265 | #: IDF/Views/Source.php:269 | ||||||
| #, php-format | #, php-format | ||||||
| msgid "%s Commit Details" | msgid "%s Commit Details" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Views/Source.php:266 | #: IDF/Views/Source.php:270 | ||||||
| #, php-format | #, php-format | ||||||
| msgid "%s Commit Details - %s" | msgid "%s Commit Details - %s" | ||||||
| msgstr "" | msgstr "" | ||||||
| @@ -762,8 +778,8 @@ msgstr "" | |||||||
| msgid "%s Open Issues" | msgid "%s Open Issues" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Views/Issue.php:67 IDF/Views/Issue.php:143 IDF/Views/Issue.php:255 | #: IDF/Views/Issue.php:67 IDF/Views/Issue.php:143 IDF/Views/Issue.php:253 | ||||||
| #: IDF/Views/Issue.php:448 IDF/Views/Issue.php:506 | #: IDF/Views/Issue.php:442 IDF/Views/Issue.php:500 | ||||||
| msgid "No issues were found." | msgid "No issues were found." | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| @@ -791,78 +807,78 @@ msgstr "" | |||||||
| msgid "Submit a new issue" | msgid "Submit a new issue" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Views/Issue.php:178 | #: IDF/Views/Issue.php:194 | ||||||
| #, php-format |  | ||||||
| msgid "<a href=\"%s\">Issue %d</a> has been created." |  | ||||||
| msgstr "" |  | ||||||
|  |  | ||||||
| #: IDF/Views/Issue.php:197 |  | ||||||
| #, php-format | #, php-format | ||||||
| msgid "Issue %s - %s (%s)" | msgid "Issue %s - %s (%s)" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Views/Issue.php:232 | #: IDF/Views/Issue.php:201 | ||||||
|  | #, php-format | ||||||
|  | msgid "<a href=\"%s\">Issue %d</a> has been created." | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
|  | #: IDF/Views/Issue.php:230 | ||||||
| #, php-format | #, php-format | ||||||
| msgid "Search Issues - %s" | msgid "Search Issues - %s" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Views/Issue.php:244 | #: IDF/Views/Issue.php:242 | ||||||
| msgid "This table shows the found issues." | msgid "This table shows the found issues." | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Views/Issue.php:274 | #: IDF/Views/Issue.php:272 | ||||||
| #, php-format | #, php-format | ||||||
| msgid "Issue <a href=\"%s\">%d</a>: %s" | msgid "Issue <a href=\"%s\">%d</a>: %s" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Views/Issue.php:298 | #: IDF/Views/Issue.php:322 | ||||||
| #, php-format |  | ||||||
| msgid "<a href=\"%s\">Issue %d</a> has been updated." |  | ||||||
| msgstr "" |  | ||||||
|  |  | ||||||
| #: IDF/Views/Issue.php:329 |  | ||||||
| #, php-format | #, php-format | ||||||
| msgid "Updated Issue %s - %s (%s)" | msgid "Updated Issue %s - %s (%s)" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Views/Issue.php:402 | #: IDF/Views/Issue.php:330 | ||||||
|  | #, php-format | ||||||
|  | msgid "<a href=\"%s\">Issue %d</a> has been updated." | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
|  | #: IDF/Views/Issue.php:396 | ||||||
| #, php-format | #, php-format | ||||||
| msgid "View %s" | msgid "View %s" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Views/Issue.php:422 | #: IDF/Views/Issue.php:416 | ||||||
| #, php-format | #, php-format | ||||||
| msgid "%s Closed Issues" | msgid "%s Closed Issues" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Views/Issue.php:432 | #: IDF/Views/Issue.php:426 | ||||||
| msgid "This table shows the closed issues." | msgid "This table shows the closed issues." | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Views/Issue.php:474 | #: IDF/Views/Issue.php:468 | ||||||
| #, php-format | #, php-format | ||||||
| msgid "%1$s Issues with Label %2$s" | msgid "%1$s Issues with Label %2$s" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Views/Issue.php:477 | #: IDF/Views/Issue.php:471 | ||||||
| #, php-format | #, php-format | ||||||
| msgid "%1$s Closed Issues with Label %2$s" | msgid "%1$s Closed Issues with Label %2$s" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Views/Issue.php:490 | #: IDF/Views/Issue.php:484 | ||||||
| #, php-format | #, php-format | ||||||
| msgid "This table shows the issues with label %s." | msgid "This table shows the issues with label %s." | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Views/Issue.php:539 | #: IDF/Views/Issue.php:533 | ||||||
| msgid "The issue has been removed from your watch list." | msgid "The issue has been removed from your watch list." | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Views/Issue.php:542 | #: IDF/Views/Issue.php:536 | ||||||
| msgid "The issue has been added to your watch list." | msgid "The issue has been added to your watch list." | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Views/Issue.php:620 | #: IDF/Views/Issue.php:614 | ||||||
| msgid "On your watch list." | msgid "On your watch list." | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| @@ -875,7 +891,7 @@ msgstr "" | |||||||
| msgid "This table shows the files to download." | msgid "This table shows the files to download." | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Views/Download.php:64 IDF/Views/Download.php:271 IDF/Form/Upload.php:49 | #: IDF/Views/Download.php:64 IDF/Views/Download.php:271 IDF/Form/Upload.php:59 | ||||||
| #: IDF/gettexttemplates/idf/source/mercurial/tree.html.php:6 | #: IDF/gettexttemplates/idf/source/mercurial/tree.html.php:6 | ||||||
| #: IDF/gettexttemplates/idf/source/svn/tree.html.php:6 | #: IDF/gettexttemplates/idf/source/svn/tree.html.php:6 | ||||||
| #: IDF/gettexttemplates/idf/source/git/tree.html.php:6 | #: IDF/gettexttemplates/idf/source/git/tree.html.php:6 | ||||||
| @@ -952,85 +968,89 @@ msgstr "" | |||||||
| msgid "Short Name" | msgid "Short Name" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Views/Admin.php:66 IDF/Views/Admin.php:203 | #: IDF/Views/Admin.php:66 IDF/Views/Admin.php:206 | ||||||
| #: IDF/Form/Admin/ProjectCreate.php:48 IDF/Form/Admin/ProjectUpdate.php:42 | #: IDF/Form/Admin/ProjectCreate.php:48 IDF/Form/Admin/ProjectUpdate.php:42 | ||||||
| msgid "Name" | msgid "Name" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Views/Admin.php:71 | #: IDF/Views/Admin.php:67 | ||||||
|  | msgid "Repository Size" | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
|  | #: IDF/Views/Admin.php:73 | ||||||
| msgid "No projects were found." | msgid "No projects were found." | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Views/Admin.php:122 | #: IDF/Views/Admin.php:125 | ||||||
| #: IDF/gettexttemplates/idf/gadmin/projects/base.html.php:4 | #: IDF/gettexttemplates/idf/gadmin/projects/base.html.php:4 | ||||||
| #: IDF/gettexttemplates/idf/gadmin/projects/create.html.php:16 | #: IDF/gettexttemplates/idf/gadmin/projects/create.html.php:16 | ||||||
| #: IDF/gettexttemplates/idf/index.html.php:5 | #: IDF/gettexttemplates/idf/index.html.php:5 | ||||||
| msgid "Create Project" | msgid "Create Project" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Views/Admin.php:128 | #: IDF/Views/Admin.php:131 | ||||||
| msgid "The project has been created." | msgid "The project has been created." | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Views/Admin.php:154 | #: IDF/Views/Admin.php:157 | ||||||
| #, php-format | #, php-format | ||||||
| msgid "Delete %s Project" | msgid "Delete %s Project" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Views/Admin.php:161 | #: IDF/Views/Admin.php:164 | ||||||
| msgid "The project has been deleted." | msgid "The project has been deleted." | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Views/Admin.php:191 | #: IDF/Views/Admin.php:194 | ||||||
| msgid "Not Validated User List" | msgid "Not Validated User List" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Views/Admin.php:194 | #: IDF/Views/Admin.php:197 | ||||||
| #: IDF/gettexttemplates/idf/gadmin/users/base.html.php:3 | #: IDF/gettexttemplates/idf/gadmin/users/base.html.php:3 | ||||||
| msgid "User List" | msgid "User List" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Views/Admin.php:197 | #: IDF/Views/Admin.php:200 | ||||||
| msgid "This table shows the users in the forge." | msgid "This table shows the users in the forge." | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Views/Admin.php:202 | #: IDF/Views/Admin.php:205 | ||||||
| msgid "login" | msgid "login" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Views/Admin.php:204 IDF/Form/Admin/UserUpdate.php:99 | #: IDF/Views/Admin.php:207 IDF/Form/Admin/UserUpdate.php:99 | ||||||
| msgid "Staff" | msgid "Staff" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Views/Admin.php:205 | #: IDF/Views/Admin.php:208 | ||||||
| msgid "Admin" | msgid "Admin" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Views/Admin.php:206 IDF/Form/Admin/UserUpdate.php:110 | #: IDF/Views/Admin.php:209 IDF/Form/Admin/UserUpdate.php:110 | ||||||
| msgid "Active" | msgid "Active" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Views/Admin.php:207 | #: IDF/Views/Admin.php:210 | ||||||
| msgid "Last Login" | msgid "Last Login" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Views/Admin.php:212 | #: IDF/Views/Admin.php:215 | ||||||
| msgid "No users were found." | msgid "No users were found." | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Views/Admin.php:249 | #: IDF/Views/Admin.php:252 | ||||||
| msgid "You do not have the rights to update this user." | msgid "You do not have the rights to update this user." | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Views/Admin.php:265 | #: IDF/Views/Admin.php:268 | ||||||
| msgid "The user has been updated." | msgid "The user has been updated." | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Views/Admin.php:284 IDF/gettexttemplates/idf/login_form.html.php:7 | #: IDF/Views/Admin.php:287 IDF/gettexttemplates/idf/login_form.html.php:7 | ||||||
| msgid "Yes" | msgid "Yes" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Views/Admin.php:284 | #: IDF/Views/Admin.php:287 | ||||||
| msgid "No" | msgid "No" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| @@ -1045,44 +1065,51 @@ msgid "" | |||||||
| "email." | "email." | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Form/UserChangeEmail.php:80 IDF/Form/Upload.php:137 | #: IDF/Form/UserChangeEmail.php:80 IDF/Form/Upload.php:147 | ||||||
| #: IDF/Form/Register.php:114 IDF/Form/UserAccount.php:119 | #: IDF/Form/Register.php:114 IDF/Form/UserAccount.php:119 | ||||||
| #: IDF/Form/Admin/ProjectCreate.php:205 IDF/Form/Admin/ProjectUpdate.php:67 | #: IDF/Form/Admin/ProjectCreate.php:215 IDF/Form/Admin/ProjectUpdate.php:77 | ||||||
| #: IDF/Form/Admin/UserUpdate.php:129 IDF/Form/Admin/ProjectDelete.php:78 | #: IDF/Form/Admin/UserUpdate.php:129 IDF/Form/Admin/ProjectDelete.php:78 | ||||||
| #: IDF/Form/UpdateUpload.php:116 IDF/Form/WikiUpdate.php:178 | #: IDF/Form/UpdateUpload.php:126 IDF/Form/WikiUpdate.php:178 | ||||||
| #: IDF/Form/TabsConf.php:92 IDF/Form/ReviewCommentFile.php:166 | #: IDF/Form/TabsConf.php:97 IDF/Form/ReviewCommentFile.php:166 | ||||||
| #: IDF/Form/IssueCreate.php:233 IDF/Form/Password.php:61 | #: IDF/Form/IssueCreate.php:233 IDF/Form/Password.php:61 | ||||||
| #: IDF/Form/IssueUpdate.php:232 IDF/Form/ReviewFileComment.php:77 | #: IDF/Form/IssueUpdate.php:232 IDF/Form/ReviewFileComment.php:77 | ||||||
| #: IDF/Form/WikiCreate.php:167 IDF/Form/MembersConf.php:64 | #: IDF/Form/WikiCreate.php:167 IDF/Form/MembersConf.php:64 | ||||||
| #: IDF/Form/ReviewCreate.php:185 | #: IDF/Form/ReviewCreate.php:187 | ||||||
| msgid "Cannot save the model from an invalid form." | msgid "Cannot save the model from an invalid form." | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Form/Upload.php:60 IDF/Form/UpdateUpload.php:61 | #: IDF/Form/Upload.php:49 IDF/Form/UpdateUpload.php:51 | ||||||
|  | #: IDF/Form/WikiUpdate.php:60 IDF/Form/ReviewCommentFile.php:69 | ||||||
|  | #: IDF/Form/IssueCreate.php:59 IDF/Form/WikiCreate.php:70 | ||||||
|  | #: IDF/Form/ReviewCreate.php:54 | ||||||
|  | msgid "Description" | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
|  | #: IDF/Form/Upload.php:70 IDF/Form/UpdateUpload.php:71 | ||||||
| #: IDF/Form/WikiUpdate.php:104 IDF/Form/ReviewCommentFile.php:92 | #: IDF/Form/WikiUpdate.php:104 IDF/Form/ReviewCommentFile.php:92 | ||||||
| #: IDF/Form/IssueCreate.php:120 IDF/Form/IssueUpdate.php:117 | #: IDF/Form/IssueCreate.php:120 IDF/Form/IssueUpdate.php:117 | ||||||
| #: IDF/Form/WikiCreate.php:93 | #: IDF/Form/WikiCreate.php:93 | ||||||
| msgid "Labels" | msgid "Labels" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Form/Upload.php:75 | #: IDF/Form/Upload.php:85 | ||||||
| msgid "For security reason, you cannot upload a file with this extension." | msgid "For security reason, you cannot upload a file with this extension." | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Form/Upload.php:108 IDF/Form/UpdateUpload.php:99 | #: IDF/Form/Upload.php:118 IDF/Form/UpdateUpload.php:109 | ||||||
| #: IDF/Form/IssueCreate.php:169 | #: IDF/Form/IssueCreate.php:169 | ||||||
| #, php-format | #, php-format | ||||||
| msgid "You cannot provide more than label from the %s class to an issue." | msgid "You cannot provide more than label from the %s class to an issue." | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Form/Upload.php:109 IDF/Form/UpdateUpload.php:100 | #: IDF/Form/Upload.php:119 IDF/Form/UpdateUpload.php:110 | ||||||
| #: IDF/Form/WikiUpdate.php:162 IDF/Form/ReviewCommentFile.php:150 | #: IDF/Form/WikiUpdate.php:162 IDF/Form/ReviewCommentFile.php:150 | ||||||
| #: IDF/Form/IssueCreate.php:163 IDF/Form/IssueCreate.php:170 | #: IDF/Form/IssueCreate.php:163 IDF/Form/IssueCreate.php:170 | ||||||
| #: IDF/Form/WikiCreate.php:151 | #: IDF/Form/WikiCreate.php:151 | ||||||
| msgid "You provided an invalid label." | msgid "You provided an invalid label." | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Form/Upload.php:176 | #: IDF/Form/Upload.php:187 | ||||||
| #, php-format | #, php-format | ||||||
| msgid "New download - %s (%s)" | msgid "New download - %s (%s)" | ||||||
| msgstr "" | msgstr "" | ||||||
| @@ -1230,7 +1257,7 @@ msgstr "" | |||||||
| msgid "The email \"%s\" is already used." | msgid "The email \"%s\" is already used." | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Form/UserAccount.php:240 IDF/Form/Admin/UserUpdate.php:211 | #: IDF/Form/UserAccount.php:240 IDF/Form/Admin/UserUpdate.php:214 | ||||||
| msgid "The passwords do not match. Please give them again." | msgid "The passwords do not match. Please give them again." | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| @@ -1264,7 +1291,8 @@ msgstr "" | |||||||
|  |  | ||||||
| #: IDF/Form/Admin/ProjectCreate.php:63 | #: IDF/Form/Admin/ProjectCreate.php:63 | ||||||
| msgid "" | msgid "" | ||||||
| "It must be unique for each project and composed only of letters and digits." | "It must be unique for each project and composed only of letters, digits and " | ||||||
|  | "dash (-) like \"my-project\"." | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Form/Admin/ProjectCreate.php:68 | #: IDF/Form/Admin/ProjectCreate.php:68 | ||||||
| @@ -1293,31 +1321,31 @@ msgstr "" | |||||||
| msgid "Project members" | msgid "Project members" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Form/Admin/ProjectCreate.php:144 | #: IDF/Form/Admin/ProjectCreate.php:154 | ||||||
| msgid "" | msgid "" | ||||||
| "Only a remote repository available throught http or https are allowed. For " | "Only a remote repository available throught http or https are allowed. For " | ||||||
| "example \"http://somewhere.com/svn/trunk\"." | "example \"http://somewhere.com/svn/trunk\"." | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Form/Admin/ProjectCreate.php:153 | #: IDF/Form/Admin/ProjectCreate.php:163 | ||||||
| msgid "" | msgid "" | ||||||
| "This shortname contains illegal characters, please use only letters and " | "This shortname contains illegal characters, please use only letters, digits " | ||||||
| "digits." | "and dash (-)." | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Form/Admin/ProjectCreate.php:156 | #: IDF/Form/Admin/ProjectCreate.php:166 | ||||||
| msgid "The shortname cannot start with the dash (-) character." | msgid "The shortname cannot start with the dash (-) character." | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Form/Admin/ProjectCreate.php:159 | #: IDF/Form/Admin/ProjectCreate.php:169 | ||||||
| msgid "The shortname cannot end with the dash (-) character." | msgid "The shortname cannot end with the dash (-) character." | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Form/Admin/ProjectCreate.php:164 | #: IDF/Form/Admin/ProjectCreate.php:174 | ||||||
| msgid "This shortname is already used. Please select another one." | msgid "This shortname is already used. Please select another one." | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Form/Admin/ProjectCreate.php:211 | #: IDF/Form/Admin/ProjectCreate.php:221 | ||||||
| msgid "Click on the Administer tab to set the description of your project." | msgid "Click on the Administer tab to set the description of your project." | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| @@ -1353,7 +1381,11 @@ msgid "" | |||||||
| "you can directly enable or disable his account here." | "you can directly enable or disable his account here." | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Form/Admin/UserUpdate.php:196 | #: IDF/Form/Admin/UserUpdate.php:183 | ||||||
|  | msgid "--- is not a valid first name." | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
|  | #: IDF/Form/Admin/UserUpdate.php:199 | ||||||
| msgid "" | msgid "" | ||||||
| "A user with this email already exists, please provide another email address." | "A user with this email already exists, please provide another email address." | ||||||
| msgstr "" | msgstr "" | ||||||
| @@ -1387,12 +1419,6 @@ msgid "" | |||||||
| "The page name must contains only letters, digits and the dash (-) character." | "The page name must contains only letters, digits and the dash (-) character." | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Form/WikiUpdate.php:60 IDF/Form/ReviewCommentFile.php:69 |  | ||||||
| #: IDF/Form/IssueCreate.php:59 IDF/Form/WikiCreate.php:70 |  | ||||||
| #: IDF/Form/ReviewCreate.php:54 |  | ||||||
| msgid "Description" |  | ||||||
| msgstr "" |  | ||||||
|  |  | ||||||
| #: IDF/Form/WikiUpdate.php:61 IDF/Form/ReviewCommentFile.php:70 | #: IDF/Form/WikiUpdate.php:61 IDF/Form/ReviewCommentFile.php:70 | ||||||
| #: IDF/Form/WikiCreate.php:71 | #: IDF/Form/WikiCreate.php:71 | ||||||
| msgid "This one line description is displayed in the list of pages." | msgid "This one line description is displayed in the list of pages." | ||||||
| @@ -1507,7 +1533,7 @@ msgid "Initial page creation" | |||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Form/IssueCreate.php:69 IDF/Form/IssueUpdate.php:65 | #: IDF/Form/IssueCreate.php:69 IDF/Form/IssueUpdate.php:65 | ||||||
| #: IDF/Form/ReviewCreate.php:81 | #: IDF/Form/ReviewCreate.php:83 | ||||||
| msgid "The \"upload_issue_path\" configuration variable was not set." | msgid "The \"upload_issue_path\" configuration variable was not set." | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| @@ -1527,7 +1553,7 @@ msgstr "" | |||||||
| msgid "You need to provide a description of the issue." | msgid "You need to provide a description of the issue." | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Form/IssueCreate.php:203 IDF/Form/ReviewCreate.php:157 | #: IDF/Form/IssueCreate.php:203 IDF/Form/ReviewCreate.php:159 | ||||||
| msgid "You provided an invalid status." | msgid "You provided an invalid status." | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| @@ -1562,6 +1588,13 @@ msgstr "" | |||||||
| msgid "New Documentation Page %s - %s (%s)" | msgid "New Documentation Page %s - %s (%s)" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
|  | #: IDF/Form/MembersConf.php:104 | ||||||
|  | #, php-format | ||||||
|  | msgid "The following login is invalid: %s." | ||||||
|  | msgid_plural "The following login are invalids: %s." | ||||||
|  | msgstr[0] "" | ||||||
|  | msgstr[1] "" | ||||||
|  |  | ||||||
| #: IDF/Form/WikiConf.php:49 | #: IDF/Form/WikiConf.php:49 | ||||||
| msgid "Predefined documentation page labels" | msgid "Predefined documentation page labels" | ||||||
| msgstr "" | msgstr "" | ||||||
| @@ -1587,33 +1620,33 @@ msgstr "" | |||||||
| msgid "Each issue may have at most one label with each of these classes" | msgid "Each issue may have at most one label with each of these classes" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Form/ReviewCreate.php:90 | #: IDF/Form/ReviewCreate.php:92 | ||||||
| msgid "Patch" | msgid "Patch" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Form/ReviewCreate.php:117 | #: IDF/Form/ReviewCreate.php:119 | ||||||
| msgid "We were not able to parse your patch. Please provide a valid patch." | msgid "We were not able to parse your patch. Please provide a valid patch." | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Form/ReviewCreate.php:126 | #: IDF/Form/ReviewCreate.php:128 | ||||||
| msgid "You provided an invalid commit." | msgid "You provided an invalid commit." | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Form/ReviewCreate.php:200 | #: IDF/Form/ReviewCreate.php:202 | ||||||
| msgid "Initial patch to be reviewed." | msgid "Initial patch to be reviewed." | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Form/ReviewCreate.php:220 | #: IDF/Form/ReviewCreate.php:222 | ||||||
| #, php-format | #, php-format | ||||||
| msgid "New Code Review %s - %s (%s)" | msgid "New Code Review %s - %s (%s)" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Scm/Mercurial.php:123 IDF/Scm/Git.php:137 | #: IDF/Scm/Mercurial.php:125 IDF/Scm/Git.php:145 | ||||||
| #, php-format | #, php-format | ||||||
| msgid "Folder %1$s not found in commit %2$s." | msgid "Folder %1$s not found in commit %2$s." | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/Scm/Mercurial.php:140 IDF/Scm/Git.php:187 | #: IDF/Scm/Mercurial.php:142 IDF/Scm/Git.php:245 | ||||||
| #, php-format | #, php-format | ||||||
| msgid "Not a valid tree: %s." | msgid "Not a valid tree: %s." | ||||||
| msgstr "" | msgstr "" | ||||||
| @@ -1787,6 +1820,10 @@ msgstr "" | |||||||
| msgid "Change Log" | msgid "Change Log" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
|  | #: IDF/gettexttemplates/idf/source/base.html.php:6 | ||||||
|  | msgid "How To Get The Code" | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/gettexttemplates/idf/source/mercurial/file.html.php:3 | #: IDF/gettexttemplates/idf/source/mercurial/file.html.php:3 | ||||||
| #: IDF/gettexttemplates/idf/source/mercurial/tree.html.php:3 | #: IDF/gettexttemplates/idf/source/mercurial/tree.html.php:3 | ||||||
| #: IDF/gettexttemplates/idf/source/svn/file.html.php:3 | #: IDF/gettexttemplates/idf/source/svn/file.html.php:3 | ||||||
| @@ -1838,6 +1875,7 @@ msgstr "" | |||||||
|  |  | ||||||
| #: IDF/gettexttemplates/idf/source/mercurial/file.html.php:8 | #: IDF/gettexttemplates/idf/source/mercurial/file.html.php:8 | ||||||
| #: IDF/gettexttemplates/idf/source/mercurial/tree.html.php:15 | #: IDF/gettexttemplates/idf/source/mercurial/tree.html.php:15 | ||||||
|  | #: IDF/gettexttemplates/idf/source/svn/tree.html.php:17 | ||||||
| #: IDF/gettexttemplates/idf/source/commit.html.php:13 | #: IDF/gettexttemplates/idf/source/commit.html.php:13 | ||||||
| #: IDF/gettexttemplates/idf/source/git/file.html.php:8 | #: IDF/gettexttemplates/idf/source/git/file.html.php:8 | ||||||
| #: IDF/gettexttemplates/idf/source/git/tree.html.php:15 | #: IDF/gettexttemplates/idf/source/git/tree.html.php:15 | ||||||
| @@ -1924,12 +1962,14 @@ msgstr "" | |||||||
|  |  | ||||||
| #: IDF/gettexttemplates/idf/source/svn/file.html.php:10 | #: IDF/gettexttemplates/idf/source/svn/file.html.php:10 | ||||||
| #: IDF/gettexttemplates/idf/source/svn/tree.html.php:15 | #: IDF/gettexttemplates/idf/source/svn/tree.html.php:15 | ||||||
|  | #: IDF/gettexttemplates/idf/source/commit.html.php:14 | ||||||
| #: IDF/gettexttemplates/idf/source/changelog.html.php:8 | #: IDF/gettexttemplates/idf/source/changelog.html.php:8 | ||||||
| msgid "Revision:" | msgid "Revision:" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/gettexttemplates/idf/source/svn/file.html.php:11 | #: IDF/gettexttemplates/idf/source/svn/file.html.php:11 | ||||||
| #: IDF/gettexttemplates/idf/source/svn/tree.html.php:16 | #: IDF/gettexttemplates/idf/source/svn/tree.html.php:16 | ||||||
|  | #: IDF/gettexttemplates/idf/source/commit.html.php:15 | ||||||
| #: IDF/gettexttemplates/idf/source/changelog.html.php:9 | #: IDF/gettexttemplates/idf/source/changelog.html.php:9 | ||||||
| msgid "Go to revision" | msgid "Go to revision" | ||||||
| msgstr "" | msgstr "" | ||||||
| @@ -2058,9 +2098,9 @@ msgstr "" | |||||||
| #: IDF/gettexttemplates/idf/review/create.html.php:12 | #: IDF/gettexttemplates/idf/review/create.html.php:12 | ||||||
| #: IDF/gettexttemplates/idf/issues/view.html.php:18 | #: IDF/gettexttemplates/idf/issues/view.html.php:18 | ||||||
| #: IDF/gettexttemplates/idf/issues/create.html.php:14 | #: IDF/gettexttemplates/idf/issues/create.html.php:14 | ||||||
| #: IDF/gettexttemplates/idf/downloads/view.html.php:7 | #: IDF/gettexttemplates/idf/downloads/view.html.php:8 | ||||||
| #: IDF/gettexttemplates/idf/downloads/delete.html.php:7 | #: IDF/gettexttemplates/idf/downloads/delete.html.php:7 | ||||||
| #: IDF/gettexttemplates/idf/downloads/submit.html.php:8 | #: IDF/gettexttemplates/idf/downloads/submit.html.php:9 | ||||||
| msgid "Cancel" | msgid "Cancel" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| @@ -2163,7 +2203,7 @@ msgstr "" | |||||||
|  |  | ||||||
| #: IDF/gettexttemplates/idf/gadmin/projects/update.html.php:18 | #: IDF/gettexttemplates/idf/gadmin/projects/update.html.php:18 | ||||||
| #: IDF/gettexttemplates/idf/wiki/view.html.php:11 | #: IDF/gettexttemplates/idf/wiki/view.html.php:11 | ||||||
| #: IDF/gettexttemplates/idf/downloads/view.html.php:9 | #: IDF/gettexttemplates/idf/downloads/view.html.php:10 | ||||||
| msgid "Trash" | msgid "Trash" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| @@ -2229,6 +2269,34 @@ msgstr "" | |||||||
| msgid "Change Project Details" | msgid "Change Project Details" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
|  | #: IDF/gettexttemplates/idf/gadmin/projects/index.html.php:3 | ||||||
|  | msgid "Space Usage Statistics" | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
|  | #: IDF/gettexttemplates/idf/gadmin/projects/index.html.php:4 | ||||||
|  | msgid "Repositories:" | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
|  | #: IDF/gettexttemplates/idf/gadmin/projects/index.html.php:5 | ||||||
|  | #: IDF/gettexttemplates/idf/issues/issue-updated-email.txt.php:17 | ||||||
|  | #: IDF/gettexttemplates/idf/issues/issue-created-email.txt.php:11 | ||||||
|  | msgid "Attachments:" | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
|  | #: IDF/gettexttemplates/idf/gadmin/projects/index.html.php:6 | ||||||
|  | #: IDF/gettexttemplates/idf/downloads/view.html.php:15 | ||||||
|  | #: IDF/gettexttemplates/idf/downloads/delete.html.php:10 | ||||||
|  | msgid "Downloads:" | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
|  | #: IDF/gettexttemplates/idf/gadmin/projects/index.html.php:7 | ||||||
|  | msgid "Database:" | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
|  | #: IDF/gettexttemplates/idf/gadmin/projects/index.html.php:8 | ||||||
|  | msgid "Total Forge:" | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/gettexttemplates/idf/gadmin/projects/create.html.php:3 | #: IDF/gettexttemplates/idf/gadmin/projects/create.html.php:3 | ||||||
| msgid "" | msgid "" | ||||||
| "You can select the type of repository you want. In the case of subversion, " | "You can select the type of repository you want. In the case of subversion, " | ||||||
| @@ -2265,7 +2333,7 @@ msgid "Welcome" | |||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/gettexttemplates/idf/admin/members.html.php:13 | #: IDF/gettexttemplates/idf/admin/members.html.php:13 | ||||||
| #: IDF/gettexttemplates/idf/admin/source.html.php:7 | #: IDF/gettexttemplates/idf/admin/source.html.php:8 | ||||||
| #: IDF/gettexttemplates/idf/admin/tabs.html.php:10 | #: IDF/gettexttemplates/idf/admin/tabs.html.php:10 | ||||||
| #: IDF/gettexttemplates/idf/admin/issue-tracking.html.php:8 | #: IDF/gettexttemplates/idf/admin/issue-tracking.html.php:8 | ||||||
| #: IDF/gettexttemplates/idf/admin/wiki.html.php:8 | #: IDF/gettexttemplates/idf/admin/wiki.html.php:8 | ||||||
| @@ -2292,6 +2360,10 @@ msgstr "" | |||||||
| msgid "Repository access:" | msgid "Repository access:" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
|  | #: IDF/gettexttemplates/idf/admin/source.html.php:7 | ||||||
|  | msgid "Repository size:" | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/gettexttemplates/idf/admin/tabs.html.php:3 | #: IDF/gettexttemplates/idf/admin/tabs.html.php:3 | ||||||
| msgid "" | msgid "" | ||||||
| "You can configure here the project tabs access rights and notification " | "You can configure here the project tabs access rights and notification " | ||||||
| @@ -2426,7 +2498,7 @@ msgstr "" | |||||||
| #: IDF/gettexttemplates/idf/wiki/delete.html.php:12 | #: IDF/gettexttemplates/idf/wiki/delete.html.php:12 | ||||||
| #: IDF/gettexttemplates/idf/review/view.html.php:24 | #: IDF/gettexttemplates/idf/review/view.html.php:24 | ||||||
| #: IDF/gettexttemplates/idf/issues/view.html.php:20 | #: IDF/gettexttemplates/idf/issues/view.html.php:20 | ||||||
| #: IDF/gettexttemplates/idf/downloads/view.html.php:13 | #: IDF/gettexttemplates/idf/downloads/view.html.php:14 | ||||||
| #: IDF/gettexttemplates/idf/downloads/delete.html.php:9 | #: IDF/gettexttemplates/idf/downloads/delete.html.php:9 | ||||||
| msgid "Updated:" | msgid "Updated:" | ||||||
| msgstr "" | msgstr "" | ||||||
| @@ -2582,7 +2654,7 @@ msgstr "" | |||||||
| #: IDF/gettexttemplates/idf/user/passrecovery-inputkey.html.php:6 | #: IDF/gettexttemplates/idf/user/passrecovery-inputkey.html.php:6 | ||||||
| #: IDF/gettexttemplates/idf/user/changeemail.html.php:6 | #: IDF/gettexttemplates/idf/user/changeemail.html.php:6 | ||||||
| #: IDF/gettexttemplates/idf/register/inputkey.html.php:6 | #: IDF/gettexttemplates/idf/register/inputkey.html.php:6 | ||||||
| #: IDF/gettexttemplates/idf/downloads/submit.html.php:9 | #: IDF/gettexttemplates/idf/downloads/submit.html.php:10 | ||||||
| msgid "Instructions" | msgid "Instructions" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| @@ -2913,7 +2985,7 @@ msgid "" | |||||||
| "If you are not interested any longer in taking\n" | "If you are not interested any longer in taking\n" | ||||||
| "part in the life of the software project or if\n" | "part in the life of the software project or if\n" | ||||||
| "you can't remember having requested the creation\n" | "you can't remember having requested the creation\n" | ||||||
| "of an accout, please excuse us and simply ignore\n" | "of an account, please excuse us and simply ignore\n" | ||||||
| "this email. \n" | "this email. \n" | ||||||
| "\n" | "\n" | ||||||
| "Yours faithfully,\n" | "Yours faithfully,\n" | ||||||
| @@ -2967,6 +3039,7 @@ msgstr "" | |||||||
|  |  | ||||||
| #: IDF/gettexttemplates/idf/review/view.html.php:28 | #: IDF/gettexttemplates/idf/review/view.html.php:28 | ||||||
| #: IDF/gettexttemplates/idf/issues/issue-created-email.txt.php:10 | #: IDF/gettexttemplates/idf/issues/issue-created-email.txt.php:10 | ||||||
|  | #: IDF/gettexttemplates/idf/downloads/download-created-email.txt.php:9 | ||||||
| msgid "Description:" | msgid "Description:" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| @@ -3101,11 +3174,6 @@ msgstr "" | |||||||
| msgid "(No comments were given for this change.)" | msgid "(No comments were given for this change.)" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/gettexttemplates/idf/issues/issue-updated-email.txt.php:17 |  | ||||||
| #: IDF/gettexttemplates/idf/issues/issue-created-email.txt.php:11 |  | ||||||
| msgid "Attachments:" |  | ||||||
| msgstr "" |  | ||||||
|  |  | ||||||
| #: IDF/gettexttemplates/idf/issues/issue-updated-email.txt.php:18 | #: IDF/gettexttemplates/idf/issues/issue-updated-email.txt.php:18 | ||||||
| #: IDF/gettexttemplates/idf/issues/issue-created-email.txt.php:12 | #: IDF/gettexttemplates/idf/issues/issue-created-email.txt.php:12 | ||||||
| msgid "Issue:" | msgid "Issue:" | ||||||
| @@ -3243,32 +3311,31 @@ msgid "" | |||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/gettexttemplates/idf/downloads/view.html.php:5 | #: IDF/gettexttemplates/idf/downloads/view.html.php:5 | ||||||
| msgid "The form contains some errors. Please correct them to update the file." | msgid "Changes" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/gettexttemplates/idf/downloads/view.html.php:6 | #: IDF/gettexttemplates/idf/downloads/view.html.php:6 | ||||||
|  | msgid "The form contains some errors. Please correct them to update the file." | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
|  | #: IDF/gettexttemplates/idf/downloads/view.html.php:7 | ||||||
| msgid "Update File" | msgid "Update File" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/gettexttemplates/idf/downloads/view.html.php:8 | #: IDF/gettexttemplates/idf/downloads/view.html.php:9 | ||||||
| #: IDF/gettexttemplates/idf/downloads/view.html.php:10 | #: IDF/gettexttemplates/idf/downloads/view.html.php:11 | ||||||
| msgid "Remove this file" | msgid "Remove this file" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/gettexttemplates/idf/downloads/view.html.php:11 | #: IDF/gettexttemplates/idf/downloads/view.html.php:12 | ||||||
| msgid "Delete this file" | msgid "Delete this file" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/gettexttemplates/idf/downloads/view.html.php:12 | #: IDF/gettexttemplates/idf/downloads/view.html.php:13 | ||||||
| #: IDF/gettexttemplates/idf/downloads/delete.html.php:8 | #: IDF/gettexttemplates/idf/downloads/delete.html.php:8 | ||||||
| msgid "Uploaded:" | msgid "Uploaded:" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/gettexttemplates/idf/downloads/view.html.php:14 |  | ||||||
| #: IDF/gettexttemplates/idf/downloads/delete.html.php:10 |  | ||||||
| msgid "Downloads:" |  | ||||||
| msgstr "" |  | ||||||
|  |  | ||||||
| #: IDF/gettexttemplates/idf/downloads/delete.html.php:3 | #: IDF/gettexttemplates/idf/downloads/delete.html.php:3 | ||||||
| msgid "" | msgid "" | ||||||
| "<strong>Attention!</strong> If you want to delete a specific version of your " | "<strong>Attention!</strong> If you want to delete a specific version of your " | ||||||
| @@ -3304,10 +3371,16 @@ msgid "" | |||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/gettexttemplates/idf/downloads/submit.html.php:6 | #: IDF/gettexttemplates/idf/downloads/submit.html.php:6 | ||||||
| msgid "The form contains some errors. Please correct them to submit the file." | #, php-format | ||||||
|  | msgid "" | ||||||
|  | "You can use the <a href=\"%%url%%\">Markdown syntax</a> for the changes." | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| #: IDF/gettexttemplates/idf/downloads/submit.html.php:7 | #: IDF/gettexttemplates/idf/downloads/submit.html.php:7 | ||||||
|  | msgid "The form contains some errors. Please correct them to submit the file." | ||||||
|  | msgstr "" | ||||||
|  |  | ||||||
|  | #: IDF/gettexttemplates/idf/downloads/submit.html.php:8 | ||||||
| msgid "Submit File" | msgid "Submit File" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| @@ -3338,3 +3411,9 @@ msgstr "" | |||||||
| #: IDF/Template/Markdown.php:61 | #: IDF/Template/Markdown.php:61 | ||||||
| msgid "Create this documentation page" | msgid "Create this documentation page" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
|  | #: IDF/gettexttemplates/idf/downloads/submit.html.php:6 | ||||||
|  | #, php-format | ||||||
|  | msgid "" | ||||||
|  | "You can use the <a href=\"%%url%%\">Markdown syntax</a> for the description." | ||||||
|  | msgstr "" | ||||||
|   | |||||||
| @@ -40,6 +40,7 @@ $m['IDF_Review_FileComment'] = array('relate_to' => array('IDF_Review_Patch', 'P | |||||||
| $m['IDF_Key'] = array('relate_to' => array('Pluf_User')); | $m['IDF_Key'] = array('relate_to' => array('Pluf_User')); | ||||||
| $m['IDF_Conf'] = array('relate_to' => array('IDF_Project')); | $m['IDF_Conf'] = array('relate_to' => array('IDF_Project')); | ||||||
| $m['IDF_Commit'] = array('relate_to' => array('IDF_Project', 'Pluf_User')); | $m['IDF_Commit'] = array('relate_to' => array('IDF_Project', 'Pluf_User')); | ||||||
|  | $m['IDF_Scm_Cache_Git'] = array('relate_to' => array('IDF_Project')); | ||||||
|  |  | ||||||
| Pluf_Signal::connect('Pluf_Template_Compiler::construct_template_tags_modifiers', | Pluf_Signal::connect('Pluf_Template_Compiler::construct_template_tags_modifiers', | ||||||
|                      array('IDF_Middleware', 'updateTemplateTagsModifiers')); |                      array('IDF_Middleware', 'updateTemplateTagsModifiers')); | ||||||
| @@ -53,7 +54,8 @@ Pluf_Signal::connect('IDF_Project::created', | |||||||
|                      array('IDF_Plugin_SyncSvn', 'entry')); |                      array('IDF_Plugin_SyncSvn', 'entry')); | ||||||
| Pluf_Signal::connect('Pluf_User::passwordUpdated',  | Pluf_Signal::connect('Pluf_User::passwordUpdated',  | ||||||
|                      array('IDF_Plugin_SyncSvn', 'entry')); |                      array('IDF_Plugin_SyncSvn', 'entry')); | ||||||
|  | Pluf_Signal::connect('IDF_Project::preDelete',  | ||||||
|  |                      array('IDF_Plugin_SyncSvn', 'entry')); | ||||||
| # | # | ||||||
| # Mercurial synchronization | # Mercurial synchronization | ||||||
| Pluf_Signal::connect('IDF_Project::membershipsUpdated',  | Pluf_Signal::connect('IDF_Project::membershipsUpdated',  | ||||||
|   | |||||||
| @@ -20,7 +20,12 @@ | |||||||
| <th>{trans 'Repository access:'}</th> | <th>{trans 'Repository access:'}</th> | ||||||
| <td>{$repository_access} | <td>{$repository_access} | ||||||
| </td> | </td> | ||||||
| </tr>{if $remote_svn} | </tr>{if $repository_size != -1} | ||||||
|  | <tr> | ||||||
|  | <th>{trans 'Repository size:'}</th> | ||||||
|  | <td>{$repository_size|size} | ||||||
|  | </td> | ||||||
|  | </tr>{/if}{if $remote_svn} | ||||||
| <tr> | <tr> | ||||||
| <th>{$form.f.svn_username.labelTag}:</th> | <th>{$form.f.svn_username.labelTag}:</th> | ||||||
| <td>{if $form.f.svn_username.errors}{$form.f.svn_username.fieldErrors}{/if} | <td>{if $form.f.svn_username.errors}{$form.f.svn_username.fieldErrors}{/if} | ||||||
|   | |||||||
| @@ -53,6 +53,15 @@ | |||||||
| </td> | </td> | ||||||
| </tr> | </tr> | ||||||
| <tr> | <tr> | ||||||
|  | <td> </td> | ||||||
|  | <td colspan="2" class="helptext"> | ||||||
|  | {blocktrans} | ||||||
|  | Only project members and admins have write access to the source.<br /> | ||||||
|  | If you restrict the access to the source, anonymous access is<br />  | ||||||
|  | not provided and the users must authenticate themselves with their<br /> | ||||||
|  | password or SSH key.{/blocktrans} | ||||||
|  | </td></tr> | ||||||
|  | <tr> | ||||||
| <th><strong>{$form.f.review_access_rights.labelTag}:</strong></th> | <th><strong>{$form.f.review_access_rights.labelTag}:</strong></th> | ||||||
| <td>{if $form.f.review_access_rights.errors}{$form.f.review_access_rights.fieldErrors}{/if} | <td>{if $form.f.review_access_rights.errors}{$form.f.review_access_rights.fieldErrors}{/if} | ||||||
| {$form.f.review_access_rights|unsafe} | {$form.f.review_access_rights|unsafe} | ||||||
|   | |||||||
| @@ -73,15 +73,18 @@ | |||||||
| {include 'idf/js-hotkeys.html'} | {include 'idf/js-hotkeys.html'} | ||||||
| {block javascript}{/block} | {block javascript}{/block} | ||||||
| {if $project} | {if $project} | ||||||
| <script type="text/javascript">{literal} | <script type="text/javascript" charset="utf-8">{literal} | ||||||
| <!-- // | //<![CDATA[ | ||||||
|  $(document).ready(function(){ | $(document).ready(function(){ | ||||||
| 	var frag = location.hash; | 	var frag = location.hash; | ||||||
| 	if (frag.length > 3 && frag.substring(0, 3) == '#ic') { | 	if ($('#preview').length) { | ||||||
|  | 		location.hash = '#preview'; | ||||||
|  | 	} | ||||||
|  | 	else if (frag.length > 3 && frag.substring(0, 3) == '#ic') { | ||||||
| 		$(frag).addClass("issue-comment-focus"); | 		$(frag).addClass("issue-comment-focus"); | ||||||
| 	} | 	} | ||||||
| }); | }); | ||||||
| //  -->{/literal} | //]]>{/literal} | ||||||
| </script>{/if} | </script>{/if} | ||||||
| </body> | </body> | ||||||
| </html> | </html> | ||||||
|   | |||||||
| @@ -75,15 +75,18 @@ | |||||||
| {include 'idf/js-hotkeys.html'} | {include 'idf/js-hotkeys.html'} | ||||||
| {block javascript}{/block} | {block javascript}{/block} | ||||||
| {if $project} | {if $project} | ||||||
| <script type="text/javascript">{literal} | <script type="text/javascript" charset="utf-8">{literal} | ||||||
| <!-- // | //<![CDATA[ | ||||||
|  $(document).ready(function(){ | $(document).ready(function(){ | ||||||
| 	var frag = location.hash; | 	var frag = location.hash; | ||||||
| 	if (frag.length > 3 && frag.substring(0, 3) == '#ic') { | 	if ($('#preview').length) { | ||||||
|  | 		location.hash = '#preview'; | ||||||
|  | 	} | ||||||
|  | 	else if (frag.length > 3 && frag.substring(0, 3) == '#ic') { | ||||||
| 		$(frag).addClass("issue-comment-focus"); | 		$(frag).addClass("issue-comment-focus"); | ||||||
| 	} | 	} | ||||||
| }); | }); | ||||||
| //  -->{/literal} | //]]>{/literal} | ||||||
| </script>{/if} | </script>{/if} | ||||||
| </body> | </body> | ||||||
| </html> | </html> | ||||||
| @@ -10,3 +10,8 @@ | |||||||
| {foreach $tags as $tag} {$tag.class|safe}:{$tag.name|safe} | {foreach $tags as $tag} {$tag.class|safe}:{$tag.name|safe} | ||||||
| {/foreach}{/if} | {/foreach}{/if} | ||||||
| {trans 'Download:'} {$urlfile} | {trans 'Download:'} {$urlfile} | ||||||
|  | {if $file.changelog} | ||||||
|  | {trans 'Description:'} | ||||||
|  |  | ||||||
|  | {$file.changelog} | ||||||
|  | {/if} | ||||||
|   | |||||||
| @@ -19,6 +19,12 @@ | |||||||
| </td> | </td> | ||||||
| </tr> | </tr> | ||||||
| <tr> | <tr> | ||||||
|  | <th>{$form.f.changelog.labelTag}:</th> | ||||||
|  | <td>{if $form.f.changelog.errors}{$form.f.changelog.fieldErrors}{/if} | ||||||
|  | {$form.f.changelog|unsafe} | ||||||
|  | </td> | ||||||
|  | </tr> | ||||||
|  | <tr> | ||||||
| <th><strong>{$form.f.file.labelTag}:</strong></th> | <th><strong>{$form.f.file.labelTag}:</strong></th> | ||||||
| <td>{if $form.f.file.errors}{$form.f.file.fieldErrors}{/if} | <td>{if $form.f.file.errors}{$form.f.file.fieldErrors}{/if} | ||||||
| {$form.f.file|unsafe} | {$form.f.file|unsafe} | ||||||
| @@ -50,6 +56,8 @@ | |||||||
| <p>{blocktrans}Each file must have a distinct name and file contents | <p>{blocktrans}Each file must have a distinct name and file contents | ||||||
| cannot be changed, so be sure to include release numbers in each file | cannot be changed, so be sure to include release numbers in each file | ||||||
| name.{/blocktrans}</p> | name.{/blocktrans}</p> | ||||||
|  | {assign $url = 'http://daringfireball.net/projects/markdown/syntax'} | ||||||
|  | <p>{blocktrans}You can use the <a href="{$url}">Markdown syntax</a> for the description.{/blocktrans}</p> | ||||||
| </div> | </div> | ||||||
| {/block} | {/block} | ||||||
| {block javascript} | {block javascript} | ||||||
|   | |||||||
| @@ -6,7 +6,11 @@ | |||||||
| {if $deprecated}<p class="smaller">{blocktrans}<strong>Attention!</strong> This file is marked as deprecated, download it only if you are sure you need this specific version.{/blocktrans}</p>{/if} | {if $deprecated}<p class="smaller">{blocktrans}<strong>Attention!</strong> This file is marked as deprecated, download it only if you are sure you need this specific version.{/blocktrans}</p>{/if} | ||||||
| <a href="{url 'IDF_Views_Download::download', array($project.shortname, $file.id)}">{$file}</a> - {$file.filesize|size} | <a href="{url 'IDF_Views_Download::download', array($project.shortname, $file.id)}">{$file}</a> - {$file.filesize|size} | ||||||
| </div> | </div> | ||||||
|  | {if $file.changelog} | ||||||
|  | <h2 class="changes">{trans 'Changes'}</h2> | ||||||
|  |  | ||||||
|  | {markdown $file.changelog, $request} | ||||||
|  | {/if} | ||||||
|  |  | ||||||
| {if $form} | {if $form} | ||||||
| {if $form.errors} | {if $form.errors} | ||||||
| @@ -19,7 +23,7 @@ | |||||||
| {/if} | {/if} | ||||||
|  |  | ||||||
| <form method="post" enctype="multipart/form-data" action="."> | <form method="post" enctype="multipart/form-data" action="."> | ||||||
| <table class="form" summary=""> | <table class="form download" summary=""> | ||||||
| <tr> | <tr> | ||||||
| <th><strong>{$form.f.summary.labelTag}:</strong></th> | <th><strong>{$form.f.summary.labelTag}:</strong></th> | ||||||
| <td>{if $form.f.summary.errors}{$form.f.summary.fieldErrors}{/if} | <td>{if $form.f.summary.errors}{$form.f.summary.fieldErrors}{/if} | ||||||
| @@ -27,6 +31,12 @@ | |||||||
| </td> | </td> | ||||||
| </tr> | </tr> | ||||||
| <tr> | <tr> | ||||||
|  | <th>{$form.f.changelog.labelTag}:</th> | ||||||
|  | <td>{if $form.f.changelog.errors}{$form.f.changelog.fieldErrors}{/if} | ||||||
|  | {$form.f.changelog|unsafe} | ||||||
|  | </td> | ||||||
|  | </tr> | ||||||
|  | <tr> | ||||||
| <th>{$form.f.label1.labelTag}:</th> | <th>{$form.f.label1.labelTag}:</th> | ||||||
| <td> | <td> | ||||||
| {if $form.f.label1.errors}{$form.f.label1.fieldErrors}{/if}{$form.f.label1|unsafe} | {if $form.f.label1.errors}{$form.f.label1.fieldErrors}{/if}{$form.f.label1|unsafe} | ||||||
| @@ -39,7 +49,8 @@ | |||||||
| </tr> | </tr> | ||||||
| <tr> | <tr> | ||||||
| <td> </td>{aurl 'url', 'IDF_Views_Download::delete', array($project.shortname, $file.id)} | <td> </td>{aurl 'url', 'IDF_Views_Download::delete', array($project.shortname, $file.id)} | ||||||
| <td><input type="submit" value="{trans 'Update File'}" name="submit" /> | <a href="{url 'IDF_Views_Download::index', array($project.shortname)}">{trans 'Cancel'}</a> <span class="dellink"><a href="{$url}" title="{trans 'Remove this file'}"><img src="{media '/idf/img/trash.png'}" style="vertical-align: text-bottom;" alt="{trans 'Trash'}" /></a> <a href="{$url}" title="{trans 'Remove this file'}">{trans 'Delete this file'}</a></span> | <td>{* float left is a fix for Firefox < 3.5 *} | ||||||
|  | <span style="float: left;"><input type="submit" value="{trans 'Update File'}" name="submit" /> | <a href="{url 'IDF_Views_Download::index', array($project.shortname)}">{trans 'Cancel'}</a></span> <span class="dellink"><a href="{$url}" title="{trans 'Remove this file'}"><img src="{media '/idf/img/trash.png'}" style="vertical-align: text-bottom;" alt="{trans 'Trash'}" /></a> <a href="{$url}" title="{trans 'Remove this file'}">{trans 'Delete this file'}</a></span> | ||||||
| </td> | </td> | ||||||
| </tr> | </tr> | ||||||
| </table> | </table> | ||||||
|   | |||||||
| @@ -1,8 +1,23 @@ | |||||||
| {extends "idf/gadmin/projects/base.html"} | {extends "idf/gadmin/projects/base.html"} | ||||||
|  |  | ||||||
| {block docclass}yui-t2{assign $inIndex=true}{/block} | {block docclass}yui-t3{assign $inIndex=true}{/block} | ||||||
|  |  | ||||||
| {block body} | {block body} | ||||||
| {$projects.render} | {$projects.render} | ||||||
| {/block} | {/block} | ||||||
|  |  | ||||||
|  | {block context} | ||||||
|  | <div class="issue-submit-info"> | ||||||
|  | <p><strong>{trans 'Space Usage Statistics'}</strong></p> | ||||||
|  | <ul> | ||||||
|  | <li>{trans 'Repositories:'} {$size['repositories']|size}</li> | ||||||
|  | <li>{trans 'Attachments:'} {$size['attachments']|size}</li>  | ||||||
|  | <li>{trans 'Downloads:'} {$size['downloads']|size}</li> | ||||||
|  | <li>{trans 'Database:'} {$size['database']|size}</li> | ||||||
|  | <li><strong>{trans 'Total Forge:'} {$size['total']|size}</strong></li> | ||||||
|  | </ul> | ||||||
|  |  | ||||||
|  | </div> | ||||||
|  | {/block} | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -35,9 +35,10 @@ | |||||||
| <tr> | <tr> | ||||||
| <td> </td> | <td> </td> | ||||||
| <td> {aurl 'url', 'IDF_Views_Admin::projectDelete', array($project.id)} | <td> {aurl 'url', 'IDF_Views_Admin::projectDelete', array($project.id)} | ||||||
| <input type="submit" value="{trans 'Update Project'}" name="submit" />  | {* float left is a fix for Firefox < 3.5 *} | ||||||
| | <a href="{url 'IDF_Views_Admin::projects'}">{trans 'Cancel'}</a> {if $isAdmin} | <span style="float: left;"><input type="submit" value="{trans 'Update Project'}" name="submit" />  | ||||||
|  <span class="dellink"><a href="{$url}" title="{trans 'Delete this project'}"><img src="{media '/idf/img/trash.png'}" style="vertical-align: text-bottom;" alt="{trans 'Trash'}" /></a> <a href="{$url}" title="{trans 'Delete this project'}">{trans 'Delete this project'}</a><br /><span class="note helptext">{trans 'You will be ask to confirm.'}</span></span>{/if} | | <a href="{url 'IDF_Views_Admin::projects'}">{trans 'Cancel'}</a></span> {if $isAdmin} | ||||||
|  |  <span class="dellink"><a href="{$url}" title="{trans 'Delete this project'}"><img src="{media '/idf/img/trash.png'}" style="vertical-align: text-bottom;" alt="{trans 'Trash'}" /></a> <a href="{$url}" title="{trans 'Delete this project'}">{trans 'Delete this project'}</a><br /><span class="note helptext">{trans 'You will be asked to confirm.'}</span></span>{/if} | ||||||
| </td> | </td> | ||||||
| </tr> | </tr> | ||||||
| </table> | </table> | ||||||
|   | |||||||
| @@ -10,7 +10,7 @@ | |||||||
| <p><a href="{$url}"><img style="vertical-align: text-bottom;" src="{media '/idf/img/add.png'}" alt="+" align="bottom" /></a> <a href="{$url}">{trans 'Create Project'}</a></p>{/if} | <p><a href="{$url}"><img style="vertical-align: text-bottom;" src="{media '/idf/img/add.png'}" alt="+" align="bottom" /></a> <a href="{$url}">{trans 'Create Project'}</a></p>{/if} | ||||||
| {else} | {else} | ||||||
| <ul>{foreach $projects as $p} | <ul>{foreach $projects as $p} | ||||||
| <li><a href="{url 'IDF_Views_Project::home', array($p.shortname)}">{$p}</a>, {$p.shortdesc}</li> | <li>{if $p.private}<img style="vertical-align: text-bottom;" src="{media '/idf/img/lock.png'}" alt="{trans 'Private project'}" /> {/if}<a href="{url 'IDF_Views_Project::home', array($p.shortname)}">{$p}</a>{if $p.shortdesc}, {$p.shortdesc}{/if}</li> | ||||||
| {/foreach}</ul> | {/foreach}</ul> | ||||||
| {/if} | {/if} | ||||||
| {/block} | {/block} | ||||||
|   | |||||||
| @@ -11,14 +11,14 @@ | |||||||
| {/if} | {/if} | ||||||
|  |  | ||||||
| {if $preview} | {if $preview} | ||||||
| <h2 class="top">{trans 'Preview'}</h2> | <h2 id="preview" class="top">{trans 'Preview'}</h2> | ||||||
| <div class="issue-comment issue-comment-first issue-comment-last"> | <div class="issue-comment issue-comment-first issue-comment-last"> | ||||||
| <br /><pre class="issue-comment-text">{issuetext $preview, $request}</pre> | <br /><pre class="issue-comment-text">{issuetext $preview, $request}</pre> | ||||||
| </div> | </div> | ||||||
| <hr /> | <hr /> | ||||||
| {/if} | {/if} | ||||||
|  |  | ||||||
| <form method="post" enctype="multipart/form-data" action="{url 'IDF_Views_Issue::create', array($project.shortname)}" > | <form method="post" enctype="multipart/form-data" action="{url 'IDF_Views_Issue::create', array($project.shortname)}#preview" > | ||||||
| <table class="form" summary=""> | <table class="form" summary=""> | ||||||
| <tr> | <tr> | ||||||
| <th><strong>{$form.f.summary.labelTag}:</strong></th> | <th><strong>{$form.f.summary.labelTag}:</strong></th> | ||||||
| @@ -107,16 +107,19 @@ $(document).ready(function(){ | |||||||
|     $("#form-show-0").click(function(){ |     $("#form-show-0").click(function(){ | ||||||
|         $("#form-attachment-1").show(); |         $("#form-attachment-1").show(); | ||||||
|         $("#form-block-0").hide(); |         $("#form-block-0").hide(); | ||||||
|  |         return false; | ||||||
|     }); |     }); | ||||||
|     $("#form-attachment-1 td").append("<span id=\"form-block-1\"><a id=\"form-show-1\" href=\"#\">{/literal}{trans 'Attach another file'}{literal}</a></span>"); |     $("#form-attachment-1 td").append("<span id=\"form-block-1\"><a id=\"form-show-1\" href=\"#\">{/literal}{trans 'Attach another file'}{literal}</a></span>"); | ||||||
|     $("#form-show-1").click(function(){ |     $("#form-show-1").click(function(){ | ||||||
|             $("#form-attachment-2").show(); |             $("#form-attachment-2").show(); | ||||||
|             $("#form-block-1").hide(); |             $("#form-block-1").hide(); | ||||||
|  |             return false; | ||||||
|         }); |         }); | ||||||
|     $("#form-attachment-2 td").append("<span id=\"form-block-2\"><a id=\"form-show-2\" href=\"#\">{/literal}{trans 'Attach another file'}{literal}</a></span>"); |     $("#form-attachment-2 td").append("<span id=\"form-block-2\"><a id=\"form-show-2\" href=\"#\">{/literal}{trans 'Attach another file'}{literal}</a></span>"); | ||||||
|     $("#form-show-2").click(function(){ |     $("#form-show-2").click(function(){ | ||||||
|             $("#form-attachment-3").show(); |             $("#form-attachment-3").show(); | ||||||
|             $("#form-block-2").hide(); |             $("#form-block-2").hide(); | ||||||
|  |             return false; | ||||||
|         }); |         }); | ||||||
|     var j=0; |     var j=0; | ||||||
|     for (j=1;j<4;j=j+1) { |     for (j=1;j<4;j=j+1) { | ||||||
|   | |||||||
| @@ -53,7 +53,7 @@ | |||||||
| {/if} | {/if} | ||||||
|  |  | ||||||
| {if $preview} | {if $preview} | ||||||
| <h2>{trans 'Preview'}</h2> | <h2 id="preview">{trans 'Preview'}</h2> | ||||||
| <div class="issue-comment issue-comment-first issue-comment-last"> | <div class="issue-comment issue-comment-first issue-comment-last"> | ||||||
| <br /><pre class="issue-comment-text">{issuetext $preview, $request}</pre> | <br /><pre class="issue-comment-text">{issuetext $preview, $request}</pre> | ||||||
| </div> | </div> | ||||||
| @@ -160,16 +160,19 @@ $(document).ready(function(){ | |||||||
|     $("#form-show-0").click(function(){ |     $("#form-show-0").click(function(){ | ||||||
|         $("#form-attachment-1").show(); |         $("#form-attachment-1").show(); | ||||||
|         $("#form-block-0").hide(); |         $("#form-block-0").hide(); | ||||||
|  |         return false; | ||||||
|     }); |     }); | ||||||
|     $("#form-attachment-1 td").append("<span id=\"form-block-1\"><a id=\"form-show-1\" href=\"#\">{/literal}{trans 'Attach another file'}{literal}</a></span>"); |     $("#form-attachment-1 td").append("<span id=\"form-block-1\"><a id=\"form-show-1\" href=\"#\">{/literal}{trans 'Attach another file'}{literal}</a></span>"); | ||||||
|     $("#form-show-1").click(function(){ |     $("#form-show-1").click(function(){ | ||||||
|             $("#form-attachment-2").show(); |             $("#form-attachment-2").show(); | ||||||
|             $("#form-block-1").hide(); |             $("#form-block-1").hide(); | ||||||
|  |             return false; | ||||||
|         }); |         }); | ||||||
|     $("#form-attachment-2 td").append("<span id=\"form-block-2\"><a id=\"form-show-2\" href=\"#\">{/literal}{trans 'Attach another file'}{literal}</a></span>"); |     $("#form-attachment-2 td").append("<span id=\"form-block-2\"><a id=\"form-show-2\" href=\"#\">{/literal}{trans 'Attach another file'}{literal}</a></span>"); | ||||||
|     $("#form-show-2").click(function(){ |     $("#form-show-2").click(function(){ | ||||||
|             $("#form-attachment-3").show(); |             $("#form-attachment-3").show(); | ||||||
|             $("#form-block-2").hide(); |             $("#form-block-2").hide(); | ||||||
|  |             return false; | ||||||
|         }); |         }); | ||||||
|     var j=0; |     var j=0; | ||||||
|     for (j=1;j<4;j=j+1) { |     for (j=1;j<4;j=j+1) { | ||||||
|   | |||||||
| @@ -18,7 +18,7 @@ and provide the following confirmation key: | |||||||
| If you are not interested any longer in taking | If you are not interested any longer in taking | ||||||
| part in the life of the software project or if | part in the life of the software project or if | ||||||
| you can't remember having requested the creation | you can't remember having requested the creation | ||||||
| of an accout, please excuse us and simply ignore | of an account, please excuse us and simply ignore | ||||||
| this email.  | this email.  | ||||||
|  |  | ||||||
| Yours faithfully, | Yours faithfully, | ||||||
|   | |||||||
| @@ -1,10 +1,12 @@ | |||||||
| {extends "idf/base.html"} | {extends "idf/base.html"} | ||||||
| {block tabsource} class="active"{/block} | {block tabsource} class="active"{/block} | ||||||
| {block subtabs} | {block subtabs} | ||||||
|  | {if !$inHelp and array_key_exists($commit, $branches)}{assign $currentCommit =  $commit}{else}{assign $currentCommit = $project.getScmRoot()}{/if} | ||||||
| <div id="sub-tabs"> | <div id="sub-tabs"> | ||||||
| <a {if $inSourceTree}class="active" {/if}href="{url 'IDF_Views_Source::treeBase', array($project.shortname, $project.getScmRoot())}">{trans 'Source Tree'}</a> | | <a {if $inSourceTree}class="active" {/if}href="{url 'IDF_Views_Source::treeBase', array($project.shortname, $currentCommit)}">{trans 'Source Tree'}</a> | | ||||||
| <a {if $inChangeLog}class="active" {/if}href="{url 'IDF_Views_Source::changeLog', array($project.shortname, $project.getScmRoot())}">{trans 'Change Log'}</a> | <a {if $inChangeLog}class="active" {/if}href="{url 'IDF_Views_Source::changeLog', array($project.shortname, $currentCommit)}">{trans 'Change Log'}</a> | ||||||
| {if $inCommit}| {trans 'Commit'}{/if} | {if $inCommit}| {trans 'Commit'}{/if} | | ||||||
|  | <a {if $inHelp}class="active" {/if}href="{url 'IDF_Views_Source::help', array($project.shortname)}">{trans 'How To Get The Code'}</a> | ||||||
| </div> | </div> | ||||||
| {/block} | {/block} | ||||||
| {block title}{$title}{/block} | {block title}{$title}{/block} | ||||||
|   | |||||||
| @@ -27,22 +27,3 @@ | |||||||
| </tbody> | </tbody> | ||||||
| </table> | </table> | ||||||
| {/block} | {/block} | ||||||
| {block context} |  | ||||||
| {if $scm != 'svn'} |  | ||||||
| <p><strong>{trans 'Branches:'}</strong><br /> |  | ||||||
| {foreach $branches as $branch} |  | ||||||
| {aurl 'url', 'IDF_Views_Source::changeLog', array($project.shortname, $branch)} |  | ||||||
| <span class="label{if $commit == $branch} active{/if}"><a href="{$url}" class="label">{$branch}</a></span><br /> |  | ||||||
| {/foreach} |  | ||||||
| </p> |  | ||||||
| {else} |  | ||||||
| <form class="star" action="{url 'IDF_Views_Source_Svn::changelogRev', array($project.shortname)}" method="get"> |  | ||||||
| <p><strong>{trans 'Revision:'}</strong> {$commit}</p> |  | ||||||
| <p> |  | ||||||
|     <input accesskey="4" type="text" value="{$commit}" name="rev" size="5" /> |  | ||||||
|     <input type="submit" name="s" value="{trans 'Go to revision'}" /> |  | ||||||
| </p> |  | ||||||
| </form> |  | ||||||
| {/if} |  | ||||||
| {/block} |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -38,13 +38,21 @@ | |||||||
|  |  | ||||||
| {/block} | {/block} | ||||||
| {block context} | {block context} | ||||||
| {if $scm == 'git'} | {if $scm != 'svn'} | ||||||
| <p><strong>{trans 'Branches:'}</strong><br /> | <p><strong>{trans 'Branches:'}</strong><br /> | ||||||
| {foreach $branches as $branch} | {foreach $branches as $branch => $path} | ||||||
| {aurl 'url', 'IDF_Views_Source::commit', array($project.shortname, $branch)} | {aurl 'url', 'IDF_Views_Source::treeBase', array($project.shortname, $branch)} | ||||||
| <span class="label{if $commit == $branch} active{/if}"><a href="{$url}" class="label">{$branch}</a></span><br /> | <span class="label{if in_array($branch, $tree_in)} active{/if}"><a href="{$url}" class="label">{$branch}</a></span><br /> | ||||||
| {/foreach} | {/foreach} | ||||||
| </p> | </p> | ||||||
|  | {else} | ||||||
|  | <form class="star" action="{url 'IDF_Views_Source_Svn::changelogRev', array($project.shortname)}" method="get"> | ||||||
|  | <p><strong>{trans 'Revision:'}</strong> {$commit}</p> | ||||||
|  | <p> | ||||||
|  |     <input accesskey="4" type="text" value="{$commit}" name="rev" size="5" /> | ||||||
|  |     <input type="submit" name="s" value="{trans 'Go to revision'}" /> | ||||||
|  | </p> | ||||||
|  | </form> | ||||||
| {/if} | {/if} | ||||||
| {/block} | {/block} | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										10
									
								
								src/IDF/templates/idf/source/git/changelog.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								src/IDF/templates/idf/source/git/changelog.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | |||||||
|  | {extends "idf/source/changelog.html"} | ||||||
|  | {block context} | ||||||
|  | <p><strong>{trans 'Branches:'}</strong><br /> | ||||||
|  | {foreach $branches as $branch => $path} | ||||||
|  | {aurl 'url', 'IDF_Views_Source::changeLog', array($project.shortname, $branch)} | ||||||
|  | <span class="label{if in_array($branch, $tree_in)} active{/if}"><a href="{$url}" class="label">{if $path}{$path}{else}{$branch}{/if}</a></span><br /> | ||||||
|  | {/foreach} | ||||||
|  | </p> | ||||||
|  | {/block} | ||||||
|  |  | ||||||
| @@ -23,9 +23,9 @@ | |||||||
| {/block} | {/block} | ||||||
| {block context} | {block context} | ||||||
| <p><strong>{trans 'Branches:'}</strong><br /> | <p><strong>{trans 'Branches:'}</strong><br /> | ||||||
| {foreach $branches as $branch} | {foreach $branches as $branch => $path} | ||||||
| {aurl 'url', 'IDF_Views_Source::treeBase', array($project.shortname, $branch)} | {aurl 'url', 'IDF_Views_Source::treeBase', array($project.shortname, $branch)} | ||||||
| <span class="label{if $commit == $branch} active{/if}"><a href="{$url}" class="label">{$branch}</a></span><br /> | <span class="label{if in_array($branch, $tree_in)} active{/if}"><a href="{$url}" class="label">{if $path}{$path}{else}{$branch}{/if}</a></span><br /> | ||||||
| {/foreach} | {/foreach} | ||||||
| </p> | </p> | ||||||
| {/block} | {/block} | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| {extends "idf/source/base.html"} | {extends "idf/source/base.html"} | ||||||
| {block docclass}yui-t2{/block} | {block docclass}yui-t2{assign $inHelp=true}{/block} | ||||||
| {block body} | {block body} | ||||||
|  |  | ||||||
| <p>{blocktrans}The team behind {$project} is using | <p>{blocktrans}The team behind {$project} is using | ||||||
| @@ -8,7 +8,7 @@ code.{/blocktrans}</p> | |||||||
|  |  | ||||||
| <h3>{trans 'Command-Line Access'}</h3> | <h3>{trans 'Command-Line Access'}</h3> | ||||||
|  |  | ||||||
| <p><kbd>git clone {if $project.private}{$project.getWriteRemoteAccessUrl()}{else}{$project.getRemoteAccessUrl()}{/if}</kbd></p> | <p><kbd>git clone {$project.getSourceAccessUrl($user)}</kbd></p> | ||||||
|  |  | ||||||
| {aurl 'url', 'IDF_Views_User::myAccount'} | {aurl 'url', 'IDF_Views_User::myAccount'} | ||||||
| <p>{blocktrans}You may need to <a href="{$url}">provide your SSH key</a>. The synchronization of your SSH key can take a couple of minutes. You can learn more about <a href="http://www.google.com/search?q=public+ssh+key+authentication">SSH key authentification</a>.{/blocktrans}</p> | <p>{blocktrans}You may need to <a href="{$url}">provide your SSH key</a>. The synchronization of your SSH key can take a couple of minutes. You can learn more about <a href="http://www.google.com/search?q=public+ssh+key+authentication">SSH key authentification</a>.{/blocktrans}</p> | ||||||
| @@ -22,7 +22,7 @@ code.{/blocktrans}</p> | |||||||
| git init | git init | ||||||
| git add . | git add . | ||||||
| git commit -m "initial import" | git commit -m "initial import" | ||||||
| git remote add origin {$project.getWriteRemoteAccessUrl()} | git remote add origin {$project.getWriteRemoteAccessUrl($url)} | ||||||
| git push origin master | git push origin master | ||||||
| </pre> | </pre> | ||||||
|  |  | ||||||
|   | |||||||
| @@ -47,15 +47,15 @@ | |||||||
| </tbody> | </tbody> | ||||||
| </table> | </table> | ||||||
| {aurl 'url', 'IDF_Views_Source::download', array($project.shortname, $commit)} | {aurl 'url', 'IDF_Views_Source::download', array($project.shortname, $commit)} | ||||||
| <p class="right soft"><a href="{$url}"><img style="vertical-align: text-bottom;" src="{media '/idf/img/package-grey.png'}" alt="{trans 'Archive'}" align="bottom" /></a> <a href="{$url}">{trans 'Download this version'}</a> {trans 'or'} <kbd>git clone {if $project.private}{$project.getWriteRemoteAccessUrl()}{else}{$project.getRemoteAccessUrl()}{/if}</kbd> <a href="{url 'IDF_Views_Source::help', array($project.shortname)}"><img style="vertical-align: text-bottom;" src="{media '/idf/img/help.png'}" alt="{trans 'Help'}" /></a></p> | <p class="right soft"><a href="{$url}"><img style="vertical-align: text-bottom;" src="{media '/idf/img/package-grey.png'}" alt="{trans 'Archive'}" align="bottom" /></a> <a href="{$url}">{trans 'Download this version'}</a> {trans 'or'} <kbd>git clone {$project.getSourceAccessUrl($user)}</kbd> <a href="{url 'IDF_Views_Source::help', array($project.shortname)}"><img style="vertical-align: text-bottom;" src="{media '/idf/img/help.png'}" alt="{trans 'Help'}" /></a></p> | ||||||
|  |  | ||||||
|  |  | ||||||
| {/block} | {/block} | ||||||
| {block context} | {block context} | ||||||
| <p><strong>{trans 'Branches:'}</strong><br /> | <p><strong>{trans 'Branches:'}</strong><br /> | ||||||
| {foreach $branches as $branch} | {foreach $branches as $branch => $path} | ||||||
| {aurl 'url', 'IDF_Views_Source::treeBase', array($project.shortname, $branch)} | {aurl 'url', 'IDF_Views_Source::treeBase', array($project.shortname, $branch)} | ||||||
| <span class="label{if $commit == $branch} active{/if}"><a href="{$url}" class="label">{$branch}</a></span><br /> | <span class="label{if in_array($branch, $tree_in)} active{/if}"><a href="{$url}" class="label">{if $path}{$path}{else}{$branch}{/if}</a></span><br /> | ||||||
| {/foreach} | {/foreach} | ||||||
| </p> | </p> | ||||||
| {/block} | {/block} | ||||||
|   | |||||||
							
								
								
									
										10
									
								
								src/IDF/templates/idf/source/mercurial/changelog.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								src/IDF/templates/idf/source/mercurial/changelog.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | |||||||
|  | {extends "idf/source/changelog.html"} | ||||||
|  | {block context} | ||||||
|  | <p><strong>{trans 'Branches:'}</strong><br /> | ||||||
|  | {foreach $branches as $branch => $path} | ||||||
|  | {aurl 'url', 'IDF_Views_Source::changeLog', array($project.shortname, $branch)} | ||||||
|  | <span class="label{if in_array($branch, $tree_in)} active{/if}"><a href="{$url}" class="label">{$branch}</a></span><br /> | ||||||
|  | {/foreach} | ||||||
|  | </p> | ||||||
|  | {/block} | ||||||
|  |  | ||||||
| @@ -24,9 +24,9 @@ | |||||||
|  |  | ||||||
| {block context} | {block context} | ||||||
| <p><strong>{trans 'Branches:'}</strong><br /> | <p><strong>{trans 'Branches:'}</strong><br /> | ||||||
| {foreach $branches as $branch} | {foreach $branches as $branch => $path} | ||||||
| {aurl 'url', 'IDF_Views_Source::treeBase', array($project.shortname, $branch)} | {aurl 'url', 'IDF_Views_Source::treeBase', array($project.shortname, $branch)} | ||||||
| <span class="label{if $commit == $branch} active{/if}"><a href="{$url}" class="label">{$branch}</a></span><br /> | <span class="label{if in_array($branch, $tree_in)} active{/if}"><a href="{$url}" class="label">{$branch}</a></span><br /> | ||||||
| {/foreach} | {/foreach} | ||||||
| </p> | </p> | ||||||
| {/block} | {/block} | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| {extends "idf/source/base.html"} | {extends "idf/source/base.html"} | ||||||
| {block docclass}yui-t2{/block} | {block docclass}yui-t2{assign $inHelp=true}{/block} | ||||||
| {block body} | {block body} | ||||||
|  |  | ||||||
| <p>{blocktrans}The team behind {$project} is using | <p>{blocktrans}The team behind {$project} is using | ||||||
|   | |||||||
| @@ -48,9 +48,10 @@ | |||||||
|  |  | ||||||
| {block context} | {block context} | ||||||
| <p><strong>{trans 'Branches:'}</strong><br /> | <p><strong>{trans 'Branches:'}</strong><br /> | ||||||
| {foreach $branches as $branch} | {foreach $branches as $branch => $path} | ||||||
| {aurl 'url', 'IDF_Views_Source::treeBase', array($project.shortname, $branch)} | {aurl 'url', 'IDF_Views_Source::treeBase', array($project.shortname, $branch)} | ||||||
| <span class="label{if $commit == $branch} active{/if}"><a href="{$url}" class="label">{$branch}</a></span><br /> | <span class="label{if in_array($branch, $tree_in)} active{/if}"><a href="{$url}" class="label">{$branch}</a></span><br /> | ||||||
| {/foreach} | {/foreach} | ||||||
| </p> | </p> | ||||||
| {/block} | {/block} | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										11
									
								
								src/IDF/templates/idf/source/svn/changelog.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								src/IDF/templates/idf/source/svn/changelog.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | |||||||
|  | {extends "idf/source/changelog.html"} | ||||||
|  | {block context} | ||||||
|  | <form class="star" action="{url 'IDF_Views_Source_Svn::changelogRev', array($project.shortname)}" method="get"> | ||||||
|  | <p><strong>{trans 'Revision:'}</strong> {$commit}</p> | ||||||
|  | <p> | ||||||
|  |     <input accesskey="4" type="text" value="{$commit}" name="rev" size="5" /> | ||||||
|  |     <input type="submit" name="s" value="{trans 'Go to revision'}" /> | ||||||
|  | </p> | ||||||
|  | </form> | ||||||
|  | {/block} | ||||||
|  |  | ||||||
| @@ -1,5 +1,5 @@ | |||||||
| {extends "idf/source/base.html"} | {extends "idf/source/base.html"} | ||||||
| {block docclass}yui-t2{/block} | {block docclass}yui-t2{assign $inHelp=true}{/block} | ||||||
| {block body} | {block body} | ||||||
|  |  | ||||||
| <p>{blocktrans}The team behind {$project} is using | <p>{blocktrans}The team behind {$project} is using | ||||||
|   | |||||||
| @@ -68,5 +68,12 @@ | |||||||
|     <input type="hidden" name="sourcefile" value="{$base}"/> |     <input type="hidden" name="sourcefile" value="{$base}"/> | ||||||
|     <input type="submit" name="s" value="{trans 'Go to revision'}" /></p> |     <input type="submit" name="s" value="{trans 'Go to revision'}" /></p> | ||||||
|   </form> |   </form> | ||||||
|  | <p><strong>{trans 'Branches:'}</strong><br /> | ||||||
|  | {foreach $branches as $branch => $path} | ||||||
|  | {if $path}{aurl 'url', 'IDF_Views_Source::tree', array($project.shortname, 'HEAD', $path)} | ||||||
|  | {else}{aurl 'url', 'IDF_Views_Source::treeBase', array($project.shortname, 'HEAD')}{/if} | ||||||
|  | <span class="label{if in_array($branch, $tree_in)} active{/if}"><a href="{$url}" class="label">{$branch}</a></span><br /> | ||||||
|  | {/foreach} | ||||||
|  | </p> | ||||||
|  |  | ||||||
| {/block} | {/block} | ||||||
|   | |||||||
| @@ -96,6 +96,7 @@ $(document).ready(function() { | |||||||
|     $("#form-show-0").click(function(){ |     $("#form-show-0").click(function(){ | ||||||
|         $(".pass-info").show(); |         $(".pass-info").show(); | ||||||
|         $("#form-block-0").hide(); |         $("#form-block-0").hide(); | ||||||
|  |         return false; | ||||||
|     }); |     }); | ||||||
|     $(".pass-info").hide(); |     $(".pass-info").hide(); | ||||||
| });{/literal} | });{/literal} | ||||||
|   | |||||||
| @@ -3,7 +3,7 @@ | |||||||
| {block body} | {block body} | ||||||
|  |  | ||||||
| {if $preview} | {if $preview} | ||||||
| <h2 class="top">{trans 'Preview of the Page'}</h2> | <h2 id="preview" class="top">{trans 'Preview of the Page'}</h2> | ||||||
|  |  | ||||||
| {markdown $preview, $request} | {markdown $preview, $request} | ||||||
| {/if} | {/if} | ||||||
|   | |||||||
| @@ -3,7 +3,7 @@ | |||||||
| {block body} | {block body} | ||||||
|  |  | ||||||
| {if $preview} | {if $preview} | ||||||
| <h2 class="top">{trans 'Preview of the Page'}</h2> | <h2 id="preview" class="top">{trans 'Preview of the Page'}</h2> | ||||||
|  |  | ||||||
| {markdown $preview, $request} | {markdown $preview, $request} | ||||||
| {/if} | {/if} | ||||||
|   | |||||||
| @@ -24,7 +24,7 @@ body { | |||||||
| } | } | ||||||
|  |  | ||||||
| .top {  | .top {  | ||||||
|   margin-top: 0; |   margin-top: 5px; | ||||||
| } | } | ||||||
|  |  | ||||||
| a:link {  | a:link {  | ||||||
| @@ -54,7 +54,6 @@ a:active{ | |||||||
| .dellink {  | .dellink {  | ||||||
|   float: right;  |   float: right;  | ||||||
|   position: relative;  |   position: relative;  | ||||||
|   margin-top: -1.6em; |  | ||||||
| } | } | ||||||
|  |  | ||||||
| .dellink a {  | .dellink a {  | ||||||
| @@ -192,6 +191,10 @@ span.px-header-title { | |||||||
|   white-space: nowrap;   |   white-space: nowrap;   | ||||||
| } | } | ||||||
|  |  | ||||||
|  | span.px-header-title a, span.px-header-title a:link, span.px-header-title a:visited, span.px-header-title a:active {  | ||||||
|  |   color: #000; | ||||||
|  | } | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Issue |  * Issue | ||||||
|  */ |  */ | ||||||
| @@ -221,7 +224,9 @@ div.issue-comment-first { | |||||||
|  |  | ||||||
| div.issue-comment-signin {  | div.issue-comment-signin {  | ||||||
|   -moz-border-radius: 0 0 3px 3px; |   -moz-border-radius: 0 0 3px 3px; | ||||||
|   -webkit-border-radius: 0 0 3px 3px; |   -webkit-border-radius: 3px; | ||||||
|  |   -webkit-border-top-left-radius: 0; | ||||||
|  |   -webkit-border-top-right-radius: 0; | ||||||
|   background-color: #d3d7cf; |   background-color: #d3d7cf; | ||||||
|   padding: 4px; |   padding: 4px; | ||||||
| } | } | ||||||
| @@ -302,6 +307,7 @@ h1.project-title { | |||||||
|   z-index: 100; |   z-index: 100; | ||||||
|   text-align: right; |   text-align: right; | ||||||
|   padding-right: 5px; |   padding-right: 5px; | ||||||
|  |   margin-bottom: 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| .note {  | .note {  | ||||||
| @@ -332,10 +338,16 @@ div.container { | |||||||
| /** | /** | ||||||
|  * Tabs |  * Tabs | ||||||
|  */ |  */ | ||||||
|  | #main-tabs {  | ||||||
|  |   line-height: normal; | ||||||
|  | } | ||||||
|  |  | ||||||
| #main-tabs a {  | #main-tabs a {  | ||||||
|   background-color: #d3d7cf; |   background-color: #d3d7cf; | ||||||
|   -moz-border-radius: 3px 3px 0 0; |   -moz-border-radius: 3px 3px 0 0; | ||||||
|   -webkit-border-radius: 3px 3px 0 0; |   -webkit-border-radius: 3px; | ||||||
|  |   -webkit-border-bottom-left-radius: 0; | ||||||
|  |   -webkit-border-bottom-right-radius: 0; | ||||||
|   padding: 4px 4px 0 4px;  |   padding: 4px 4px 0 4px;  | ||||||
|   text-decoration: none; |   text-decoration: none; | ||||||
|   color: #2e3436; |   color: #2e3436; | ||||||
| @@ -349,7 +361,8 @@ div.container { | |||||||
| #sub-tabs {  | #sub-tabs {  | ||||||
|   background-color: #a5e26a; |   background-color: #a5e26a; | ||||||
|   -moz-border-radius: 0 3px 3px 3px; |   -moz-border-radius: 0 3px 3px 3px; | ||||||
|   -webkit-border-radius: 0 3px 3px 3px; |   -webkit-border-radius: 3px; | ||||||
|  |   -webkit-border-top-left-radius: 0; | ||||||
|   padding: 4px; |   padding: 4px; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -616,13 +629,17 @@ div.download-file { | |||||||
|   background-repeat: no-repeat; |   background-repeat: no-repeat; | ||||||
|   background-position: 1em 1em; |   background-position: 1em 1em; | ||||||
|   font-size: 140%; |   font-size: 140%; | ||||||
|   margin-bottom: 3em; |   margin-bottom: 1.5em; | ||||||
|   background-color: #bbe394; |   background-color: #bbe394; | ||||||
|   width: 40%; |   width: 40%; | ||||||
|   -moz-border-radius: 5px; |   -moz-border-radius: 5px; | ||||||
|   -webkit-border-radius: 5px; |   -webkit-border-radius: 5px; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | table.download {  | ||||||
|  |   margin-top: 1.5em; | ||||||
|  | } | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Wiki |  * Wiki | ||||||
|  */ |  */ | ||||||
| @@ -678,7 +695,9 @@ div.deprecated-page { | |||||||
|   padding-left: 0px; |   padding-left: 0px; | ||||||
|   background-color: #eeeeec;  |   background-color: #eeeeec;  | ||||||
|   -moz-border-radius: 3px 0 0 3px; |   -moz-border-radius: 3px 0 0 3px; | ||||||
|   -webkit-border-radius: 3px 0 0 3px; |   -webkit-border-radius: 3px; | ||||||
|  |   -webkit-border-top-right-radius: 0; | ||||||
|  |   -webkit-border-bottom-right-radius: 0; | ||||||
|   color: #888a85; |   color: #888a85; | ||||||
|   clear: both; |   clear: both; | ||||||
|   background-image: url("../img/ceondo.png"); |   background-image: url("../img/ceondo.png"); | ||||||
|   | |||||||
							
								
								
									
										
											BIN
										
									
								
								www/media/idf/img/lock.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								www/media/idf/img/lock.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 430 B | 
		Reference in New Issue
	
	Block a user