diff --git a/src/IDF/Form/Admin/ProjectCreate.php b/src/IDF/Form/Admin/ProjectCreate.php index 1a4887d..b2ef162 100644 --- a/src/IDF/Form/Admin/ProjectCreate.php +++ b/src/IDF/Form/Admin/ProjectCreate.php @@ -118,6 +118,20 @@ class IDF_Form_Admin_ProjectCreate extends Pluf_Form 'cols' => 40), 'widget' => 'Pluf_Form_Widget_TextareaInput', )); + + $projects = array('--' => '--'); + foreach (Pluf::factory('IDF_Project')->getList(array('order' => 'name ASC')) as $proj) { + $projects[$proj->name] = $proj->shortname; + } + $this->fields['template'] = new Pluf_Form_Field_Varchar( + array('required' => false, + 'label' => __('Project template'), + 'initial' => '--', + 'help_text' => __('Use the given project to initialize the new project. Access rights and general configuration will be taken from the template project.'), + 'widget' => 'Pluf_Form_Widget_SelectInput', + 'widget_attrs' => array('choices' => $projects), + )); + /** * [signal] * @@ -259,8 +273,18 @@ class IDF_Form_Admin_ProjectCreate extends Pluf_Form $project = new IDF_Project(); $project->name = $this->cleaned_data['name']; $project->shortname = $this->cleaned_data['shortname']; - $project->private = $this->cleaned_data['private_project']; - $project->description = __('Click on the Project Management tab to set the description of your project.'); + + if ($this->cleaned_data['template'] != '--') { + // Find the template project + $sql = new Pluf_SQL('shortname=%s', + array($this->cleaned_data['template'])); + $tmpl = Pluf::factory('IDF_Project')->getOne(array('filter' => $sql->gen())); + $project->private = $tmpl->private; + $project->description = $tmpl->description; + } else { + $project->private = $this->cleaned_data['private_project']; + $project->description = __('Click on the Project Management tab to set the description of your project.'); + } $project->create(); $conf = new IDF_Conf(); $conf->setProject($project); @@ -271,12 +295,64 @@ class IDF_Form_Admin_ProjectCreate extends Pluf_Form $this->cleaned_data[$key] : ''; $conf->setVal($key, $this->cleaned_data[$key]); } + if ($this->cleaned_data['template'] != '--') { + $tmplconf = new IDF_Conf(); + $tmplconf->setProject($tmpl); + // We need to get all the configuration variables we want from + // the old project and put them into the new project. + $props = array( + 'labels_download_predefined' => IDF_Form_UploadConf::init_predefined, + '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_open' => IDF_Form_IssueTrackingConf::init_open, + 'labels_issue_closed' => IDF_Form_IssueTrackingConf::init_closed, + 'labels_issue_predefined' => IDF_Form_IssueTrackingConf::init_predefined, + 'labels_issue_one_max' => IDF_Form_IssueTrackingConf::init_one_max, + 'webhook_url' => '', + 'downloads_access_rights' => 'all', + 'review_access_rights' => 'all', + 'wiki_access_rights' => 'all', + 'source_access_rights' => 'all', + 'issues_access_rights' => 'all', + 'downloads_notification_email' => '', + 'review_notification_email' => '', + 'wiki_notification_email' => '', + 'source_notification_email' => '', + 'issues_notification_email' => '', + ); + foreach ($props as $prop => $def) { + $conf->setVal($prop, $tmplconf->getVal($prop, $def)); + } + } $project->created(); - IDF_Form_MembersConf::updateMemberships($project, - $this->cleaned_data); + + if ($this->cleaned_data['template'] == '--') { + IDF_Form_MembersConf::updateMemberships($project, + $this->cleaned_data); + } else { + // Get the membership of the template $tmpl + IDF_Form_MembersConf::updateMemberships($project, + $tmpl->getMembershipData('string')); + } $project->membershipsUpdated(); return $project; } + + /** + * Check that the template project exists. + */ + public function clean_template() + { + if ($this->cleaned_data['template'] == '--') { + return $this->cleaned_data['template']; + } + $sql = new Pluf_SQL('shortname=%s', array($this->cleaned_data['template'])); + if (Pluf::factory('IDF_Project')->getOne(array('filter' => $sql->gen())) == null) { + throw new Pluf_Form_Invalid(__('This project is not available.')); + } + return $this->cleaned_data['template']; + } } diff --git a/src/IDF/Views/Admin.php b/src/IDF/Views/Admin.php index b69f851..5e81f9e 100644 --- a/src/IDF/Views/Admin.php +++ b/src/IDF/Views/Admin.php @@ -118,6 +118,9 @@ class IDF_Views_Admin /** * Creation of a project. * + * A project can use another project as template. In that case, + * everything but the data in the input at creation time is + * reused, including the wiki pages. */ public $projectCreate_precond = array('Pluf_Precondition::staffRequired'); public function projectCreate($request, $match) diff --git a/src/IDF/templates/idf/gadmin/projects/create.html b/src/IDF/templates/idf/gadmin/projects/create.html index 0b39ccd..1c1cddf 100644 --- a/src/IDF/templates/idf/gadmin/projects/create.html +++ b/src/IDF/templates/idf/gadmin/projects/create.html @@ -60,21 +60,28 @@ +{$form.f.template.labelTag} +{if $form.f.template.errors}{$form.f.template.fieldErrors}{/if} +{$form.f.template|unsafe}
+{$form.f.template.help_text} + + + {$form.f.owners.labelTag}: {if $form.f.owners.errors}{$form.f.owners.fieldErrors}{/if} {$form.f.owners|unsafe}
-{trans 'Provide at least one owner for the project.'} +{trans 'Provide at least one owner for the project or use a template.'} - + {$form.f.members.labelTag}: {if $form.f.members.errors}{$form.f.members.fieldErrors}{/if} {$form.f.members|unsafe} - + {if $form.f.private_project.errors}{$form.f.private_project.fieldErrors}{/if} {$form.f.private_project|unsafe} @@ -136,18 +143,19 @@ $(document).ready(function() { } }); + // Hide if not svn + if ($("#id_template option:selected").val() == "--") { + $(".no-template").show(); + } else { + $(".no-template").hide(); + } + $("#id_template").change(function () { + if ($("#id_template option:selected").val() == "--") { + $(".no-template").show(); + } else { + $(".no-template").hide(); + } + }); }); {/literal}{/block} -{* - - $("select").change(function () { - var str = ""; - $("select option:selected").each(function () { - str += $(this).text() + " "; - }); - $("div").text(str); - }) - .trigger('change'); - -*}