diff --git a/scripts/mtn-post-push b/scripts/mtn-post-push index 46f5d3b..e41b41f 100755 --- a/scripts/mtn-post-push +++ b/scripts/mtn-post-push @@ -15,8 +15,7 @@ res=$(cd "$dir" && /bin/pwd || "$dir") SCRIPTDIR="$res/$(readlink $0)" PHP_POST_PUSH=$SCRIPTDIR/mtnpostpush.php -base=$(basename "$0") -TMPFILE=$(mktemp /tmp/${tempfoo}.XXXXXX) || exit 1 +TMPFILE=$(mktemp /tmp/mtn-post-push.XXXXXX) || exit 1 while read rev; do echo $rev >> $TMPFILE; done echo php $PHP_POST_PUSH "$1" \< $TMPFILE \&\& rm -f $TMPFILE |\ diff --git a/src/IDF/Form/Admin/ProjectCreate.php b/src/IDF/Form/Admin/ProjectCreate.php index d297f14..f6b75a8 100644 --- a/src/IDF/Form/Admin/ProjectCreate.php +++ b/src/IDF/Form/Admin/ProjectCreate.php @@ -313,6 +313,7 @@ class IDF_Form_Admin_ProjectCreate extends Pluf_Form 'labels_download_one_max' => IDF_Form_UploadConf::init_one_max, 'labels_wiki_predefined' => IDF_Form_WikiConf::init_predefined, 'labels_wiki_one_max' => IDF_Form_WikiConf::init_one_max, + 'labels_issue_template' => IDF_Form_IssueTrackingConf::init_template, 'labels_issue_open' => IDF_Form_IssueTrackingConf::init_open, 'labels_issue_closed' => IDF_Form_IssueTrackingConf::init_closed, 'labels_issue_predefined' => IDF_Form_IssueTrackingConf::init_predefined, diff --git a/src/IDF/Form/IssueCreate.php b/src/IDF/Form/IssueCreate.php index 56f9ceb..3c38e7b 100644 --- a/src/IDF/Form/IssueCreate.php +++ b/src/IDF/Form/IssueCreate.php @@ -45,6 +45,9 @@ class IDF_Form_IssueCreate extends Pluf_Form or $this->user->hasPerm('IDF.project-member', $this->project)) { $this->show_full = true; } + $contentTemplate = $this->project->getConf()->getVal( + 'labels_issue_template', IDF_Form_IssueTrackingConf::init_template + ); $this->fields['summary'] = new Pluf_Form_Field_Varchar( array('required' => true, 'label' => __('Summary'), @@ -57,7 +60,7 @@ class IDF_Form_IssueCreate extends Pluf_Form $this->fields['content'] = new Pluf_Form_Field_Varchar( array('required' => true, 'label' => __('Description'), - 'initial' => '', + 'initial' => $contentTemplate, 'widget' => 'Pluf_Form_Widget_TextareaInput', 'widget_attrs' => array( 'cols' => 58, diff --git a/src/IDF/Form/IssueTrackingConf.php b/src/IDF/Form/IssueTrackingConf.php index ae7a9d0..0aa4f59 100644 --- a/src/IDF/Form/IssueTrackingConf.php +++ b/src/IDF/Form/IssueTrackingConf.php @@ -31,6 +31,15 @@ class IDF_Form_IssueTrackingConf extends Pluf_Form * Defined as constants to easily access the value in the * IssueUpdate/Create form in the case nothing is in the db yet. */ + const init_template = 'Steps to reproduce the problem: +1. +2. +3. + +Expected result: + +Actual result: +'; const init_open = 'New = Issue has not had initial review yet Accepted = Problem reproduced / Need acknowledged Started = Work on this issue has begun'; @@ -66,6 +75,15 @@ Maintainability = Hinders future changes'; public function initFields($extra=array()) { + $this->fields['labels_issue_template'] = new Pluf_Form_Field_Varchar( + array('required' => false, + 'label' => __('Define an issue template to hint the reporter to provide certain information'), + 'initial' => self::init_template, + 'widget_attrs' => array('rows' => 7, + 'cols' => 75), + 'widget' => 'Pluf_Form_Widget_TextareaInput', + )); + $this->fields['labels_issue_open'] = new Pluf_Form_Field_Varchar( array('required' => true, 'label' => __('Open issue status values'), @@ -99,8 +117,6 @@ Maintainability = Hinders future changes'; 'widget_attrs' => array('size' => 60), )); - - } } diff --git a/src/IDF/Middleware.php b/src/IDF/Middleware.php index 424cc01..b836e25 100644 --- a/src/IDF/Middleware.php +++ b/src/IDF/Middleware.php @@ -112,6 +112,7 @@ function IDF_Middleware_ContextPreProcessor($request) $c = array_merge($c, $request->rights); } $c['usherConfigured'] = Pluf::f("mtn_usher_conf", null) !== null; + $c['allProjects'] = IDF_Views::getProjects($request->user); return $c; } diff --git a/src/IDF/Plugin/SyncMonotone.php b/src/IDF/Plugin/SyncMonotone.php index e34c674..2da68cd 100644 --- a/src/IDF/Plugin/SyncMonotone.php +++ b/src/IDF/Plugin/SyncMonotone.php @@ -250,7 +250,9 @@ class IDF_Plugin_SyncMonotone array('key' => 'server', 'values' => array($shortname)), array('key' => 'local', 'values' => array( '--confdir', $projectpath, - '-d', $dbfile + '-d', $dbfile, + '--timestamps', + '--ticker=dot' )), ); diff --git a/src/IDF/Scm/Monotone.php b/src/IDF/Scm/Monotone.php index 13a33e1..74c6b78 100644 --- a/src/IDF/Scm/Monotone.php +++ b/src/IDF/Scm/Monotone.php @@ -413,7 +413,7 @@ class IDF_Scm_Monotone extends IDF_Scm $certs = $scm->_getCerts($revs[0]); // for the very seldom case that a revision // has no branch certificate - if (count($certs['branch']) == 0) { + if (!array_key_exists('branch', $certs)) { $branch = '*'; } else diff --git a/src/IDF/Views/Project.php b/src/IDF/Views/Project.php index 48ed153..20854d9 100644 --- a/src/IDF/Views/Project.php +++ b/src/IDF/Views/Project.php @@ -61,6 +61,66 @@ class IDF_Views_Project $request); } + /** + * Returns an associative array with available model filters + * + * @return array + */ + private static function getAvailableModelFilters() + { + return array( + 'all' => __('All Updates'), + 'commits' => __('Commits'), + 'issues' => __('Issues and Comments'), + 'downloads' => __('Downloads'), + 'documents' => __('Documents'), + 'reviews' => __('Reviews and Patches'), + ); + } + + /** + * Returns an array of model classes for which the current user + * has rights and which should be used according to his filter + * + * @param object $request + * @param string $model_filter + * @return array + */ + private static function determineModelClasses($request, $model_filter = 'all') + { + $classes = array(); + if (true === IDF_Precondition::accessSource($request) && + ($model_filter == 'all' || $model_filter == 'commits')) { + $classes[] = '\'IDF_Commit\''; + // FIXME: this looks like a hack... + IDF_Scm::syncTimeline($request->project); + } + if (true === IDF_Precondition::accessIssues($request) && + ($model_filter == 'all' || $model_filter == 'issues')) { + $classes[] = '\'IDF_Issue\''; + $classes[] = '\'IDF_IssueComment\''; + } + if (true === IDF_Precondition::accessDownloads($request) && + ($model_filter == 'all' || $model_filter == 'downloads')) { + $classes[] = '\'IDF_Upload\''; + } + if (true === IDF_Precondition::accessWiki($request) && + ($model_filter == 'all' || $model_filter == 'documents')) { + $classes[] = '\'IDF_WikiPage\''; + $classes[] = '\'IDF_WikiRevision\''; + } + if (true === IDF_Precondition::accessReview($request) && + ($model_filter == 'all' || $model_filter == 'reviews')) { + $classes[] = '\'IDF_Review_Comment\''; + $classes[] = '\'IDF_Review_Patch\''; + } + if (count($classes) == 0) { + $classes[] = '\'IDF_Dummy\''; + } + + return $classes; + } + /** * Timeline of the project. */ @@ -68,38 +128,21 @@ class IDF_Views_Project public function timeline($request, $match) { $prj = $request->project; - $title = sprintf(__('%s Updates'), (string) $prj); - $team = $prj->getMembershipData(); + + $model_filter = @$match[2]; + $all_model_filters = self::getAvailableModelFilters(); + if (!array_key_exists($model_filter, $all_model_filters)) { + $model_filter = 'all'; + } + $title = (string)$prj . ' ' . $all_model_filters[$model_filter]; $pag = new IDF_Timeline_Paginator(new IDF_Timeline()); $pag->class = 'recent-issues'; $pag->item_extra_props = array('request' => $request); $pag->summary = __('This table shows the project updates.'); - // Need to check the rights - $rights = array(); - if (true === IDF_Precondition::accessSource($request)) { - $rights[] = '\'IDF_Commit\''; - IDF_Scm::syncTimeline($request->project); - } - if (true === IDF_Precondition::accessIssues($request)) { - $rights[] = '\'IDF_Issue\''; - $rights[] = '\'IDF_IssueComment\''; - } - if (true === IDF_Precondition::accessDownloads($request)) { - $rights[] = '\'IDF_Upload\''; - } - if (true === IDF_Precondition::accessWiki($request)) { - $rights[] = '\'IDF_WikiPage\''; - $rights[] = '\'IDF_WikiRevision\''; - } - if (true === IDF_Precondition::accessReview($request)) { - $rights[] = '\'IDF_Review_Comment\''; - $rights[] = '\'IDF_Review_Patch\''; - } - if (count($rights) == 0) { - $rights[] = '\'IDF_Dummy\''; - } - $sql = sprintf('model_class IN (%s)', implode(', ', $rights)); + + $classes = self::determineModelClasses($request, $model_filter); + $sql = sprintf('model_class IN (%s)', implode(', ', $classes)); $pag->forced_where = new Pluf_SQL('project=%s AND '.$sql, array($prj->id)); $pag->sort_order = array('creation_dtime', 'ASC'); @@ -113,32 +156,23 @@ class IDF_Views_Project $pag->items_per_page = 20; $pag->no_results_text = __('No changes were found.'); $pag->setFromRequest($request); - $downloads = array(); - if ($request->rights['hasDownloadsAccess']) { - $tags = IDF_Views_Download::getDownloadTags($prj); - // the first tag is the featured, the last is the deprecated. - $downloads = $tags[0]->get_idf_upload_list(); - } - $pages = array(); - if ($request->rights['hasWikiAccess']) { - $tags = IDF_Views_Wiki::getWikiTags($prj); - $pages = $tags[0]->get_idf_wikipage_list(); - } + if (!$request->user->isAnonymous() and $prj->isRestricted()) { $feedurl = Pluf_HTTP_URL_urlForView('idf_project_timeline_feed_auth', array($prj->shortname, + $model_filter, IDF_Precondition::genFeedToken($prj, $request->user))); } else { $feedurl = Pluf_HTTP_URL_urlForView('idf_project_timeline_feed', - array($prj->shortname)); + array($prj->shortname, $model_filter)); } return Pluf_Shortcuts_RenderToResponse('idf/project/timeline.html', array( 'page_title' => $title, 'feedurl' => $feedurl, 'timeline' => $pag, - 'team' => $team, - 'downloads' => $downloads, + 'model_filter' => $model_filter, + 'all_model_filters' => $all_model_filters, ), $request); @@ -156,31 +190,17 @@ class IDF_Views_Project public function timelineFeed($request, $match) { $prj = $request->project; - // Need to check the rights - $rights = array(); - if (true === IDF_Precondition::accessSource($request)) { - $rights[] = '\'IDF_Commit\''; - IDF_Scm::syncTimeline($request->project); + $model_filter = @$match[2]; + + $model_filter = @$match[2]; + $all_model_filters = self::getAvailableModelFilters(); + if (!array_key_exists($model_filter, $all_model_filters)) { + $model_filter = 'all'; } - if (true === IDF_Precondition::accessIssues($request)) { - $rights[] = '\'IDF_Issue\''; - $rights[] = '\'IDF_IssueComment\''; - } - if (true === IDF_Precondition::accessDownloads($request)) { - $rights[] = '\'IDF_Upload\''; - } - if (true === IDF_Precondition::accessWiki($request)) { - $rights[] = '\'IDF_WikiPage\''; - $rights[] = '\'IDF_WikiRevision\''; - } - if (true === IDF_Precondition::accessReview($request)) { - $rights[] = '\'IDF_Review_Comment\''; - $rights[] = '\'IDF_Review_Patch\''; - } - if (count($rights) == 0) { - $rights[] = '\'IDF_Dummy\''; - } - $sqls = sprintf('model_class IN (%s)', implode(', ', $rights)); + $title = $all_model_filters[$model_filter]; + + $classes = self::determineModelClasses($request, $model_filter); + $sqls = sprintf('model_class IN (%s)', implode(', ', $classes)); $sql = new Pluf_SQL('project=%s AND '.$sqls, array($prj->id)); $params = array( 'filter' => $sql->gen(), @@ -203,7 +223,6 @@ class IDF_Views_Project } $out = Pluf_Template::markSafe(implode("\n", $out)); $tmpl = new Pluf_Template('idf/index.atom'); - $title = __('Updates'); $feedurl = Pluf::f('url_base').Pluf::f('idf_base').$request->query; $viewurl = Pluf_HTTP_URL_urlForView('IDF_Views_Project::timeline', array($prj->shortname)); @@ -277,7 +296,8 @@ class IDF_Views_Project } } else { $params = array(); - $keys = array('labels_issue_open', 'labels_issue_closed', + $keys = array('labels_issue_template', + 'labels_issue_open', 'labels_issue_closed', 'labels_issue_predefined', 'labels_issue_one_max'); foreach ($keys as $key) { $_val = $conf->getVal($key, false); @@ -535,4 +555,4 @@ class IDF_Views_Project ), $request); } -} \ No newline at end of file +} diff --git a/src/IDF/Views/Source.php b/src/IDF/Views/Source.php index 2d1b3f8..d53e644 100644 --- a/src/IDF/Views/Source.php +++ b/src/IDF/Views/Source.php @@ -533,8 +533,10 @@ class IDF_Views_Source if (0 === strpos($fileinfo[0], 'text/')) { return true; } - $ext = 'mdtext php-dist h gitignore diff patch' - .Pluf::f('idf_extra_text_ext', ''); + $ext = 'mdtext php-dist h gitignore diff patch'; + $extra_ext = trim(Pluf::f('idf_extra_text_ext', '')); + if (!empty($extra_ext)) + $ext .= ' ' . $extra_ext; $ext = array_merge(self::$supportedExtenstions, explode(' ' , $ext)); return (in_array($fileinfo[2], $ext)); } diff --git a/src/IDF/conf/idf.php-dist b/src/IDF/conf/idf.php-dist index 2e4ffcf..e1dbd4a 100644 --- a/src/IDF/conf/idf.php-dist +++ b/src/IDF/conf/idf.php-dist @@ -205,8 +205,8 @@ $cfg['db_database'] = 'website'; # put absolute path to the db if you # are using SQLite. # # The extension of the downloads are limited. You can add extra -# extensions here. The list must start with a space. -# $cfg['idf_extra_upload_ext'] = ' ext1 ext2'; +# extensions here. +# $cfg['idf_extra_upload_ext'] = 'ext1 ext2'; # # By default, the size of the downloads is limited to 2MB. # The php.ini upload_max_filesize configuration setting will @@ -256,6 +256,13 @@ $cfg['allowed_scm'] = array('git' => 'IDF_Scm_Git', 'mtn' => 'IDF_Scm_Monotone', ); +# Set to true when uploaded public keys should not only be validated +# syntactically, but also by the specific backend. For SSH public +# keys, ssh-keygen(3) must be available and usable in PATH, for +# monotone public keys, the monotone binary (as configured above) +# is used. +# $cfg['idf_strong_key_check'] = false; + # If you want to use another memtypes database # $cfg['idf_mimetypes_db'] = '/etc/mime.types'; diff --git a/src/IDF/conf/urls.php b/src/IDF/conf/urls.php index c01e565..1afe134 100644 --- a/src/IDF/conf/urls.php +++ b/src/IDF/conf/urls.php @@ -74,18 +74,18 @@ $ctl[] = array('regex' => '#^/p/([\-\w]+)/$#', 'model' => 'IDF_Views_Project', 'method' => 'home'); -$ctl[] = array('regex' => '#^/p/([\-\w]+)/timeline/$#', +$ctl[] = array('regex' => '#^/p/([\-\w]+)/timeline/(\w+)/$#', 'base' => $base, 'model' => 'IDF_Views_Project', 'method' => 'timeline'); -$ctl[] = array('regex' => '#^/p/([\-\w]+)/feed/timeline/$#', +$ctl[] = array('regex' => '#^/p/([\-\w]+)/feed/timeline/(\w+)/$#', 'base' => $base, 'model' => 'IDF_Views_Project', 'method' => 'timelineFeed', 'name' => 'idf_project_timeline_feed'); -$ctl[] = array('regex' => '#^/p/([\-\w]+)/feed/timeline/token/(.*)/$#', +$ctl[] = array('regex' => '#^/p/([\-\w]+)/feed/timeline/(\w+)/token/(.*)/$#', 'base' => $base, 'model' => 'IDF_Views_Project', 'method' => 'timelineFeed', diff --git a/src/IDF/relations.php b/src/IDF/relations.php index 9442aba..6848e1a 100644 --- a/src/IDF/relations.php +++ b/src/IDF/relations.php @@ -96,7 +96,7 @@ Pluf_Signal::connect('IDF_Key::postSave', array('IDF_Plugin_SyncMonotone', 'entry')); Pluf_Signal::connect('IDF_Key::preDelete', array('IDF_Plugin_SyncMonotone', 'entry')); -Pluf_Signal::connect('phppostpush.php::run', +Pluf_Signal::connect('mtnpostpush.php::run', array('IDF_Plugin_SyncMonotone', 'entry')); # diff --git a/src/IDF/templates/idf/admin/issue-tracking.html b/src/IDF/templates/idf/admin/issue-tracking.html index f835a68..fb5766c 100644 --- a/src/IDF/templates/idf/admin/issue-tracking.html +++ b/src/IDF/templates/idf/admin/issue-tracking.html @@ -4,6 +4,12 @@
+ + +
{$form.f.labels_issue_template.labelTag}:
+{if $form.f.labels_issue_template.errors}{$form.f.labels_issue_template.fieldErrors}{/if} +{$form.f.labels_issue_template|unsafe} +
{$form.f.labels_issue_open.labelTag}:
{if $form.f.labels_issue_open.errors}{$form.f.labels_issue_open.fieldErrors}{/if} {$form.f.labels_issue_open|unsafe} diff --git a/src/IDF/templates/idf/base-full.html b/src/IDF/templates/idf/base-full.html index fbb7280..23b5863 100644 --- a/src/IDF/templates/idf/base-full.html +++ b/src/IDF/templates/idf/base-full.html @@ -29,22 +29,19 @@ {block extraheader}{/block} {block pagetitle}{$page_title|strip_tags}{/block}{if $project} - {$project.shortdesc}{/if} +
-{if $project}

{$project}

{/if} -

-{if !$user.isAnonymous()}{aurl 'url', 'idf_dashboard'}{blocktrans}Welcome, {$user}.{/blocktrans} {trans 'Sign Out'}{else}{trans 'Sign in or create your account'}{/if} -{if $project} | {trans 'Project List'}{/if} -| {trans 'Help'} -

+ {if $project}

{$project}

{/if} + {include 'idf/main-menu.html'}
-
+
-
+
{if $user and $user.id}{getmsgs $user}{/if} -
{block body}{/block}
-
+
{block body}{/block}
+
{block foot}{/block}
- {include 'idf/js-hotkeys.html'} {block javascript}{/block} {if $project} {/if} diff --git a/src/IDF/templates/idf/base-simple.html b/src/IDF/templates/idf/base-simple.html index a88f42d..98dd8d1 100644 --- a/src/IDF/templates/idf/base-simple.html +++ b/src/IDF/templates/idf/base-simple.html @@ -29,31 +29,27 @@ {block extraheader}{/block} {block pagetitle}{$page_title|strip_tags}{/block} +
-

-{if !$user.isAnonymous()}{aurl 'url', 'idf_dashboard'}{blocktrans}Welcome, {$user}.{/blocktrans} {trans 'Sign Out'}{else}{trans 'Sign in or create your account'}{/if} - | {trans 'Project List'} {if $isAdmin}| {trans 'Forge Management'}{/if} -| {trans 'Help'} -

-

{block title}{$page_title}{/block}

+ {include 'idf/main-menu.html'} +

{block title}{$page_title}{/block}

-
+
-
+
{if $user and $user.id}{getmsgs $user}{/if} -
{block body}{/block}
-
+
{block body}{/block}
+
{block context}{/block}
{block foot}{/block}
- {include 'idf/js-hotkeys.html'} {block javascript}{/block} diff --git a/src/IDF/templates/idf/base.html b/src/IDF/templates/idf/base.html index 6a8182b..772bbd5 100644 --- a/src/IDF/templates/idf/base.html +++ b/src/IDF/templates/idf/base.html @@ -29,23 +29,19 @@ {block extraheader}{/block} {block pagetitle}{$page_title|strip_tags}{/block}{if $project} - {$project.shortdesc}{/if} +
-{if $project}

{$project}

{/if} -

-{if !$user.isAnonymous()}{aurl 'url', 'idf_dashboard'}{blocktrans}Welcome, {$user}.{/blocktrans} {trans 'Sign Out'}{else}{trans 'Sign in or create your account'}{/if} -{if $project} | {trans 'Project List'}{/if} -{if $isAdmin}| {trans 'Forge Management'}{/if} -| {trans 'Help'} -

+ {if $project}

{$project}

{/if} + {include 'idf/main-menu.html'}
-
+
-
+
{if $user and $user.id}{getmsgs $user}{/if} -
{block body}{/block}
-
+
{block body}{/block}
+
{block context}{/block}
{block foot}{/block}
- {include 'idf/js-hotkeys.html'} {block javascript}{/block} {if $project} {/if} diff --git a/src/IDF/templates/idf/gadmin/base.html b/src/IDF/templates/idf/gadmin/base.html index 1858682..b68a99d 100644 --- a/src/IDF/templates/idf/gadmin/base.html +++ b/src/IDF/templates/idf/gadmin/base.html @@ -29,16 +29,12 @@ {block extraheader}{/block} {block pagetitle}{$page_title|strip_tags}{/block} +
-

-{aurl 'url', 'IDF_Views_User::dashboard'}{blocktrans}Welcome, {$user}.{/blocktrans} {trans 'Sign Out'} -| {trans 'Project List'} -| {trans 'Forge Management'} -| {trans 'Help'} -

+ {include 'idf/main-menu.html'} - {include 'idf/js-hotkeys.html'} {block javascript}{/block} diff --git a/src/IDF/templates/idf/js-hotkeys.html b/src/IDF/templates/idf/js-hotkeys.html index ee39cac..66793fb 100644 --- a/src/IDF/templates/idf/js-hotkeys.html +++ b/src/IDF/templates/idf/js-hotkeys.html @@ -3,7 +3,7 @@ //