Merge branch 'develop' into feature.issue-due-date

This commit is contained in:
Simon Holywell
2012-03-22 11:01:34 +00:00
116 changed files with 6952 additions and 1354 deletions

View File

@@ -0,0 +1,47 @@
<?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-2011 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 ***** */
/**
* Configuration of the forge's start page.
*/
class IDF_Form_Admin_ForgeConf extends Pluf_Form
{
public function initFields($extra=array())
{
$this->fields['enabled'] = new Pluf_Form_Field_Boolean(
array('required' => false,
'label' => __('Custom forge page enabled'),
'widget' => 'Pluf_Form_Widget_CheckboxInput',
));
$this->fields['content'] = new Pluf_Form_Field_Varchar(
array('required' => true,
'label' => __('Content'),
'widget' => 'Pluf_Form_Widget_TextareaInput',
'widget_attrs' => array(
'cols' => 68,
'rows' => 26,
),
));
}
}

View File

@@ -0,0 +1,62 @@
<?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-2011 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 ***** */
/**
* Configuration of forge labels.
*/
class IDF_Form_Admin_LabelConf extends Pluf_Form
{
const init_project_labels = 'UI:GUI = Applications with graphical user interfaces
UI:CLI = Applications with no graphical user interfaces
License:BSD = Applications with BSD license
License:GPL = Applications with GPL license
';
public function initFields($extra=array())
{
$this->fields['project_labels'] = new Pluf_Form_Field_Varchar(
array('required' => true,
'label' => __('Predefined project labels'),
'initial' => self::init_project_labels,
'widget_attrs' => array('rows' => 13,
'cols' => 75),
'widget' => 'Pluf_Form_Widget_TextareaInput',
));
}
public function clean_project_labels()
{
$labels = preg_split("/\s*\n\s*/", $this->cleaned_data['project_labels'], -1, PREG_SPLIT_NO_EMPTY);
for ($i=0; $i<count($labels); ++$i) {
$labels[$i] = trim($labels[$i]);
if (!preg_match('/^[\w-]+(:[\w-]+)?(\s*=\s*[^=]+)?$/', $labels[$i])) {
throw new Pluf_Form_Invalid(sprintf(
__('The label "%s" is invalid: A label must only consist of alphanumeric '.
'characters and dashes, and can optionally contain a ":" with a group prefix.'),
$labels[$i]));
}
}
return implode("\n", $labels);
}
}

View File

@@ -72,6 +72,13 @@ class IDF_Form_Admin_ProjectCreate extends Pluf_Form
'widget_attrs' => array('size' => '35'),
));
$this->fields['external_project_url'] = new Pluf_Form_Field_Varchar(
array('required' => false,
'label' => __('External URL'),
'widget_attrs' => array('size' => '35'),
'initial' => '',
));
$this->fields['scm'] = new Pluf_Form_Field_Varchar(
array('required' => true,
'label' => __('Repository type'),
@@ -127,6 +134,18 @@ class IDF_Form_Admin_ProjectCreate extends Pluf_Form
'widget' => 'Pluf_Form_Widget_TextareaInput',
));
for ($i=1;$i<7;$i++) {
$this->fields['label'.$i] = new Pluf_Form_Field_Varchar(
array('required' => false,
'label' => __('Labels'),
'initial' => '',
'widget_attrs' => array(
'maxlength' => 50,
'size' => 20,
),
));
}
$projects = array('--' => '--');
foreach (Pluf::factory('IDF_Project')->getList(array('order' => 'name ASC')) as $proj) {
$projects[$proj->name] = $proj->shortname;
@@ -235,6 +254,11 @@ class IDF_Form_Admin_ProjectCreate extends Pluf_Form
return $shortname;
}
public function clean_external_project_url()
{
return IDF_Form_ProjectConf::checkWebURL($this->cleaned_data['external_project_url']);
}
public function clean()
{
if ($this->cleaned_data['scm'] != 'svn') {
@@ -278,11 +302,29 @@ class IDF_Form_Admin_ProjectCreate extends Pluf_Form
if (!$this->isValid()) {
throw new Exception(__('Cannot save the model from an invalid form.'));
}
// Add a tag for each label
$tagids = array();
for ($i=1;$i<7;$i++) {
if (strlen($this->cleaned_data['label'.$i]) > 0) {
if (strpos($this->cleaned_data['label'.$i], ':') !== false) {
list($class, $name) = explode(':', $this->cleaned_data['label'.$i], 2);
list($class, $name) = array(trim($class), trim($name));
} else {
$class = 'Other';
$name = trim($this->cleaned_data['label'.$i]);
}
$tag = IDF_Tag::addGlobal($name, $class);
$tagids[] = $tag->id;
}
}
$project = new IDF_Project();
$project->name = $this->cleaned_data['name'];
$project->shortname = $this->cleaned_data['shortname'];
$project->shortdesc = $this->cleaned_data['shortdesc'];
$tagids = array();
if ($this->cleaned_data['template'] != '--') {
// Find the template project
$sql = new Pluf_SQL('shortname=%s',
@@ -290,15 +332,36 @@ class IDF_Form_Admin_ProjectCreate extends Pluf_Form
$tmpl = Pluf::factory('IDF_Project')->getOne(array('filter' => $sql->gen()));
$project->private = $tmpl->private;
$project->description = $tmpl->description;
foreach ($tmpl->get_tags_list() as $tag) {
$tagids[] = $tag->id;
}
} else {
$project->private = $this->cleaned_data['private_project'];
$project->description = __('Click on the Project Management tab to set the description of your project.');
// Add a tag for each label
for ($i=1;$i<7;$i++) {
if (strlen($this->cleaned_data['label'.$i]) > 0) {
if (strpos($this->cleaned_data['label'.$i], ':') !== false) {
list($class, $name) = explode(':', $this->cleaned_data['label'.$i], 2);
list($class, $name) = array(trim($class), trim($name));
} else {
$class = 'Other';
$name = trim($this->cleaned_data['label'.$i]);
}
$tag = IDF_Tag::addGlobal($name, $class);
$tagids[] = $tag->id;
}
}
}
$project->create();
$project->batchAssoc('IDF_Tag', $tagids);
$conf = new IDF_Conf();
$conf->setProject($project);
$keys = array('scm', 'svn_remote_url', 'svn_username',
'svn_password', 'mtn_master_branch');
'svn_password', 'mtn_master_branch', 'external_project_url');
foreach ($keys as $key) {
$this->cleaned_data[$key] = (!empty($this->cleaned_data[$key])) ?
$this->cleaned_data[$key] : '';

View File

@@ -53,6 +53,13 @@ class IDF_Form_Admin_ProjectUpdate extends Pluf_Form
'widget_attrs' => array('size' => '35'),
));
$this->fields['external_project_url'] = new Pluf_Form_Field_Varchar(
array('required' => false,
'label' => __('External URL'),
'widget_attrs' => array('size' => '35'),
'initial' => $conf->getVal('external_project_url'),
));
if ($this->project->getConf()->getVal('scm') == 'mtn') {
$this->fields['mtn_master_branch'] = new Pluf_Form_Field_Varchar(
array('required' => false,
@@ -63,6 +70,26 @@ class IDF_Form_Admin_ProjectUpdate extends Pluf_Form
));
}
$tags = $this->project->get_tags_list();
for ($i=1;$i<7;$i++) {
$initial = '';
if (isset($tags[$i-1])) {
if ($tags[$i-1]->class != 'Other') {
$initial = (string) $tags[$i-1];
} else {
$initial = $tags[$i-1]->name;
}
}
$this->fields['label'.$i] = new Pluf_Form_Field_Varchar(
array('required' => false,
'label' => __('Labels'),
'initial' => $initial,
'widget_attrs' => array(
'maxlength' => 50,
'size' => 20,
),
));
}
$this->fields['owners'] = new Pluf_Form_Field_Varchar(
array('required' => false,
'label' => __('Project owners'),
@@ -115,22 +142,52 @@ class IDF_Form_Admin_ProjectUpdate extends Pluf_Form
return IDF_Form_MembersConf::checkBadLogins($this->cleaned_data['members']);
}
public function clean_external_project_url()
{
return IDF_Form_ProjectConf::checkWebURL($this->cleaned_data['external_project_url']);
}
public function save($commit=true)
{
if (!$this->isValid()) {
throw new Exception(__('Cannot save the model from an invalid form.'));
}
// Add a tag for each label
$tagids = array();
for ($i=1;$i<7;$i++) {
if (strlen($this->cleaned_data['label'.$i]) > 0) {
if (strpos($this->cleaned_data['label'.$i], ':') !== false) {
list($class, $name) = explode(':', $this->cleaned_data['label'.$i], 2);
list($class, $name) = array(trim($class), trim($name));
} else {
$class = 'Other';
$name = trim($this->cleaned_data['label'.$i]);
}
$tag = IDF_Tag::addGlobal($name, $class);
$tagids[] = $tag->id;
}
}
$this->project->batchAssoc('IDF_Tag', $tagids);
IDF_Form_MembersConf::updateMemberships($this->project,
$this->cleaned_data);
$this->project->membershipsUpdated();
$this->project->name = $this->cleaned_data['name'];
$this->project->shortdesc = $this->cleaned_data['shortdesc'];
$this->project->update();
$keys = array('mtn_master_branch');
$conf = $this->project->getConf();
$keys = array('mtn_master_branch', 'external_project_url');
foreach ($keys as $key) {
if (!empty($this->cleaned_data[$key])) {
$this->project->getConf()->setVal($key, $this->cleaned_data[$key]);
if (array_key_exists($key, $this->cleaned_data)) {
if (!empty($this->cleaned_data[$key])) {
$conf->setVal($key, $this->cleaned_data[$key]);
}
else {
$conf->delVal($key);
}
}
}
}

View File

@@ -32,6 +32,7 @@ class IDF_Form_ProjectConf extends Pluf_Form
public function initFields($extra=array())
{
$this->project = $extra['project'];
$conf = $this->project->getConf();
// Basic part
$this->fields['name'] = new Pluf_Form_Field_Varchar(array('required' => true,
@@ -51,6 +52,32 @@ class IDF_Form_ProjectConf extends Pluf_Form
),
'widget' => 'Pluf_Form_Widget_TextareaInput',
));
$this->fields['external_project_url'] = new Pluf_Form_Field_Varchar(array('required' => false,
'label' => __('External URL'),
'widget_attrs' => array('size' => '68'),
'initial' => $conf->getVal('external_project_url'),
));
$tags = $this->project->get_tags_list();
for ($i=1;$i<7;$i++) {
$initial = '';
if (isset($tags[$i-1])) {
if ($tags[$i-1]->class != 'Other') {
$initial = (string) $tags[$i-1];
} else {
$initial = $tags[$i-1]->name;
}
}
$this->fields['label'.$i] = new Pluf_Form_Field_Varchar(
array('required' => false,
'label' => __('Labels'),
'initial' => $initial,
'widget_attrs' => array(
'maxlength' => 50,
'size' => 20,
),
));
}
// Logo part
$upload_path = Pluf::f('upload_path', false);
@@ -119,20 +146,63 @@ class IDF_Form_ProjectConf extends Pluf_Form
return $this->cleaned_data['logo'];
}
public function clean_external_project_url()
{
return self::checkWebURL($this->cleaned_data['external_project_url']);
}
public static function checkWebURL($url)
{
$url = trim($url);
if (empty($url)) {
return '';
}
$parsed = parse_url($url);
if ($parsed === false || !array_key_exists('scheme', $parsed) ||
($parsed['scheme'] != 'http' && $parsed['scheme'] != 'https')) {
throw new Pluf_Form_Invalid(__('The entered URL is invalid. Only http and https URLs are allowed.'));
}
return $url;
}
public function save($commit=true)
{
$conf = $this->project->getConf();
// Add a tag for each label
$tagids = array();
for ($i=1;$i<7;$i++) {
if (strlen($this->cleaned_data['label'.$i]) > 0) {
if (strpos($this->cleaned_data['label'.$i], ':') !== false) {
list($class, $name) = explode(':', $this->cleaned_data['label'.$i], 2);
list($class, $name) = array(trim($class), trim($name));
} else {
$class = 'Other';
$name = trim($this->cleaned_data['label'.$i]);
}
$tag = IDF_Tag::addGlobal($name, $class);
$tagids[] = $tag->id;
}
}
// Basic part
$this->project->name = $this->cleaned_data['name'];
$this->project->shortdesc = $this->cleaned_data['shortdesc'];
$this->project->description = $this->cleaned_data['description'];
$this->project->batchAssoc('IDF_Tag', $tagids);
$this->project->update();
// Logo part
if ($this->cleaned_data['logo'] !== "") {
$conf = $this->project->getConf();
if (!empty($this->cleaned_data['logo'])) {
$conf->setVal('logo', $this->cleaned_data['logo']);
}
if (!empty($this->cleaned_data['external_project_url'])) {
$conf->setVal('external_project_url', $this->cleaned_data['external_project_url']);
}
else {
$conf->delVal('external_project_url');
}
if ($this->cleaned_data['logo_remove'] === true) {
@unlink(Pluf::f('upload_path') . '/' . $this->project->shortname . $conf->getVal('logo'));
$conf->delVal('logo');

View File

@@ -49,13 +49,10 @@ class IDF_Form_SourceConf extends Pluf_Form
'widget' => 'Pluf_Form_Widget_PasswordInput',
));
}
Pluf::loadFunction('Pluf_HTTP_URL_urlForView');
$url = Pluf_HTTP_URL_urlForView('idf_faq').'#webhooks';
$this->fields['webhook_url'] = new Pluf_Form_Field_Url(
array('required' => false,
'label' => __('Webhook URL'),
'initial' => $this->conf->getVal('webhook_url', ''),
'help_text' => sprintf(__('Learn more about the <a href="%s">post-commit webhooks</a>.'), $url),
'widget_attrs' => array('size' => 35),
));

View File

@@ -57,20 +57,44 @@ class IDF_Form_TabsConf extends Pluf_Form
'widget' => 'Pluf_Form_Widget_SelectInput',
));
}
$ak = array('downloads_notification_email',
'review_notification_email',
'wiki_notification_email',
'source_notification_email',
'issues_notification_email',);
foreach ($ak as $key) {
$this->fields[$key] = new IDF_Form_Field_EmailList(
array('required' => false,
'label' => $key,
'initial' => $this->conf->getVal($key, ''),
'widget_attrs' => array('size' => 40),
));
}
$sections = array(
'downloads_notification',
'review_notification',
'wiki_notification',
'source_notification',
'issues_notification',
);
foreach ($sections as $section) {
$this->fields[$section.'_owners_enabled'] = new Pluf_Form_Field_Boolean(
array('required' => false,
'label' => __('Project owners'),
'initial' => $this->conf->getVal($section.'_owners_enabled', false),
'widget' => 'Pluf_Form_Widget_CheckboxInput',
));
$this->fields[$section.'_members_enabled'] = new Pluf_Form_Field_Boolean(
array('required' => false,
'label' => __('Project members'),
'initial' => $this->conf->getVal($section.'_members_enabled', false),
'widget' => 'Pluf_Form_Widget_CheckboxInput',
));
$this->fields[$section.'_email_enabled'] = new Pluf_Form_Field_Boolean(
array('required' => false,
'label' => __('Others'),
'initial' => $this->conf->getVal($section.'_email_enabled', false),
'widget' => 'Pluf_Form_Widget_CheckboxInput',
));
if ($this->conf->getVal($section.'_email_enabled', false)) {
$attrs['readonly'] = 'readonly';
}
$this->fields[$section.'_email'] = new IDF_Form_Field_EmailList(
array('required' => false,
'label' => null,
'initial' => $this->conf->getVal($section.'_email', ''),
'widget_attrs' => array('size' => 20),
));
}
$this->fields['private_project'] = new Pluf_Form_Field_Boolean(
array('required' => false,

View File

@@ -96,7 +96,7 @@ class IDF_Form_UpdateUpload extends Pluf_Form
$this->cleaned_data['label'.$i] = trim($this->cleaned_data['label'.$i]);
if (strpos($this->cleaned_data['label'.$i], ':') !== false) {
list($class, $name) = explode(':', $this->cleaned_data['label'.$i], 2);
list($class, $name) = array(mb_strtolower(trim($class)),
list($class, $name) = array(mb_strtolower(trim($class)),
trim($name));
} else {
$class = 'other';
@@ -146,6 +146,9 @@ class IDF_Form_UpdateUpload extends Pluf_Form
$this->upload->modif_dtime = gmdate('Y-m-d H:i:s');
$this->upload->update();
$this->upload->batchAssoc('IDF_Tag', $tags);
// Send the notification
$this->upload->notify($this->project->getConf(), false);
/**
* [signal]
*
@@ -166,7 +169,7 @@ class IDF_Form_UpdateUpload extends Pluf_Form
*
*/
$params = array('upload' => $this->upload);
Pluf_Signal::send('IDF_Upload::update',
Pluf_Signal::send('IDF_Upload::update',
'IDF_Form_UpdateUpload', $params);
return $this->upload;
}

View File

@@ -79,6 +79,7 @@ class IDF_Form_Upload extends Pluf_Form
public function clean_file()
{
// FIXME: we do the same in IDF_Form_WikiResourceCreate and a couple of other places as well
$extra = strtolower(implode('|', explode(' ', Pluf::f('idf_extra_upload_ext'))));
if (strlen($extra)) $extra .= '|';
if (!preg_match('/\.('.$extra.'png|jpg|jpeg|gif|bmp|psd|tif|aiff|asf|avi|bz2|css|doc|eps|gz|jar|mdtext|mid|mov|mp3|mpg|ogg|pdf|ppt|ps|qt|ra|ram|rm|rtf|sdd|sdw|sit|sxi|sxw|swf|tgz|txt|wav|xls|xml|war|wmv|zip)$/i', $this->cleaned_data['file'])) {
@@ -106,7 +107,7 @@ class IDF_Form_Upload extends Pluf_Form
$this->cleaned_data['label'.$i] = trim($this->cleaned_data['label'.$i]);
if (strpos($this->cleaned_data['label'.$i], ':') !== false) {
list($class, $name) = explode(':', $this->cleaned_data['label'.$i], 2);
list($class, $name) = array(mb_strtolower(trim($class)),
list($class, $name) = array(mb_strtolower(trim($class)),
trim($name));
} else {
$class = 'other';
@@ -116,7 +117,7 @@ class IDF_Form_Upload extends Pluf_Form
else $count[$class] += 1;
if (in_array($class, $onemax) and $count[$class] > 1) {
if (!isset($this->errors['label'.$i])) $this->errors['label'.$i] = array();
$this->errors['label'.$i][] = sprintf(__('You cannot provide more than one label from the %s class to an issue.'), $class);
$this->errors['label'.$i][] = sprintf(__('You cannot provide more than one label from the %s class to a download.'), $class);
throw new Pluf_Form_Invalid(__('You provided an invalid label.'));
}
}
@@ -129,7 +130,7 @@ class IDF_Form_Upload extends Pluf_Form
*/
function failed()
{
if (!empty($this->cleaned_data['file'])
if (!empty($this->cleaned_data['file'])
and file_exists(Pluf::f('upload_path').'/'.$this->project->shortname.'/files/'.$this->cleaned_data['file'])) {
@unlink(Pluf::f('upload_path').'/'.$this->project->shortname.'/files/'.$this->cleaned_data['file']);
}

View File

@@ -0,0 +1,227 @@
<?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-2011 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 ***** */
/**
* Upload and process an archive file.
*
*/
class IDF_Form_UploadArchive extends Pluf_Form
{
public $user = null;
public $project = null;
private $archiveHelper = null;
public function initFields($extra=array())
{
$this->user = $extra['user'];
$this->project = $extra['project'];
$this->fields['archive'] = new Pluf_Form_Field_File(
array('required' => true,
'label' => __('Archive file'),
'initial' => '',
'max_size' => Pluf::f('max_upload_archive_size', 20971520),
'move_function_params' => array(
'upload_path' => Pluf::f('upload_path').'/'.$this->project->shortname.'/archives',
'upload_path_create' => true,
'upload_overwrite' => true,
)));
}
public function clean_archive()
{
$this->archiveHelper = new IDF_Form_UploadArchiveHelper(
Pluf::f('upload_path').'/'.$this->project->shortname.'/archives/'.$this->cleaned_data['archive']);
// basic archive validation
$this->archiveHelper->validate();
// extension validation
$fileNames = $this->archiveHelper->getEntryNames();
foreach ($fileNames as $fileName) {
$extra = strtolower(implode('|', explode(' ', Pluf::f('idf_extra_upload_ext'))));
if (strlen($extra)) $extra .= '|';
if (!preg_match('/\.('.$extra.'png|jpg|jpeg|gif|bmp|psd|tif|aiff|asf|avi|bz2|css|doc|eps|gz|jar|mdtext|mid|mov|mp3|mpg|ogg|pdf|ppt|ps|qt|ra|ram|rm|rtf|sdd|sdw|sit|sxi|sxw|swf|tgz|txt|wav|xls|xml|war|wmv|zip)$/i', $fileName)) {
@unlink(Pluf::f('upload_path').'/'.$this->project->shortname.'/files/'.$this->cleaned_data['archive']);
throw new Pluf_Form_Invalid(sprintf(__('For security reasons, you cannot upload a file (%s) with this extension.'), $fileName));
}
}
// label and file name validation
$conf = new IDF_Conf();
$conf->setProject($this->project);
$onemax = array();
foreach (explode(',', $conf->getVal('labels_download_one_max', IDF_Form_UploadConf::init_one_max)) as $class) {
if (trim($class) != '') {
$onemax[] = mb_strtolower(trim($class));
}
}
foreach ($fileNames as $fileName) {
$meta = $this->archiveHelper->getMetaData($fileName);
$count = array();
foreach ($meta['labels'] as $label) {
$label = trim($label);
if (strpos($label, ':') !== false) {
list($class, $name) = explode(':', $label, 2);
list($class, $name) = array(mb_strtolower(trim($class)),
trim($name));
} else {
$class = 'other';
$name = $label;
}
if (!isset($count[$class])) $count[$class] = 1;
else $count[$class] += 1;
if (in_array($class, $onemax) and $count[$class] > 1) {
throw new Pluf_Form_Invalid(
sprintf(__('You cannot provide more than label from the %1$s class to a download (%2$s).'), $class, $name)
);
}
}
$sql = new Pluf_SQL('file=%s AND project=%s', array($fileName, $this->project->id));
$upload = Pluf::factory('IDF_Upload')->getOne(array('filter' => $sql->gen()));
$meta = $this->archiveHelper->getMetaData($fileName);
if ($upload != null && $meta['replaces'] !== $fileName) {
throw new Pluf_Form_Invalid(
sprintf(__('A file with the name "%s" has already been uploaded and is not marked to be replaced.'), $fileName));
}
}
return $this->cleaned_data['archive'];
}
/**
* If we have uploaded a file, but the form failed remove it.
*
*/
function failed()
{
if (!empty($this->cleaned_data['archive'])
and file_exists(Pluf::f('upload_path').'/'.$this->project->shortname.'/archives/'.$this->cleaned_data['archive'])) {
@unlink(Pluf::f('upload_path').'/'.$this->project->shortname.'/archives/'.$this->cleaned_data['archive']);
}
}
/**
* Save the model in the database.
*
* @param bool Commit in the database or not. If not, the object
* is returned but not saved in the database.
*/
function save($commit=true)
{
if (!$this->isValid()) {
throw new Exception(__('Cannot save the model from an invalid form.'));
}
$uploadDir = Pluf::f('upload_path').'/'.$this->project->shortname.'/files/';
$fileNames = $this->archiveHelper->getEntryNames();
foreach ($fileNames as $fileName) {
$meta = $this->archiveHelper->getMetaData($fileName);
// add a tag for each label
$tags = array();
foreach ($meta['labels'] as $label) {
$label = trim($label);
if (strlen($label) > 0) {
if (strpos($label, ':') !== false) {
list($class, $name) = explode(':', $label, 2);
list($class, $name) = array(trim($class), trim($name));
} else {
$class = 'Other';
$name = $label;
}
$tags[] = IDF_Tag::add($name, $this->project, $class);
}
}
// process a possible replacement
if (!empty($meta['replaces'])) {
$sql = new Pluf_SQL('file=%s AND project=%s', array($meta['replaces'], $this->project->id));
$oldUpload = Pluf::factory('IDF_Upload')->getOne(array('filter' => $sql->gen()));
if ($oldUpload) {
if ($meta['replaces'] === $fileName) {
$oldUpload->delete();
} else {
$tags = $this->project->getTagsFromConfig('labels_download_predefined',
IDF_Form_UploadConf::init_predefined);
// the deprecate tag is - by definition - always the last one
$deprecatedTag = array_pop($tags);
$oldUpload->setAssoc($deprecatedTag);
}
}
}
// extract the file
$this->archiveHelper->extract($fileName, $uploadDir);
// create the upload
$upload = new IDF_Upload();
$upload->project = $this->project;
$upload->submitter = $this->user;
$upload->summary = trim($meta['summary']);
$upload->changelog = trim($meta['description']);
$upload->file = $fileName;
$upload->filesize = filesize($uploadDir.$fileName);
$upload->downloads = 0;
$upload->create();
foreach ($tags as $tag) {
$upload->setAssoc($tag);
}
// send the notification
$upload->notify($this->project->getConf());
/**
* [signal]
*
* IDF_Upload::create
*
* [sender]
*
* IDF_Form_Upload
*
* [description]
*
* This signal allows an application to perform a set of tasks
* just after the upload of a file and after the notification run.
*
* [parameters]
*
* array('upload' => $upload);
*
*/
$params = array('upload' => $upload);
Pluf_Signal::send('IDF_Upload::create', 'IDF_Form_Upload',
$params);
}
// finally unlink the uploaded archive
@unlink(Pluf::f('upload_path').'/'.$this->project->shortname.'/archives/'.$this->cleaned_data['archive']);
}
}

View File

@@ -0,0 +1,158 @@
<?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-2011 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 ***** */
class IDF_Form_UploadArchiveHelper
{
private $file = null;
private $entries = array();
public function __construct($file)
{
$this->file = $file;
}
/**
* Validates the archive; throws a invalid form exception in case the
* archive contains invalid data or cannot be read.
*/
public function validate()
{
if (!file_exists($this->file)) {
throw new Pluf_Form_Invalid(__('The archive does not exist.'));
}
$za = new ZipArchive();
$res = $za->open($this->file);
if ($res !== true) {
throw new Pluf_Form_Invalid(
sprintf(__('The archive could not be read (code %d).'), $res));
}
$manifest = $za->getFromName('manifest.xml');
if ($manifest === false) {
throw new Pluf_Form_Invalid(__('The archive does not contain a manifest.xml.'));
}
libxml_use_internal_errors(true);
$xml = @simplexml_load_string($manifest);
if ($xml === false) {
$error = libxml_get_last_error();
throw new Pluf_Form_Invalid(
sprintf(__('The archive\'s manifest is invalid: %s'), $error->message));
}
foreach (@$xml->file as $idx => $file)
{
$entry = array(
'name' => (string)@$file->name,
'summary' => (string)@$file->summary,
'description' => (string)@$file->description,
'replaces' => (string)@$file->replaces,
'labels' => array(),
'stream' => null
);
if (empty($entry['name'])) {
throw new Pluf_Form_Invalid(
sprintf(__('The entry %d in the manifest is missing a file name.'), $idx));
}
if (empty($entry['summary'])) {
throw new Pluf_Form_Invalid(
sprintf(__('The entry %d in the manifest is missing a summary.'), $idx));
}
if ($entry['name'] === 'manifest.xml') {
throw new Pluf_Form_Invalid(__('The manifest must not reference itself.'));
}
if ($za->locateName($entry['name']) === false) {
throw new Pluf_Form_Invalid(
sprintf(__('The entry %s in the manifest does not exist in the archive.'), $entry['name']));
}
if (in_array($entry['name'], $this->entries)) {
throw new Pluf_Form_Invalid(
sprintf(__('The entry %s in the manifest is referenced more than once.'), $entry['name']));
}
if ($file->labels) {
foreach (@$file->labels->label as $label) {
$entry['labels'][] = (string)$label;
}
}
// FIXME: remove this once we allow more than six labels everywhere
if (count($entry['labels']) > 6) {
throw new Pluf_Form_Invalid(
sprintf(__('The entry %s in the manifest has more than the six allowed labels set.'), $entry['name']));
}
$this->entries[$entry['name']] = $entry;
}
$za->close();
}
/**
* Returns all entry names
*
* @return array of string
*/
public function getEntryNames()
{
return array_keys($this->entries);
}
/**
* Returns meta data for the given entry
*
* @param string $name
* @throws Exception
*/
public function getMetaData($name)
{
if (!array_key_exists($name, $this->entries)) {
throw new Exception('unknown file ' . $name);
}
return $this->entries[$name];
}
/**
* Extracts the file entry $name at $path
*
* @param string $name
* @param string $path
* @throws Exception
*/
public function extract($name, $path)
{
if (!array_key_exists($name, $this->entries)) {
throw new Exception('unknown file ' . $name);
}
$za = new ZipArchive();
$za->open($this->file);
$za->extractTo($path, $name);
$za->close();
}
}

View File

@@ -60,10 +60,18 @@ Deprecated = Most users should NOT download this';
$this->fields['labels_download_one_max'] = new Pluf_Form_Field_Varchar(
array('required' => false,
'label' => __('Each download may have at most one label with each of these classes'),
'initial' => self::init_one_max,
'initial' => self::init_one_max,
'widget_attrs' => array('size' => 60),
));
$this->conf = $extra['conf'];
$this->fields['upload_webhook_url'] = new Pluf_Form_Field_Url(
array('required' => false,
'label' => __('Webhook URL'),
'initial' => $this->conf->getVal('upload_webhook_url', ''),
'widget_attrs' => array('size' => 60),
));
}
}

View File

@@ -27,7 +27,7 @@
* This create a new page and the corresponding revision.
*
*/
class IDF_Form_WikiCreate extends Pluf_Form
class IDF_Form_WikiPageCreate extends Pluf_Form
{
public $user = null;
public $project = null;
@@ -107,9 +107,9 @@ Add your content here. Format your content with:
if (preg_match('/[^a-zA-Z0-9\-]/', $title)) {
throw new Pluf_Form_Invalid(__('The title contains invalid characters.'));
}
$sql = new Pluf_SQL('project=%s AND title=%s',
$sql = new Pluf_SQL('project=%s AND title=%s',
array($this->project->id, $title));
$pages = Pluf::factory('IDF_WikiPage')->getList(array('filter'=>$sql->gen()));
$pages = Pluf::factory('IDF_Wiki_Page')->getList(array('filter'=>$sql->gen()));
if ($pages->count() > 0) {
throw new Pluf_Form_Invalid(__('A page with this title already exists.'));
}
@@ -137,7 +137,7 @@ Add your content here. Format your content with:
$this->cleaned_data['label'.$i] = trim($this->cleaned_data['label'.$i]);
if (strpos($this->cleaned_data['label'.$i], ':') !== false) {
list($class, $name) = explode(':', $this->cleaned_data['label'.$i], 2);
list($class, $name) = array(mb_strtolower(trim($class)),
list($class, $name) = array(mb_strtolower(trim($class)),
trim($name));
} else {
$class = 'other';
@@ -181,9 +181,9 @@ Add your content here. Format your content with:
$tags[] = IDF_Tag::add($name, $this->project, $class);
}
}
}
}
// Create the page
$page = new IDF_WikiPage();
$page = new IDF_Wiki_Page();
$page->project = $this->project;
$page->submitter = $this->user;
$page->summary = trim($this->cleaned_data['summary']);
@@ -193,7 +193,7 @@ Add your content here. Format your content with:
$page->setAssoc($tag);
}
// add the first revision
$rev = new IDF_WikiRevision();
$rev = new IDF_Wiki_PageRevision();
$rev->wikipage = $page;
$rev->content = $this->cleaned_data['content'];
$rev->submitter = $this->user;

View File

@@ -27,7 +27,7 @@
* This is a hard delete of the page and the revisions.
*
*/
class IDF_Form_WikiDelete extends Pluf_Form
class IDF_Form_WikiPageDelete extends Pluf_Form
{
protected $page = null;

View File

@@ -27,13 +27,13 @@
* This add a corresponding revision.
*
*/
class IDF_Form_WikiUpdate extends Pluf_Form
class IDF_Form_WikiPageUpdate extends Pluf_Form
{
public $user = null;
public $project = null;
public $page = null;
public $show_full = false;
public function initFields($extra=array())
{
@@ -118,9 +118,9 @@ class IDF_Form_WikiUpdate extends Pluf_Form
if (preg_match('/[^a-zA-Z0-9\-]/', $title)) {
throw new Pluf_Form_Invalid(__('The title contains invalid characters.'));
}
$sql = new Pluf_SQL('project=%s AND title=%s',
$sql = new Pluf_SQL('project=%s AND title=%s',
array($this->project->id, $title));
$pages = Pluf::factory('IDF_WikiPage')->getList(array('filter'=>$sql->gen()));
$pages = Pluf::factory('IDF_Wiki_Page')->getList(array('filter'=>$sql->gen()));
if ($pages->count() > 0 and $pages[0]->id != $this->page->id) {
throw new Pluf_Form_Invalid(__('A page with this title already exists.'));
}
@@ -148,7 +148,7 @@ class IDF_Form_WikiUpdate extends Pluf_Form
$this->cleaned_data['label'.$i] = trim($this->cleaned_data['label'.$i]);
if (strpos($this->cleaned_data['label'.$i], ':') !== false) {
list($class, $name) = explode(':', $this->cleaned_data['label'.$i], 2);
list($class, $name) = array(mb_strtolower(trim($class)),
list($class, $name) = array(mb_strtolower(trim($class)),
trim($name));
} else {
$class = 'other';
@@ -229,7 +229,7 @@ class IDF_Form_WikiUpdate extends Pluf_Form
}
$this->page->update();
// add the new revision
$rev = new IDF_WikiRevision();
$rev = new IDF_Wiki_PageRevision();
$rev->wikipage = $this->page;
$rev->content = $this->cleaned_data['content'];
$rev->submitter = $this->user;

View File

@@ -0,0 +1,169 @@
<?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-2011 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 ***** */
/**
* Create a new resource.
*
* This create a new resource and the corresponding revision.
*
*/
class IDF_Form_WikiResourceCreate extends Pluf_Form
{
public $user = null;
public $project = null;
public $show_full = false;
public function initFields($extra=array())
{
$this->project = $extra['project'];
$this->user = $extra['user'];
$initname = (!empty($extra['name'])) ? $extra['name'] : __('ResourceName');
$this->fields['title'] = new Pluf_Form_Field_Varchar(
array('required' => true,
'label' => __('Resource title'),
'initial' => $initname,
'widget_attrs' => array(
'maxlength' => 200,
'size' => 67,
),
'help_text' => __('The resource name must contains only letters, digits and the dash (-) character.'),
));
$this->fields['summary'] = new Pluf_Form_Field_Varchar(
array('required' => true,
'label' => __('Description'),
'help_text' => __('This one line description is displayed in the list of resources.'),
'initial' => '',
'widget_attrs' => array(
'maxlength' => 200,
'size' => 67,
),
));
$this->fields['file'] = new Pluf_Form_Field_File(
array('required' => true,
'label' => __('File'),
'initial' => '',
'max_size' => Pluf::f('max_upload_size', 2097152),
'move_function_params' => array('upload_path' => $this->getTempUploadPath(),
'upload_path_create' => true,
'upload_overwrite' => true),
));
}
public function clean_title()
{
$title = $this->cleaned_data['title'];
if (preg_match('/[^a-zA-Z0-9\-]/', $title)) {
throw new Pluf_Form_Invalid(__('The title contains invalid characters.'));
}
$sql = new Pluf_SQL('project=%s AND title=%s',
array($this->project->id, $title));
$resources = Pluf::factory('IDF_Wiki_Resource')->getList(array('filter'=>$sql->gen()));
if ($resources->count() > 0) {
throw new Pluf_Form_Invalid(__('A resource with this title already exists.'));
}
return $title;
}
public function clean_file()
{
// FIXME: we do the same in IDF_Form_Upload and a couple of other places as well
$extra = strtolower(implode('|', explode(' ', Pluf::f('idf_extra_upload_ext'))));
if (strlen($extra)) $extra .= '|';
if (!preg_match('/\.('.$extra.'png|jpg|jpeg|gif|bmp|psd|tif|aiff|asf|avi|bz2|css|doc|eps|gz|jar|mdtext|mid|mov|mp3|mpg|ogg|pdf|ppt|ps|qt|ra|ram|rm|rtf|sdd|sdw|sit|sxi|sxw|swf|tgz|txt|wav|xls|xml|war|wmv|zip)$/i', $this->cleaned_data['file'])) {
@unlink($this->getTempUploadPath().$this->cleaned_data['file']);
throw new Pluf_Form_Invalid(__('For security reasons, you cannot upload a file with this extension.'));
}
return $this->cleaned_data['file'];
}
/**
* If we have uploaded a file, but the form failed remove it.
*
*/
function failed()
{
if (!empty($this->cleaned_data['file'])
and file_exists($this->getTempUploadPath().$this->cleaned_data['file'])) {
@unlink($this->getTempUploadPath().$this->cleaned_data['file']);
}
}
/**
* Save the model in the database.
*
* @param bool Commit in the database or not. If not, the object
* is returned but not saved in the database.
* @return Object Model with data set from the form.
*/
function save($commit=true)
{
if (!$this->isValid()) {
throw new Exception(__('Cannot save the model from an invalid form.'));
}
$tempFile = $this->getTempUploadPath().$this->cleaned_data['file'];
list($mimeType, , $extension) = IDF_FileUtil::getMimeType($tempFile);
// create the resource
$resource = new IDF_Wiki_Resource();
$resource->project = $this->project;
$resource->submitter = $this->user;
$resource->summary = trim($this->cleaned_data['summary']);
$resource->title = trim($this->cleaned_data['title']);
$resource->mime_type = $mimeType;
$resource->create();
// add the first revision
$rev = new IDF_Wiki_ResourceRevision();
$rev->wikiresource = $resource;
$rev->submitter = $this->user;
$rev->summary = __('Initial resource creation');
$rev->filesize = filesize($tempFile);
$rev->fileext = $extension;
$rev->create();
$finalFile = $rev->getFilePath();
if (!@mkdir(dirname($finalFile), 0755, true)) {
@unlink($tempFile);
$rev->delete();
$resource->delete();
throw new Exception('could not create final resource path');
}
if (!@rename($tempFile, $finalFile)) {
@unlink($tempFile);
$rev->delete();
$resource->delete();
throw new Exception('could not move resource to final location');
}
return $resource;
}
private function getTempUploadPath()
{
return Pluf::f('upload_path').'/'.$this->project->shortname.'/wiki/temp/';
}
}

View File

@@ -0,0 +1,64 @@
<?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-2011 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 ***** */
/**
* Delete a documentation page.
*
* This is a hard delete of the page and the revisions.
*
*/
class IDF_Form_WikiResourceDelete extends Pluf_Form
{
protected $resource = null;
public function initFields($extra=array())
{
$this->resource = $extra['resource'];
$this->fields['confirm'] = new Pluf_Form_Field_Boolean(
array('required' => true,
'label' => __('Yes, I understand that the resource and all its revisions will be deleted.'),
'initial' => '',
));
}
/**
* Check the confirmation.
*/
public function clean_confirm()
{
if (!$this->cleaned_data['confirm']) {
throw new Pluf_Form_Invalid(__('You need to confirm the deletion.'));
}
return $this->cleaned_data['confirm'];
}
function save($commit=true)
{
if (!$this->isValid()) {
throw new Exception(__('Cannot save the model from an invalid form.'));
}
$this->resource->delete();
return true;
}
}

View File

@@ -0,0 +1,161 @@
<?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-2011 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 ***** */
/**
* Update a documentation page.
*
* This add a corresponding revision.
*
*/
class IDF_Form_WikiResourceUpdate extends Pluf_Form
{
public $user = null;
public $project = null;
public $page = null;
public $show_full = false;
public function initFields($extra=array())
{
$this->resource = $extra['resource'];
$this->user = $extra['user'];
$this->project = $extra['project'];
$this->fields['summary'] = new Pluf_Form_Field_Varchar(
array('required' => true,
'label' => __('Description'),
'help_text' => __('This one line description is displayed in the list of resources.'),
'initial' => $this->resource->summary,
'widget_attrs' => array(
'maxlength' => 200,
'size' => 67,
),
));
$this->fields['file'] = new Pluf_Form_Field_File(
array('required' => true,
'label' => __('File'),
'initial' => '',
'max_size' => Pluf::f('max_upload_size', 2097152),
'move_function_params' => array('upload_path' => $this->getTempUploadPath(),
'upload_path_create' => true,
'upload_overwrite' => true),
));
$this->fields['comment'] = new Pluf_Form_Field_Varchar(
array('required' => true,
'label' => __('Comment'),
'help_text' => __('One line to describe the changes you made.'),
'initial' => '',
'widget_attrs' => array(
'maxlength' => 200,
'size' => 67,
),
));
}
public function clean_file()
{
// FIXME: we do the same in IDF_Form_Upload and a couple of other places as well
$extra = strtolower(implode('|', explode(' ', Pluf::f('idf_extra_upload_ext'))));
if (strlen($extra)) $extra .= '|';
if (!preg_match('/\.('.$extra.'png|jpg|jpeg|gif|bmp|psd|tif|aiff|asf|avi|bz2|css|doc|eps|gz|jar|mdtext|mid|mov|mp3|mpg|ogg|pdf|ppt|ps|qt|ra|ram|rm|rtf|sdd|sdw|sit|sxi|sxw|swf|tgz|txt|wav|xls|xml|war|wmv|zip)$/i', $this->cleaned_data['file'])) {
@unlink($this->getTempUploadPath().$this->cleaned_data['file']);
throw new Pluf_Form_Invalid(__('For security reasons, you cannot upload a file with this extension.'));
}
list($mimeType, , $extension) = IDF_FileUtil::getMimeType($this->getTempUploadPath().$this->cleaned_data['file']);
if ($this->resource->mime_type != $mimeType) {
throw new Pluf_Form_Invalid(sprintf(
__('The mime type of the uploaded file "%1$s" does not match the mime type of this resource "%2$s"'),
$mimeType, $this->resource->mime_type
));
}
$this->cleaned_data['fileext'] = $extension;
if (md5_file($this->getTempUploadPath().$this->cleaned_data['file']) ===
md5_file($this->resource->get_current_revision()->getFilePath())) {
throw new Pluf_Form_Invalid(__('The current version of the resource and the uploaded file are equal.'));
}
return $this->cleaned_data['file'];
}
/**
* If we have uploaded a file, but the form failed remove it.
*
*/
function failed()
{
if (!empty($this->cleaned_data['file'])
and file_exists($this->getTempUploadPath().$this->cleaned_data['file'])) {
@unlink($this->getTempUploadPath().$this->cleaned_data['file']);
}
}
/**
* Save the model in the database.
*
* @param bool Commit in the database or not. If not, the object
* is returned but not saved in the database.
* @return Object Model with data set from the form.
*/
function save($commit=true)
{
if (!$this->isValid()) {
throw new Exception(__('Cannot save the model from an invalid form.'));
}
$tempFile = $this->getTempUploadPath().$this->cleaned_data['file'];
$this->resource->summary = trim($this->cleaned_data['summary']);
$this->resource->update();
// add the new revision
$rev = new IDF_Wiki_ResourceRevision();
$rev->wikiresource = $this->resource;
$rev->submitter = $this->user;
$rev->summary = $this->cleaned_data['comment'];
$rev->filesize = filesize($tempFile);
$rev->fileext = $this->cleaned_data['fileext'];
$rev->create();
$finalFile = $rev->getFilePath();
if (!is_dir(dirname($finalFile))) {
@unlink($tempFile);
$rev->delete();
throw new Exception('resource path does not exist');
}
if (!@rename($tempFile, $finalFile)) {
@unlink($tempFile);
$rev->delete();
throw new Exception('could not move resource to final location');
}
return $this->resource;
}
private function getTempUploadPath()
{
return Pluf::f('upload_path').'/'.$this->project->shortname.'/wiki/temp/';
}
}