diff --git a/src/IDF/Form/Upload.php b/src/IDF/Form/Upload.php index 02c7019..8cde96c 100644 --- a/src/IDF/Form/Upload.php +++ b/src/IDF/Form/Upload.php @@ -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'])) { diff --git a/src/IDF/Form/WikiCreate.php b/src/IDF/Form/WikiCreate.php deleted file mode 100644 index 9c06c75..0000000 --- a/src/IDF/Form/WikiCreate.php +++ /dev/null @@ -1,205 +0,0 @@ -user = $extra['user']; - $this->project = $extra['project']; - if ($this->user->hasPerm('IDF.project-owner', $this->project) - or $this->user->hasPerm('IDF.project-member', $this->project)) { - $this->show_full = true; - } - $initname = (!empty($extra['name'])) ? $extra['name'] : __('PageName'); - $this->fields['title'] = new Pluf_Form_Field_Varchar( - array('required' => true, - 'label' => __('Page title'), - 'initial' => $initname, - 'widget_attrs' => array( - 'maxlength' => 200, - 'size' => 67, - ), - 'help_text' => __('The page 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 pages.'), - 'initial' => '', - 'widget_attrs' => array( - 'maxlength' => 200, - 'size' => 67, - ), - )); - $this->fields['content'] = new Pluf_Form_Field_Varchar( - array('required' => true, - 'label' => __('Content'), - 'initial' => $initial, - 'widget' => 'Pluf_Form_Widget_TextareaInput', - 'widget_attrs' => array( - 'cols' => 68, - 'rows' => 26, - ), - )); - - if ($this->show_full) { - for ($i=1;$i<4;$i++) { - $this->fields['label'.$i] = new Pluf_Form_Field_Varchar( - array('required' => false, - 'label' => __('Labels'), - 'initial' => '', - 'widget_attrs' => array( - 'maxlength' => 50, - 'size' => 20, - ), - )); - } - } - } - - 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)); - $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.')); - } - return $title; - } - - /** - * Validate the interconnection in the form. - */ - public function clean() - { - if (!$this->show_full) { - return $this->cleaned_data; - } - $conf = new IDF_Conf(); - $conf->setProject($this->project); - $onemax = array(); - foreach (explode(',', $conf->getVal('labels_wiki_one_max', IDF_Form_WikiConf::init_one_max)) as $class) { - if (trim($class) != '') { - $onemax[] = mb_strtolower(trim($class)); - } - } - $count = array(); - for ($i=1;$i<4;$i++) { - $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)), - trim($name)); - } else { - $class = 'other'; - $name = $this->cleaned_data['label'.$i]; - } - if (!isset($count[$class])) $count[$class] = 1; - 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 label from the %s class to a page.'), $class); - throw new Pluf_Form_Invalid(__('You provided an invalid label.')); - } - } - return $this->cleaned_data; - } - - /** - * 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.')); - } - // Add a tag for each label - $tags = array(); - if ($this->show_full) { - for ($i=1;$i<4;$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]); - } - $tags[] = IDF_Tag::add($name, $this->project, $class); - } - } - } - // Create the page - $page = new IDF_Wiki_Page(); - $page->project = $this->project; - $page->submitter = $this->user; - $page->summary = trim($this->cleaned_data['summary']); - $page->title = trim($this->cleaned_data['title']); - $page->create(); - foreach ($tags as $tag) { - $page->setAssoc($tag); - } - // add the first revision - $rev = new IDF_Wiki_PageRevision(); - $rev->wikipage = $page; - $rev->content = $this->cleaned_data['content']; - $rev->submitter = $this->user; - $rev->summary = __('Initial page creation'); - $rev->create(); - $rev->notify($this->project->getConf()); - return $page; - } -} diff --git a/src/IDF/Form/WikiDelete.php b/src/IDF/Form/WikiDelete.php deleted file mode 100644 index 1595ecb..0000000 --- a/src/IDF/Form/WikiDelete.php +++ /dev/null @@ -1,64 +0,0 @@ -page = $extra['page']; - $this->fields['confirm'] = new Pluf_Form_Field_Boolean( - array('required' => true, - 'label' => __('Yes, I understand that the page 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->page->delete(); - return true; - } -} diff --git a/src/IDF/Form/WikiPageCreate.php b/src/IDF/Form/WikiPageCreate.php new file mode 100644 index 0000000..01df4ce --- /dev/null +++ b/src/IDF/Form/WikiPageCreate.php @@ -0,0 +1,205 @@ +user = $extra['user']; + $this->project = $extra['project']; + if ($this->user->hasPerm('IDF.project-owner', $this->project) + or $this->user->hasPerm('IDF.project-member', $this->project)) { + $this->show_full = true; + } + $initname = (!empty($extra['name'])) ? $extra['name'] : __('PageName'); + $this->fields['title'] = new Pluf_Form_Field_Varchar( + array('required' => true, + 'label' => __('Page title'), + 'initial' => $initname, + 'widget_attrs' => array( + 'maxlength' => 200, + 'size' => 67, + ), + 'help_text' => __('The page 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 pages.'), + 'initial' => '', + 'widget_attrs' => array( + 'maxlength' => 200, + 'size' => 67, + ), + )); + $this->fields['content'] = new Pluf_Form_Field_Varchar( + array('required' => true, + 'label' => __('Content'), + 'initial' => $initial, + 'widget' => 'Pluf_Form_Widget_TextareaInput', + 'widget_attrs' => array( + 'cols' => 68, + 'rows' => 26, + ), + )); + + if ($this->show_full) { + for ($i=1;$i<4;$i++) { + $this->fields['label'.$i] = new Pluf_Form_Field_Varchar( + array('required' => false, + 'label' => __('Labels'), + 'initial' => '', + 'widget_attrs' => array( + 'maxlength' => 50, + 'size' => 20, + ), + )); + } + } + } + + 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)); + $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.')); + } + return $title; + } + + /** + * Validate the interconnection in the form. + */ + public function clean() + { + if (!$this->show_full) { + return $this->cleaned_data; + } + $conf = new IDF_Conf(); + $conf->setProject($this->project); + $onemax = array(); + foreach (explode(',', $conf->getVal('labels_wiki_one_max', IDF_Form_WikiConf::init_one_max)) as $class) { + if (trim($class) != '') { + $onemax[] = mb_strtolower(trim($class)); + } + } + $count = array(); + for ($i=1;$i<4;$i++) { + $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)), + trim($name)); + } else { + $class = 'other'; + $name = $this->cleaned_data['label'.$i]; + } + if (!isset($count[$class])) $count[$class] = 1; + 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 label from the %s class to a page.'), $class); + throw new Pluf_Form_Invalid(__('You provided an invalid label.')); + } + } + return $this->cleaned_data; + } + + /** + * 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.')); + } + // Add a tag for each label + $tags = array(); + if ($this->show_full) { + for ($i=1;$i<4;$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]); + } + $tags[] = IDF_Tag::add($name, $this->project, $class); + } + } + } + // Create the page + $page = new IDF_Wiki_Page(); + $page->project = $this->project; + $page->submitter = $this->user; + $page->summary = trim($this->cleaned_data['summary']); + $page->title = trim($this->cleaned_data['title']); + $page->create(); + foreach ($tags as $tag) { + $page->setAssoc($tag); + } + // add the first revision + $rev = new IDF_Wiki_PageRevision(); + $rev->wikipage = $page; + $rev->content = $this->cleaned_data['content']; + $rev->submitter = $this->user; + $rev->summary = __('Initial page creation'); + $rev->create(); + $rev->notify($this->project->getConf()); + return $page; + } +} diff --git a/src/IDF/Form/WikiPageDelete.php b/src/IDF/Form/WikiPageDelete.php new file mode 100644 index 0000000..d7b952a --- /dev/null +++ b/src/IDF/Form/WikiPageDelete.php @@ -0,0 +1,64 @@ +page = $extra['page']; + $this->fields['confirm'] = new Pluf_Form_Field_Boolean( + array('required' => true, + 'label' => __('Yes, I understand that the page 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->page->delete(); + return true; + } +} diff --git a/src/IDF/Form/WikiPageUpdate.php b/src/IDF/Form/WikiPageUpdate.php new file mode 100644 index 0000000..d164793 --- /dev/null +++ b/src/IDF/Form/WikiPageUpdate.php @@ -0,0 +1,242 @@ +page = $extra['page']; + $this->user = $extra['user']; + $this->project = $extra['project']; + if ($this->user->hasPerm('IDF.project-owner', $this->project) + or $this->user->hasPerm('IDF.project-member', $this->project)) { + $this->show_full = true; + } + if ($this->show_full) { + $this->fields['title'] = new Pluf_Form_Field_Varchar( + array('required' => true, + 'label' => __('Page title'), + 'initial' => $this->page->title, + 'widget_attrs' => array( + 'maxlength' => 200, + 'size' => 67, + ), + 'help_text' => __('The page 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 pages.'), + 'initial' => $this->page->summary, + 'widget_attrs' => array( + 'maxlength' => 200, + 'size' => 67, + ), + )); + } + $rev = $this->page->get_current_revision(); + $this->fields['content'] = new Pluf_Form_Field_Varchar( + array('required' => true, + 'label' => __('Content'), + 'initial' => $rev->content, + 'widget' => 'Pluf_Form_Widget_TextareaInput', + 'widget_attrs' => array( + 'cols' => 68, + 'rows' => 26, + ), + )); + $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, + ), + )); + + if ($this->show_full) { + $tags = $this->page->get_tags_list(); + for ($i=1;$i<4;$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, + ), + )); + } + } + } + + 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)); + $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.')); + } + return $title; + } + + /** + * Validate the interconnection in the form. + */ + public function clean() + { + if (!$this->show_full) { + return $this->cleaned_data; + } + $conf = new IDF_Conf(); + $conf->setProject($this->project); + $onemax = array(); + foreach (explode(',', $conf->getVal('labels_wiki_one_max', IDF_Form_WikiConf::init_one_max)) as $class) { + if (trim($class) != '') { + $onemax[] = mb_strtolower(trim($class)); + } + } + $count = array(); + for ($i=1;$i<4;$i++) { + $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)), + trim($name)); + } else { + $class = 'other'; + $name = $this->cleaned_data['label'.$i]; + } + if (!isset($count[$class])) $count[$class] = 1; + 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 label from the %s class to a page.'), $class); + throw new Pluf_Form_Invalid(__('You provided an invalid label.')); + } + } + return $this->cleaned_data; + } + + /** + * 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.')); + } + if ($this->show_full) { + $tagids = array(); + $tags = array(); + for ($i=1;$i<4;$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::add($name, $this->project, $class); + $tags[] = $tag; + $tagids[] = $tag->id; + } + } + // Compare between the old and the new data + $changes = array(); + $oldtags = $this->page->get_tags_list(); + foreach ($tags as $tag) { + if (!Pluf_Model_InArray($tag, $oldtags)) { + if (!isset($changes['lb'])) $changes['lb'] = array(); + if ($tag->class != 'Other') { + $changes['lb'][] = (string) $tag; //new tag + } else { + $changes['lb'][] = (string) $tag->name; + } + } + } + foreach ($oldtags as $tag) { + if (!Pluf_Model_InArray($tag, $tags)) { + if (!isset($changes['lb'])) $changes['lb'] = array(); + if ($tag->class != 'Other') { + $changes['lb'][] = '-'.(string) $tag; //new tag + } else { + $changes['lb'][] = '-'.(string) $tag->name; + } + } + } + if (trim($this->page->summary) != trim($this->cleaned_data['summary'])) { + $changes['su'] = trim($this->cleaned_data['summary']); + } + // Update the page + $this->page->batchAssoc('IDF_Tag', $tagids); + $this->page->summary = trim($this->cleaned_data['summary']); + $this->page->title = trim($this->cleaned_data['title']); + } else { + $changes = array(); + } + $this->page->update(); + // add the new revision + $rev = new IDF_Wiki_PageRevision(); + $rev->wikipage = $this->page; + $rev->content = $this->cleaned_data['content']; + $rev->submitter = $this->user; + $rev->summary = $this->cleaned_data['comment']; + $rev->changes = $changes; + $rev->create(); + $rev->notify($this->project->getConf(), false); + return $this->page; + } +} diff --git a/src/IDF/Form/WikiResourceCreate.php b/src/IDF/Form/WikiResourceCreate.php new file mode 100644 index 0000000..a1edfa1 --- /dev/null +++ b/src/IDF/Form/WikiResourceCreate.php @@ -0,0 +1,169 @@ +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->orig_file_ext = $extension; + $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->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/'; + } +} diff --git a/src/IDF/Form/WikiUpdate.php b/src/IDF/Form/WikiUpdate.php deleted file mode 100644 index dae75f0..0000000 --- a/src/IDF/Form/WikiUpdate.php +++ /dev/null @@ -1,242 +0,0 @@ -page = $extra['page']; - $this->user = $extra['user']; - $this->project = $extra['project']; - if ($this->user->hasPerm('IDF.project-owner', $this->project) - or $this->user->hasPerm('IDF.project-member', $this->project)) { - $this->show_full = true; - } - if ($this->show_full) { - $this->fields['title'] = new Pluf_Form_Field_Varchar( - array('required' => true, - 'label' => __('Page title'), - 'initial' => $this->page->title, - 'widget_attrs' => array( - 'maxlength' => 200, - 'size' => 67, - ), - 'help_text' => __('The page 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 pages.'), - 'initial' => $this->page->summary, - 'widget_attrs' => array( - 'maxlength' => 200, - 'size' => 67, - ), - )); - } - $rev = $this->page->get_current_revision(); - $this->fields['content'] = new Pluf_Form_Field_Varchar( - array('required' => true, - 'label' => __('Content'), - 'initial' => $rev->content, - 'widget' => 'Pluf_Form_Widget_TextareaInput', - 'widget_attrs' => array( - 'cols' => 68, - 'rows' => 26, - ), - )); - $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, - ), - )); - - if ($this->show_full) { - $tags = $this->page->get_tags_list(); - for ($i=1;$i<4;$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, - ), - )); - } - } - } - - 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)); - $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.')); - } - return $title; - } - - /** - * Validate the interconnection in the form. - */ - public function clean() - { - if (!$this->show_full) { - return $this->cleaned_data; - } - $conf = new IDF_Conf(); - $conf->setProject($this->project); - $onemax = array(); - foreach (explode(',', $conf->getVal('labels_wiki_one_max', IDF_Form_WikiConf::init_one_max)) as $class) { - if (trim($class) != '') { - $onemax[] = mb_strtolower(trim($class)); - } - } - $count = array(); - for ($i=1;$i<4;$i++) { - $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)), - trim($name)); - } else { - $class = 'other'; - $name = $this->cleaned_data['label'.$i]; - } - if (!isset($count[$class])) $count[$class] = 1; - 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 label from the %s class to a page.'), $class); - throw new Pluf_Form_Invalid(__('You provided an invalid label.')); - } - } - return $this->cleaned_data; - } - - /** - * 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.')); - } - if ($this->show_full) { - $tagids = array(); - $tags = array(); - for ($i=1;$i<4;$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::add($name, $this->project, $class); - $tags[] = $tag; - $tagids[] = $tag->id; - } - } - // Compare between the old and the new data - $changes = array(); - $oldtags = $this->page->get_tags_list(); - foreach ($tags as $tag) { - if (!Pluf_Model_InArray($tag, $oldtags)) { - if (!isset($changes['lb'])) $changes['lb'] = array(); - if ($tag->class != 'Other') { - $changes['lb'][] = (string) $tag; //new tag - } else { - $changes['lb'][] = (string) $tag->name; - } - } - } - foreach ($oldtags as $tag) { - if (!Pluf_Model_InArray($tag, $tags)) { - if (!isset($changes['lb'])) $changes['lb'] = array(); - if ($tag->class != 'Other') { - $changes['lb'][] = '-'.(string) $tag; //new tag - } else { - $changes['lb'][] = '-'.(string) $tag->name; - } - } - } - if (trim($this->page->summary) != trim($this->cleaned_data['summary'])) { - $changes['su'] = trim($this->cleaned_data['summary']); - } - // Update the page - $this->page->batchAssoc('IDF_Tag', $tagids); - $this->page->summary = trim($this->cleaned_data['summary']); - $this->page->title = trim($this->cleaned_data['title']); - } else { - $changes = array(); - } - $this->page->update(); - // add the new revision - $rev = new IDF_Wiki_PageRevision(); - $rev->wikipage = $this->page; - $rev->content = $this->cleaned_data['content']; - $rev->submitter = $this->user; - $rev->summary = $this->cleaned_data['comment']; - $rev->changes = $changes; - $rev->create(); - $rev->notify($this->project->getConf(), false); - return $this->page; - } -} diff --git a/src/IDF/Views/Wiki.php b/src/IDF/Views/Wiki.php index 0e75c47..a70617b 100644 --- a/src/IDF/Views/Wiki.php +++ b/src/IDF/Views/Wiki.php @@ -77,6 +77,44 @@ class IDF_Views_Wiki $request); } + /** + * View list of resources for a given project. + */ + public $listResources_precond = array('IDF_Precondition::accessWiki', + 'Pluf_Precondition::loginRequired'); + public function listResources($request, $match) + { + $prj = $request->project; + $title = sprintf(__('%s Documentation Resources'), (string) $prj); + $pag = new Pluf_Paginator(new IDF_Wiki_Resource()); + $pag->class = 'recent-issues'; + $pag->item_extra_props = array('project_m' => $prj, + 'shortname' => $prj->shortname, + 'current_user' => $request->user); + $pag->summary = __('This table shows the resources that can be used on documentation pages.'); + $pag->action = array('IDF_Views_Wiki::listResources', array($prj->shortname)); + $pag->edit_action = array('IDF_Views_Wiki::viewResource', 'shortname', 'title'); + $pag->forced_where = new Pluf_SQL('project=%s', array($prj->id)); + $pag->extra_classes = array('right', 'a-c', 'a-c', 'a-c'); + $list_display = array( + 'title' => __('Resource Title'), + 'mime_type' => __('MIME type'), + 'summary' => __('Description'), + array('modif_dtime', 'Pluf_Paginator_DateYMD', __('Updated')), + ); + $pag->configure($list_display, array(), array('title', 'modif_dtime')); + $pag->items_per_page = 25; + $pag->no_results_text = __('No resources were found.'); + $pag->sort_order = array('title', 'ASC'); + $pag->setFromRequest($request); + return Pluf_Shortcuts_RenderToResponse('idf/wiki/listResources.html', + array( + 'page_title' => $title, + 'resources' => $pag, + ), + $request); + } + public $search_precond = array('IDF_Precondition::accessWiki',); public function search($request, $match) { @@ -173,7 +211,7 @@ class IDF_Views_Wiki $title = __('New Page'); $preview = false; if ($request->method == 'POST') { - $form = new IDF_Form_WikiCreate($request->POST, + $form = new IDF_Form_WikiPageCreate($request->POST, array('project' => $prj, 'user' => $request->user )); @@ -191,7 +229,7 @@ class IDF_Views_Wiki } else { $pagename = (isset($request->GET['name'])) ? $request->GET['name'] : ''; - $form = new IDF_Form_WikiCreate(null, + $form = new IDF_Form_WikiPageCreate(null, array('name' => $pagename, 'project' => $prj, 'user' => $request->user)); @@ -207,6 +245,43 @@ class IDF_Views_Wiki } /** + * Create a new resource. + */ + public $createResource_precond = array('IDF_Precondition::accessWiki', + 'Pluf_Precondition::loginRequired'); + public function createResource($request, $match) + { + $prj = $request->project; + $title = __('New Resource'); + $preview = false; + if ($request->method == 'POST') { + $form = new IDF_Form_WikiResourceCreate(array_merge($request->POST, $request->FILES), + array('project' => $prj, 'user' => $request->user)); + if ($form->isValid()) { + $resource = $form->save(); + $urlresource = Pluf_HTTP_URL_urlForView('IDF_Views_Wiki::viewResource', + array($prj->shortname, $resource->title)); + $request->user->setMessage(sprintf(__('The resource %s has been created.'), $urlresource, Pluf_esc($resource->title))); + $url = Pluf_HTTP_URL_urlForView('IDF_Views_Wiki::listResources', + array($prj->shortname)); + return new Pluf_HTTP_Response_Redirect($url); + } + } else { + $resourcename = (isset($request->GET['name'])) ? + $request->GET['name'] : ''; + $form = new IDF_Form_WikiResourceCreate(null, + array('name' => $resourcename, + 'project' => $prj, 'user' => $request->user)); + } + return Pluf_Shortcuts_RenderToResponse('idf/wiki/createResource.html', + array( + 'resource_title' => $title, + 'form' => $form, + ), + $request); + } + + /** * View a documentation page. */ public $viewPage_precond = array('IDF_Precondition::accessWiki'); @@ -314,7 +389,7 @@ class IDF_Views_Wiki 'user' => $request->user, 'page' => $page); if ($request->method == 'POST') { - $form = new IDF_Form_WikiUpdate($request->POST, $params); + $form = new IDF_Form_WikiPageUpdate($request->POST, $params); if ($form->isValid() and !isset($request->POST['preview'])) { $page = $form->save(); $urlpage = Pluf_HTTP_URL_urlForView('IDF_Views_Wiki::viewPage', @@ -328,7 +403,7 @@ class IDF_Views_Wiki } } else { - $form = new IDF_Form_WikiUpdate(null, $params); + $form = new IDF_Form_WikiPageUpdate(null, $params); } return Pluf_Shortcuts_RenderToResponse('idf/wiki/updatePage.html', array( @@ -354,7 +429,7 @@ class IDF_Views_Wiki $prj->inOr404($page); $params = array('page' => $page); if ($request->method == 'POST') { - $form = new IDF_Form_WikiDelete($request->POST, $params); + $form = new IDF_Form_WikiPageDelete($request->POST, $params); if ($form->isValid()) { $form->save(); $request->user->setMessage(__('The documentation page has been deleted.')); @@ -363,7 +438,7 @@ class IDF_Views_Wiki return new Pluf_HTTP_Response_Redirect($url); } } else { - $form = new IDF_Form_WikiDelete(null, $params); + $form = new IDF_Form_WikiPageDelete(null, $params); } $title = sprintf(__('Delete Page %s'), $page->title); $revision = $page->get_current_revision(); diff --git a/src/IDF/Wiki/Resource.php b/src/IDF/Wiki/Resource.php index 1504682..cc4c318 100644 --- a/src/IDF/Wiki/Resource.php +++ b/src/IDF/Wiki/Resource.php @@ -72,6 +72,14 @@ class IDF_Wiki_Resource extends Pluf_Model 'verbose' => __('MIME media type'), 'help_text' => __('The MIME media type of the resource.'), ), + 'orig_file_ext' => + array( + 'type' => 'Pluf_DB_Field_Varchar', + 'blank' => false, + 'size' => 10, + 'verbose' => __('Original file extension'), + 'help_text' => __('The original file extension of the uploaded resource.'), + ), 'summary' => array( 'type' => 'Pluf_DB_Field_Varchar', diff --git a/src/IDF/Wiki/ResourceRevision.php b/src/IDF/Wiki/ResourceRevision.php index e29b0c2..43eadd4 100644 --- a/src/IDF/Wiki/ResourceRevision.php +++ b/src/IDF/Wiki/ResourceRevision.php @@ -109,78 +109,37 @@ class IDF_Wiki_ResourceRevision extends Pluf_Model { if ($this->id == '') { $this->creation_dtime = gmdate('Y-m-d H:i:s'); + $this->is_head = true; } } function postSave($create=false) { if ($create) { - IDF_Timeline::insert($this, $this->get_project(), - $this->get_submitter(), $this->creation_dtime); + $sql = new Pluf_SQL('wikiresource=%s', array($this->wikiresource)); + $rev = Pluf::factory('IDF_Wiki_ResourceRevision')->getList(array('filter'=>$sql->gen())); + if ($rev->count() > 1) { + foreach ($rev as $r) { + if ($r->id != $this->id and $r->is_head) { + $r->is_head = false; + $r->update(); + } + } + } + // update the modification timestamp + $resource = $this->get_wikiresource(); + $resource->update(); } } - function getAbsoluteUrl($project) + function getFilePath() { - return Pluf::f('url_upload').'/'.$project->shortname.'/files/'.$this->file; + return sprintf(Pluf::f('upload_path').'/'.$this->get_wikiresource()->get_project()->shortname.'/wiki/res/%d/%d.%s', + $this->get_wikiresource()->id, $this->id, $this->get_wikiresource()->orig_file_ext); } - function getFullPath() - { - return(Pluf::f('upload_path').'/'.$this->get_project()->shortname.'/files/'.$this->file); - } - - /** - * We drop the information from the timeline. - */ function preDelete() { - IDF_Timeline::remove($this); - @unlink(Pluf::f('upload_path').'/'.$this->project->shortname.'/files/'.$this->file); - } - - /** - * Returns the timeline fragment for the file. - * - * - * @param Pluf_HTTP_Request - * @return Pluf_Template_SafeString - */ - public function timelineFragment($request) - { - $url = Pluf_HTTP_URL_urlForView('IDF_Views_Download::view', - array($request->project->shortname, - $this->id)); - $out = '
{trans 'Number of resources:'} {$resources.nb_items}
+{/block} +