Partial fix of issue 55, addition of a simple Wiki.
Added a base wiki, it is now possible to create wiki pages and update them. Revisions are kept also not used/displayed at the moment.
This commit is contained in:
parent
b13633fed2
commit
8eb5715656
@ -36,6 +36,7 @@ class IDF_Form_TabsConf extends Pluf_Form
|
|||||||
$this->project = $extra['project'];
|
$this->project = $extra['project'];
|
||||||
|
|
||||||
$ak = array('downloads_access_rights' => __('Downloads'),
|
$ak = array('downloads_access_rights' => __('Downloads'),
|
||||||
|
'wiki_access_rights' => __('Documentation'),
|
||||||
'source_access_rights' => __('Source'),
|
'source_access_rights' => __('Source'),
|
||||||
'issues_access_rights' => __('Issues'),);
|
'issues_access_rights' => __('Issues'),);
|
||||||
foreach ($ak as $key=>$label) {
|
foreach ($ak as $key=>$label) {
|
||||||
|
66
src/IDF/Form/WikiConf.php
Normal file
66
src/IDF/Form/WikiConf.php
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
<?php
|
||||||
|
/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||||
|
/*
|
||||||
|
# ***** BEGIN LICENSE BLOCK *****
|
||||||
|
# This file is part of InDefero, an open source project management application.
|
||||||
|
# Copyright (C) 2008 Céondo Ltd and contributors.
|
||||||
|
#
|
||||||
|
# InDefero is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# InDefero is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
#
|
||||||
|
# ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configuration of the labels etc. for the wiki pages.
|
||||||
|
*/
|
||||||
|
class IDF_Form_WikiConf extends Pluf_Form
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Defined as constants to easily access the value in the
|
||||||
|
* form in the case nothing is in the db yet.
|
||||||
|
*/
|
||||||
|
const init_predefined = 'Featured = Listed on project home page
|
||||||
|
Phase:Requirements = Project vision and requirements
|
||||||
|
Phase:Design = Project design and key concerns
|
||||||
|
Phase:Implementation = Developers\' guide
|
||||||
|
Phase:QA = Testing plans and QA strategies
|
||||||
|
Phase:Deploy = How to install and configure the program
|
||||||
|
Phase:Support = Plans for user support and advocacy
|
||||||
|
Deprecated = Most users should NOT reference this';
|
||||||
|
|
||||||
|
const init_one_max = '';
|
||||||
|
|
||||||
|
public function initFields($extra=array())
|
||||||
|
{
|
||||||
|
$this->fields['labels_wiki_predefined'] = new Pluf_Form_Field_Varchar(
|
||||||
|
array('required' => true,
|
||||||
|
'label' => __('Predefined documentation page labels'),
|
||||||
|
'initial' => self::init_predefined,
|
||||||
|
'widget_attrs' => array('rows' => 13,
|
||||||
|
'cols' => 75),
|
||||||
|
'widget' => 'Pluf_Form_Widget_TextareaInput',
|
||||||
|
));
|
||||||
|
|
||||||
|
$this->fields['labels_wiki_one_max'] = new Pluf_Form_Field_Varchar(
|
||||||
|
array('required' => false,
|
||||||
|
'label' => __('Each documentation page may have at most one label with each of these classes'),
|
||||||
|
'initial' => self::init_one_max,
|
||||||
|
'widget_attrs' => array('size' => 60),
|
||||||
|
));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
203
src/IDF/Form/WikiCreate.php
Normal file
203
src/IDF/Form/WikiCreate.php
Normal file
@ -0,0 +1,203 @@
|
|||||||
|
<?php
|
||||||
|
/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||||
|
/*
|
||||||
|
# ***** BEGIN LICENSE BLOCK *****
|
||||||
|
# This file is part of InDefero, an open source project management application.
|
||||||
|
# Copyright (C) 2008 Céondo Ltd and contributors.
|
||||||
|
#
|
||||||
|
# InDefero is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# InDefero is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
#
|
||||||
|
# ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new documentation page.
|
||||||
|
*
|
||||||
|
* This create a new page and the corresponding revision.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class IDF_Form_WikiCreate extends Pluf_Form
|
||||||
|
{
|
||||||
|
public $user = null;
|
||||||
|
public $project = null;
|
||||||
|
public $show_full = false;
|
||||||
|
|
||||||
|
public function initFields($extra=array())
|
||||||
|
{
|
||||||
|
$initial = __('# Introduction
|
||||||
|
|
||||||
|
Add your content here.
|
||||||
|
|
||||||
|
|
||||||
|
# Details
|
||||||
|
|
||||||
|
Add your content here. Format your content with:
|
||||||
|
|
||||||
|
* Text in **bold** or *italic*.
|
||||||
|
* Headings, paragraphs, and lists.
|
||||||
|
* Links to other [[WikiPage]].
|
||||||
|
');
|
||||||
|
$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;
|
||||||
|
}
|
||||||
|
$this->fields['title'] = new Pluf_Form_Field_Varchar(
|
||||||
|
array('required' => true,
|
||||||
|
'label' => __('Page title'),
|
||||||
|
'initial' => __('PageName'),
|
||||||
|
'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' => 58,
|
||||||
|
'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_WikiPage')->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 (split(',', $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_WikiPage();
|
||||||
|
$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_WikiRevision();
|
||||||
|
$rev->wikipage = $page;
|
||||||
|
$rev->content = $this->cleaned_data['content'];
|
||||||
|
$rev->submitter = $this->user;
|
||||||
|
$rev->summary = __('Initial page creation');
|
||||||
|
$rev->create();
|
||||||
|
return $page;
|
||||||
|
}
|
||||||
|
}
|
241
src/IDF/Form/WikiUpdate.php
Normal file
241
src/IDF/Form/WikiUpdate.php
Normal file
@ -0,0 +1,241 @@
|
|||||||
|
<?php
|
||||||
|
/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||||
|
/*
|
||||||
|
# ***** BEGIN LICENSE BLOCK *****
|
||||||
|
# This file is part of InDefero, an open source project management application.
|
||||||
|
# Copyright (C) 2008 Céondo Ltd and contributors.
|
||||||
|
#
|
||||||
|
# InDefero is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# InDefero is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
#
|
||||||
|
# ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update a documentation page.
|
||||||
|
*
|
||||||
|
* This add a corresponding revision.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class IDF_Form_WikiUpdate extends Pluf_Form
|
||||||
|
{
|
||||||
|
public $user = null;
|
||||||
|
public $project = null;
|
||||||
|
public $page = null;
|
||||||
|
public $show_full = false;
|
||||||
|
|
||||||
|
|
||||||
|
public function initFields($extra=array())
|
||||||
|
{
|
||||||
|
$this->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' => 58,
|
||||||
|
'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_WikiPage')->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 (split(',', $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_WikiRevision();
|
||||||
|
$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();
|
||||||
|
return $this->page;
|
||||||
|
}
|
||||||
|
}
|
@ -53,6 +53,7 @@ class IDF_Middleware
|
|||||||
$request->conf = new IDF_Conf();
|
$request->conf = new IDF_Conf();
|
||||||
$request->conf->setProject($request->project);
|
$request->conf->setProject($request->project);
|
||||||
$ak = array('downloads_access_rights' => 'hasDownloadsAccess',
|
$ak = array('downloads_access_rights' => 'hasDownloadsAccess',
|
||||||
|
'wiki_access_rights' => 'hasWikiAccess',
|
||||||
'source_access_rights' => 'hasSourceAccess',
|
'source_access_rights' => 'hasSourceAccess',
|
||||||
'issues_access_rights' => 'hasIssuesAccess');
|
'issues_access_rights' => 'hasIssuesAccess');
|
||||||
$request->rights = array();
|
$request->rights = array();
|
||||||
|
54
src/IDF/Migrations/7Wiki.php
Normal file
54
src/IDF/Migrations/7Wiki.php
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
<?php
|
||||||
|
/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||||
|
/*
|
||||||
|
# ***** BEGIN LICENSE BLOCK *****
|
||||||
|
# This file is part of InDefero, an open source project management application.
|
||||||
|
# Copyright (C) 2008 Céondo Ltd and contributors.
|
||||||
|
#
|
||||||
|
# InDefero is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# InDefero is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
#
|
||||||
|
# ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the download of files.
|
||||||
|
*/
|
||||||
|
|
||||||
|
function IDF_Migrations_7Wiki_up($params=null)
|
||||||
|
{
|
||||||
|
$models = array(
|
||||||
|
'IDF_WikiPage',
|
||||||
|
'IDF_WikiRevision',
|
||||||
|
);
|
||||||
|
$db = Pluf::db();
|
||||||
|
$schema = new Pluf_DB_Schema($db);
|
||||||
|
foreach ($models as $model) {
|
||||||
|
$schema->model = new $model();
|
||||||
|
$schema->createTables();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function IDF_Migrations_7Wiki_down($params=null)
|
||||||
|
{
|
||||||
|
$models = array(
|
||||||
|
'IDF_WikiRevision',
|
||||||
|
'IDF_WikiPage',
|
||||||
|
);
|
||||||
|
$db = Pluf::db();
|
||||||
|
$schema = new Pluf_DB_Schema($db);
|
||||||
|
foreach ($models as $model) {
|
||||||
|
$schema->model = new $model();
|
||||||
|
$schema->dropTables();
|
||||||
|
}
|
||||||
|
}
|
@ -40,6 +40,8 @@ function IDF_Migrations_Install_setup($params=null)
|
|||||||
'IDF_IssueFile',
|
'IDF_IssueFile',
|
||||||
'IDF_Commit',
|
'IDF_Commit',
|
||||||
'IDF_Timeline',
|
'IDF_Timeline',
|
||||||
|
'IDF_WikiPage',
|
||||||
|
'IDF_WikiRevision',
|
||||||
);
|
);
|
||||||
$db = Pluf::db();
|
$db = Pluf::db();
|
||||||
$schema = new Pluf_DB_Schema($db);
|
$schema = new Pluf_DB_Schema($db);
|
||||||
@ -69,6 +71,8 @@ function IDF_Migrations_Install_teardown($params=null)
|
|||||||
$perm = Pluf_Permission::getFromString('IDF.project-owner');
|
$perm = Pluf_Permission::getFromString('IDF.project-owner');
|
||||||
if ($perm) $perm->delete();
|
if ($perm) $perm->delete();
|
||||||
$models = array(
|
$models = array(
|
||||||
|
'IDF_WikiRevision',
|
||||||
|
'IDF_WikiPage',
|
||||||
'IDF_Timeline',
|
'IDF_Timeline',
|
||||||
'IDF_IssueFile',
|
'IDF_IssueFile',
|
||||||
'IDF_Search_Occ',
|
'IDF_Search_Occ',
|
||||||
|
@ -143,6 +143,15 @@ class IDF_Precondition
|
|||||||
return self::accessTabGeneric($request, 'downloads_access_rights');
|
return self::accessTabGeneric($request, 'downloads_access_rights');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static public function accessWiki($request)
|
||||||
|
{
|
||||||
|
$res = self::baseAccess($request);
|
||||||
|
if (true !== $res) {
|
||||||
|
return $res;
|
||||||
|
}
|
||||||
|
return self::accessTabGeneric($request, 'wiki_access_rights');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Based on the request, it is automatically setting the user.
|
* Based on the request, it is automatically setting the user.
|
||||||
*
|
*
|
||||||
|
@ -283,10 +283,9 @@ class IDF_Project extends Pluf_Model
|
|||||||
/**
|
/**
|
||||||
* Generate the tag clouds.
|
* Generate the tag clouds.
|
||||||
*
|
*
|
||||||
* Return an array of tags sorted class, then name. Each tag get
|
* Return an array of tags sorted by class, then name. Each tag
|
||||||
* the extra property 'nb_use' for the number of use in the
|
* get the extra property 'nb_use' for the number of use in the
|
||||||
* project. For issues, only open issues are used to generate the
|
* project.
|
||||||
* cloud.
|
|
||||||
*
|
*
|
||||||
* @param string ('issues') 'closed_issues' or 'downloads'
|
* @param string ('issues') 'closed_issues' or 'downloads'
|
||||||
* @return ArrayObject of IDF_Tag
|
* @return ArrayObject of IDF_Tag
|
||||||
|
@ -32,13 +32,13 @@ class IDF_Template_IssueComment extends Pluf_Template_Tag
|
|||||||
private $request = null;
|
private $request = null;
|
||||||
private $scm = null;
|
private $scm = null;
|
||||||
|
|
||||||
function start($text, $request, $echo=true, $wordwrap=true)
|
function start($text, $request, $echo=true, $wordwrap=true, $esc=true)
|
||||||
{
|
{
|
||||||
$this->project = $request->project;
|
$this->project = $request->project;
|
||||||
$this->request = $request;
|
$this->request = $request;
|
||||||
$this->scm = IDF_Scm::get($request);
|
$this->scm = IDF_Scm::get($request);
|
||||||
if ($wordwrap) $text = wordwrap($text, 69, "\n", true);
|
if ($wordwrap) $text = wordwrap($text, 69, "\n", true);
|
||||||
$text = Pluf_esc($text);
|
if ($esc) $text = Pluf_esc($text);
|
||||||
$text = ereg_replace('[[:alpha:]]+://[^<>[:space:]]+[[:alnum:]/]',
|
$text = ereg_replace('[[:alpha:]]+://[^<>[:space:]]+[[:alnum:]/]',
|
||||||
'<a href="\\0" rel="nofollow">\\0</a>',
|
'<a href="\\0" rel="nofollow">\\0</a>',
|
||||||
$text);
|
$text);
|
||||||
|
@ -23,80 +23,55 @@
|
|||||||
|
|
||||||
Pluf::loadFunction('Pluf_Text_MarkDown_parse');
|
Pluf::loadFunction('Pluf_Text_MarkDown_parse');
|
||||||
|
|
||||||
function IDF_Template_Markdown_filter($mdtext)
|
/**
|
||||||
|
* Make the links to issues and commits.
|
||||||
|
*/
|
||||||
|
class IDF_Template_Markdown extends Pluf_Template_Tag
|
||||||
{
|
{
|
||||||
$filter = new IDF_Template_Markdown();
|
private $project = null;
|
||||||
return Pluf_Template::markSafe(Pluf_Text_MarkDown_parse($filter->go($mdtext)));
|
private $request = null;
|
||||||
|
private $scm = null;
|
||||||
|
|
||||||
|
function start($text, $request)
|
||||||
|
{
|
||||||
|
$this->project = $request->project;
|
||||||
|
$this->request = $request;
|
||||||
|
$filter = new IDF_Template_MarkdownPrefilter();
|
||||||
|
$text = $filter->go($text);
|
||||||
|
// The filter has replace < and > also in the code blocks so
|
||||||
|
// we need to revert them
|
||||||
|
$tmp = array();
|
||||||
|
foreach (preg_split("/\015\012|\015|\012/", $text, -1) as $s) {
|
||||||
|
if (0 === strpos($s, ' ')) {
|
||||||
|
$s = str_replace(array('<', '>'),
|
||||||
|
array('<', '>'), $s);
|
||||||
|
}
|
||||||
|
$tmp[] = $s;
|
||||||
|
}
|
||||||
|
$text = implode("\n", $tmp);
|
||||||
|
// Replace like in the issue text
|
||||||
|
$tag = new IDF_Template_IssueComment();
|
||||||
|
$text = $tag->start($text, $request, false, false, false);
|
||||||
|
// Replace [[PageName]] with corresponding link to the page.
|
||||||
|
// if not the right to see the
|
||||||
|
$text = preg_replace_callback('#\[\[([A-Za-z0-9\-]+)\]\]#im',
|
||||||
|
array($this, 'callbackWikiPage'),
|
||||||
|
$text);
|
||||||
|
echo Pluf_Text_MarkDown_parse($text);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
function callbackWikiPage($m)
|
||||||
* Strict class to only allow entities.
|
|
||||||
*/
|
|
||||||
class IDF_Template_Markdown extends Pluf_Text_HTML_Filter
|
|
||||||
{
|
{
|
||||||
public $allowed = array();
|
$sql = new Pluf_SQL('project=%s AND title=%s',
|
||||||
public $always_close = array();
|
array($this->project->id, $m[1]));
|
||||||
public $remove_blanks = array();
|
$pages = Pluf::factory('IDF_WikiPage')->getList(array('filter'=>$sql->gen()));
|
||||||
public $allowed_entities = array(
|
if ($pages->count() != 1) {
|
||||||
'amp',
|
return $m[0];
|
||||||
'gt',
|
|
||||||
'lt',
|
|
||||||
'quot',
|
|
||||||
'nbsp',
|
|
||||||
'ndash',
|
|
||||||
'rdquo',
|
|
||||||
'ldquo',
|
|
||||||
'Alpha',
|
|
||||||
'Beta',
|
|
||||||
'Gamma',
|
|
||||||
'Delta',
|
|
||||||
'Epsilon',
|
|
||||||
'Zeta',
|
|
||||||
'Eta',
|
|
||||||
'Theta',
|
|
||||||
'Iota',
|
|
||||||
'Kappa',
|
|
||||||
'Lambda',
|
|
||||||
'Mu',
|
|
||||||
'Nu',
|
|
||||||
'Xi',
|
|
||||||
'Omicron',
|
|
||||||
'Pi',
|
|
||||||
'Rho',
|
|
||||||
'Sigma',
|
|
||||||
'Tau',
|
|
||||||
'Upsilon',
|
|
||||||
'Phi',
|
|
||||||
'Chi',
|
|
||||||
'Psi',
|
|
||||||
'Omega',
|
|
||||||
'alpha',
|
|
||||||
'beta',
|
|
||||||
'gamma',
|
|
||||||
'delta',
|
|
||||||
'epsilon',
|
|
||||||
'zeta',
|
|
||||||
'eta',
|
|
||||||
'theta',
|
|
||||||
'iota',
|
|
||||||
'kappa',
|
|
||||||
'lambda',
|
|
||||||
'mu',
|
|
||||||
'nu',
|
|
||||||
'xi',
|
|
||||||
'omicron',
|
|
||||||
'pi',
|
|
||||||
'rho',
|
|
||||||
'sigmaf',
|
|
||||||
'sigma',
|
|
||||||
'tau',
|
|
||||||
'upsilon',
|
|
||||||
'phi',
|
|
||||||
'chi',
|
|
||||||
'psi',
|
|
||||||
'omega',
|
|
||||||
'thetasym',
|
|
||||||
'upsih',
|
|
||||||
'piv',
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
if (!$this->request->rights['hasWikiAccess']) {
|
||||||
|
return $m[1];
|
||||||
|
}
|
||||||
|
return '<a href="'.Pluf_HTTP_URL_urlForView('IDF_Views_Wiki::view', array($this->project->shortname, $pages[0]->title)).'" title="'.Pluf_esc($pages[0]->summary).'">'.$m[1].'</a>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
94
src/IDF/Template/MarkdownPrefilter.php
Normal file
94
src/IDF/Template/MarkdownPrefilter.php
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
<?php
|
||||||
|
/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||||
|
/*
|
||||||
|
# ***** BEGIN LICENSE BLOCK *****
|
||||||
|
# This file is part of InDefero, an open source project management application.
|
||||||
|
# Copyright (C) 2008 Céondo Ltd and contributors.
|
||||||
|
#
|
||||||
|
# InDefero is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# InDefero is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
#
|
||||||
|
# ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Strict class to only allow entities.
|
||||||
|
*/
|
||||||
|
class IDF_Template_MarkdownPrefilter extends Pluf_Text_HTML_Filter
|
||||||
|
{
|
||||||
|
public $allowed = array();
|
||||||
|
public $always_close = array();
|
||||||
|
public $remove_blanks = array();
|
||||||
|
public $allowed_entities = array(
|
||||||
|
'amp',
|
||||||
|
'gt',
|
||||||
|
'lt',
|
||||||
|
'quot',
|
||||||
|
'nbsp',
|
||||||
|
'ndash',
|
||||||
|
'rdquo',
|
||||||
|
'ldquo',
|
||||||
|
'Alpha',
|
||||||
|
'Beta',
|
||||||
|
'Gamma',
|
||||||
|
'Delta',
|
||||||
|
'Epsilon',
|
||||||
|
'Zeta',
|
||||||
|
'Eta',
|
||||||
|
'Theta',
|
||||||
|
'Iota',
|
||||||
|
'Kappa',
|
||||||
|
'Lambda',
|
||||||
|
'Mu',
|
||||||
|
'Nu',
|
||||||
|
'Xi',
|
||||||
|
'Omicron',
|
||||||
|
'Pi',
|
||||||
|
'Rho',
|
||||||
|
'Sigma',
|
||||||
|
'Tau',
|
||||||
|
'Upsilon',
|
||||||
|
'Phi',
|
||||||
|
'Chi',
|
||||||
|
'Psi',
|
||||||
|
'Omega',
|
||||||
|
'alpha',
|
||||||
|
'beta',
|
||||||
|
'gamma',
|
||||||
|
'delta',
|
||||||
|
'epsilon',
|
||||||
|
'zeta',
|
||||||
|
'eta',
|
||||||
|
'theta',
|
||||||
|
'iota',
|
||||||
|
'kappa',
|
||||||
|
'lambda',
|
||||||
|
'mu',
|
||||||
|
'nu',
|
||||||
|
'xi',
|
||||||
|
'omicron',
|
||||||
|
'pi',
|
||||||
|
'rho',
|
||||||
|
'sigmaf',
|
||||||
|
'sigma',
|
||||||
|
'tau',
|
||||||
|
'upsilon',
|
||||||
|
'phi',
|
||||||
|
'chi',
|
||||||
|
'psi',
|
||||||
|
'omega',
|
||||||
|
'thetasym',
|
||||||
|
'upsih',
|
||||||
|
'piv',
|
||||||
|
);
|
||||||
|
}
|
@ -81,6 +81,10 @@ class IDF_Views_Project
|
|||||||
if (true === IDF_Precondition::accessDownloads($request)) {
|
if (true === IDF_Precondition::accessDownloads($request)) {
|
||||||
$rights[] = '\'IDF_Upload\'';
|
$rights[] = '\'IDF_Upload\'';
|
||||||
}
|
}
|
||||||
|
if (true === IDF_Precondition::accessWiki($request)) {
|
||||||
|
$rights[] = '\'IDF_WikiPage\'';
|
||||||
|
$rights[] = '\'IDF_WikiRevision\'';
|
||||||
|
}
|
||||||
if (count($rights) == 0) {
|
if (count($rights) == 0) {
|
||||||
$rights[] = '\'IDF_Dummy\'';
|
$rights[] = '\'IDF_Dummy\'';
|
||||||
}
|
}
|
||||||
@ -233,6 +237,49 @@ class IDF_Views_Project
|
|||||||
$request);
|
$request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Administrate the information pages of a project.
|
||||||
|
*/
|
||||||
|
public $adminWiki_precond = array('IDF_Precondition::projectOwner');
|
||||||
|
public function adminWiki($request, $match)
|
||||||
|
{
|
||||||
|
$prj = $request->project;
|
||||||
|
$title = sprintf(__('%s Documentation Configuration'), (string) $prj);
|
||||||
|
$conf = new IDF_Conf();
|
||||||
|
$conf->setProject($prj);
|
||||||
|
if ($request->method == 'POST') {
|
||||||
|
$form = new IDF_Form_WikiConf($request->POST);
|
||||||
|
if ($form->isValid()) {
|
||||||
|
foreach ($form->cleaned_data as $key=>$val) {
|
||||||
|
$conf->setVal($key, $val);
|
||||||
|
}
|
||||||
|
$request->user->setMessage(__('The documentation configuration has been saved.'));
|
||||||
|
$url = Pluf_HTTP_URL_urlForView('IDF_Views_Project::adminDownloads',
|
||||||
|
array($prj->shortname));
|
||||||
|
return new Pluf_HTTP_Response_Redirect($url);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$params = array();
|
||||||
|
$keys = array('labels_wiki_predefined', 'labels_wiki_one_max');
|
||||||
|
foreach ($keys as $key) {
|
||||||
|
$_val = $conf->getVal($key, false);
|
||||||
|
if ($_val !== false) {
|
||||||
|
$params[$key] = $_val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (count($params) == 0) {
|
||||||
|
$params = null; //Nothing in the db, so new form.
|
||||||
|
}
|
||||||
|
$form = new IDF_Form_WikiConf($params);
|
||||||
|
}
|
||||||
|
return Pluf_Shortcuts_RenderToResponse('idf/admin/wiki.html',
|
||||||
|
array(
|
||||||
|
'page_title' => $title,
|
||||||
|
'form' => $form,
|
||||||
|
),
|
||||||
|
$request);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Administrate the members of a project.
|
* Administrate the members of a project.
|
||||||
*/
|
*/
|
||||||
@ -292,7 +339,8 @@ class IDF_Views_Project
|
|||||||
} else {
|
} else {
|
||||||
$params = array();
|
$params = array();
|
||||||
$keys = array('downloads_access_rights', 'source_access_rights',
|
$keys = array('downloads_access_rights', 'source_access_rights',
|
||||||
'issues_access_rights', 'private_project');
|
'issues_access_rights', 'private_project',
|
||||||
|
'wiki_access_rights');
|
||||||
foreach ($keys as $key) {
|
foreach ($keys as $key) {
|
||||||
$_val = $request->conf->getVal($key, false);
|
$_val = $request->conf->getVal($key, false);
|
||||||
if ($_val !== false) {
|
if ($_val !== false) {
|
||||||
|
279
src/IDF/Views/Wiki.php
Normal file
279
src/IDF/Views/Wiki.php
Normal file
@ -0,0 +1,279 @@
|
|||||||
|
<?php
|
||||||
|
/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||||
|
/*
|
||||||
|
# ***** BEGIN LICENSE BLOCK *****
|
||||||
|
# This file is part of InDefero, an open source project management application.
|
||||||
|
# Copyright (C) 2008 Céondo Ltd and contributors.
|
||||||
|
#
|
||||||
|
# InDefero is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# InDefero is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
#
|
||||||
|
# ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
Pluf::loadFunction('Pluf_HTTP_URL_urlForView');
|
||||||
|
Pluf::loadFunction('Pluf_Shortcuts_RenderToResponse');
|
||||||
|
Pluf::loadFunction('Pluf_Shortcuts_GetObjectOr404');
|
||||||
|
Pluf::loadFunction('Pluf_Shortcuts_GetFormForModel');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Documentation pages views.
|
||||||
|
*/
|
||||||
|
class IDF_Views_Wiki
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* View list of issues for a given project.
|
||||||
|
*/
|
||||||
|
public $index_precond = array('IDF_Precondition::accessWiki');
|
||||||
|
public function index($request, $match, $api=false)
|
||||||
|
{
|
||||||
|
$prj = $request->project;
|
||||||
|
$title = sprintf(__('%s Documentation'), (string) $prj);
|
||||||
|
// Paginator to paginate the pages
|
||||||
|
$pag = new Pluf_Paginator(new IDF_WikiPage());
|
||||||
|
$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 documentation pages.');
|
||||||
|
$pag->action = array('IDF_Views_Wiki::index', array($prj->shortname));
|
||||||
|
$pag->edit_action = array('IDF_Views_Wiki::view', 'shortname', 'title');
|
||||||
|
$sql = 'project=%s';
|
||||||
|
$ptags = self::getWikiTags($prj);
|
||||||
|
$dtag = array_pop($ptags); // The last tag is the deprecated tag.
|
||||||
|
$ids = self::getDeprecatedPagesIds($prj, $dtag);
|
||||||
|
if (count($ids)) {
|
||||||
|
$sql .= ' AND id NOT IN ('.implode(',', $ids).')';
|
||||||
|
}
|
||||||
|
$pag->forced_where = new Pluf_SQL($sql, array($prj->id));
|
||||||
|
$list_display = array(
|
||||||
|
'title' => __('Page Title'),
|
||||||
|
array('summary', 'IDF_Views_Wiki_SummaryAndLabels', __('Summary')),
|
||||||
|
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 documentation pages were found.');
|
||||||
|
$pag->sort_order = array('title', 'ASC');
|
||||||
|
$pag->setFromRequest($request);
|
||||||
|
//$tags = $prj->getTagCloud('downloads');
|
||||||
|
return Pluf_Shortcuts_RenderToResponse('idf/wiki/index.html',
|
||||||
|
array(
|
||||||
|
'page_title' => $title,
|
||||||
|
'pages' => $pag,
|
||||||
|
//'tags' => $tags,
|
||||||
|
'deprecated' => count($ids),
|
||||||
|
'dlabel' => $dtag,
|
||||||
|
),
|
||||||
|
$request);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new documentation page.
|
||||||
|
*/
|
||||||
|
public $create_precond = array('IDF_Precondition::accessWiki',
|
||||||
|
'Pluf_Precondition::loginRequired');
|
||||||
|
public function create($request, $match)
|
||||||
|
{
|
||||||
|
$prj = $request->project;
|
||||||
|
$title = __('New Page');
|
||||||
|
$preview = false;
|
||||||
|
if ($request->method == 'POST') {
|
||||||
|
$form = new IDF_Form_WikiCreate($request->POST,
|
||||||
|
array('project' => $prj,
|
||||||
|
'user' => $request->user
|
||||||
|
));
|
||||||
|
if ($form->isValid() and !isset($request->POST['preview'])) {
|
||||||
|
$page = $form->save();
|
||||||
|
$urlpage = Pluf_HTTP_URL_urlForView('IDF_Views_Wiki::view',
|
||||||
|
array($prj->shortname, $page->title));
|
||||||
|
$request->user->setMessage(sprintf(__('The page <a href="%s">%s</a> has been created.'), $urlpage, Pluf_esc($page->title)));
|
||||||
|
$url = Pluf_HTTP_URL_urlForView('IDF_Views_Wiki::index',
|
||||||
|
array($prj->shortname));
|
||||||
|
return new Pluf_HTTP_Response_Redirect($url);
|
||||||
|
} elseif (isset($request->POST['preview'])) {
|
||||||
|
$preview = $request->POST['content'];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$form = new IDF_Form_WikiCreate(null,
|
||||||
|
array('project' => $prj,
|
||||||
|
'user' => $request->user));
|
||||||
|
}
|
||||||
|
return Pluf_Shortcuts_RenderToResponse('idf/wiki/create.html',
|
||||||
|
array(
|
||||||
|
'auto_labels' => self::autoCompleteArrays($prj),
|
||||||
|
'page_title' => $title,
|
||||||
|
'form' => $form,
|
||||||
|
'preview' => $preview,
|
||||||
|
),
|
||||||
|
$request);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* View a documentation page.
|
||||||
|
*/
|
||||||
|
public $view_precond = array('IDF_Precondition::accessWiki');
|
||||||
|
public function view($request, $match)
|
||||||
|
{
|
||||||
|
$prj = $request->project;
|
||||||
|
// Find the page
|
||||||
|
$sql = new Pluf_SQL('project=%s AND title=%s',
|
||||||
|
array($prj->id, $match[2]));
|
||||||
|
$pages = Pluf::factory('IDF_WikiPage')->getList(array('filter'=>$sql->gen()));
|
||||||
|
if ($pages->count() != 1) {
|
||||||
|
throw new Pluf_HTTP_Error404($request);
|
||||||
|
}
|
||||||
|
$page = $pages[0];
|
||||||
|
$title = $page->title;
|
||||||
|
$revision = $page->get_current_revision();
|
||||||
|
return Pluf_Shortcuts_RenderToResponse('idf/wiki/view.html',
|
||||||
|
array(
|
||||||
|
'page_title' => $title,
|
||||||
|
'page' => $page,
|
||||||
|
'rev' => $revision,
|
||||||
|
'tags' => $page->get_tags_list(),
|
||||||
|
),
|
||||||
|
$request);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* View a documentation page.
|
||||||
|
*/
|
||||||
|
public $update_precond = array('IDF_Precondition::accessWiki',
|
||||||
|
'Pluf_Precondition::loginRequired');
|
||||||
|
public function update($request, $match)
|
||||||
|
{
|
||||||
|
$prj = $request->project;
|
||||||
|
// Find the page
|
||||||
|
$sql = new Pluf_SQL('project=%s AND title=%s',
|
||||||
|
array($prj->id, $match[2]));
|
||||||
|
$pages = Pluf::factory('IDF_WikiPage')->getList(array('filter'=>$sql->gen()));
|
||||||
|
if ($pages->count() != 1) {
|
||||||
|
throw new Pluf_HTTP_Error404($request);
|
||||||
|
}
|
||||||
|
$page = $pages[0];
|
||||||
|
$title = sprintf(__('Update %s'), $page->title);
|
||||||
|
$revision = $page->get_current_revision();
|
||||||
|
$preview = false;
|
||||||
|
$params = array('project' => $prj,
|
||||||
|
'user' => $request->user,
|
||||||
|
'page' => $page);
|
||||||
|
if ($request->method == 'POST') {
|
||||||
|
$form = new IDF_Form_WikiUpdate($request->POST, $params);
|
||||||
|
if ($form->isValid() and !isset($request->POST['preview'])) {
|
||||||
|
$page = $form->save();
|
||||||
|
$urlpage = Pluf_HTTP_URL_urlForView('IDF_Views_Wiki::view',
|
||||||
|
array($prj->shortname, $page->title));
|
||||||
|
$request->user->setMessage(sprintf(__('The page <a href="%s">%s</a> has been updated.'), $urlpage, Pluf_esc($page->title)));
|
||||||
|
$url = Pluf_HTTP_URL_urlForView('IDF_Views_Wiki::index',
|
||||||
|
array($prj->shortname));
|
||||||
|
return new Pluf_HTTP_Response_Redirect($url);
|
||||||
|
} elseif (isset($request->POST['preview'])) {
|
||||||
|
$preview = $request->POST['content'];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
|
$form = new IDF_Form_WikiUpdate(null, $params);
|
||||||
|
}
|
||||||
|
return Pluf_Shortcuts_RenderToResponse('idf/wiki/update.html',
|
||||||
|
array(
|
||||||
|
'auto_labels' => self::autoCompleteArrays($prj),
|
||||||
|
'page_title' => $title,
|
||||||
|
'page' => $page,
|
||||||
|
'rev' => $revision,
|
||||||
|
'form' => $form,
|
||||||
|
'preview' => $preview,
|
||||||
|
),
|
||||||
|
$request);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the wiki tags.
|
||||||
|
*
|
||||||
|
* @param IDF_Project
|
||||||
|
* @return ArrayObject The tags
|
||||||
|
*/
|
||||||
|
public static function getWikiTags($project)
|
||||||
|
{
|
||||||
|
return $project->getTagsFromConfig('labels_wiki_predefined',
|
||||||
|
IDF_Form_WikiConf::init_predefined);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get deprecated page ids.
|
||||||
|
*
|
||||||
|
* @param IDF_Project
|
||||||
|
* @param IDF_Tag Deprecated tag (null)
|
||||||
|
* @return array Ids of the deprecated pages.
|
||||||
|
*/
|
||||||
|
public static function getDeprecatedPagesIds($project, $dtag=null)
|
||||||
|
{
|
||||||
|
if (is_null($dtag)) {
|
||||||
|
$ptags = self::getDownloadTags($project);
|
||||||
|
$dtag = array_pop($ptags); // The last tag is the deprecated tag
|
||||||
|
}
|
||||||
|
$sql = new Pluf_SQL('project=%s AND idf_tag_id=%s', array($project->id,
|
||||||
|
$dtag->id));
|
||||||
|
$ids = array();
|
||||||
|
foreach (Pluf::factory('IDF_WikiPage')->getList(array('filter' => $sql->gen(), 'view' => 'join_tags'))
|
||||||
|
as $file) {
|
||||||
|
$ids[] = (int) $file->id;
|
||||||
|
}
|
||||||
|
return $ids;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the autocomplete arrays for the little AJAX stuff.
|
||||||
|
*/
|
||||||
|
public static function autoCompleteArrays($project)
|
||||||
|
{
|
||||||
|
$conf = new IDF_Conf();
|
||||||
|
$conf->setProject($project);
|
||||||
|
$st = preg_split("/\015\012|\015|\012/",
|
||||||
|
$conf->getVal('labels_wiki_predefined', IDF_Form_UploadConf::init_predefined), -1, PREG_SPLIT_NO_EMPTY);
|
||||||
|
$auto = '';
|
||||||
|
foreach ($st as $s) {
|
||||||
|
$v = '';
|
||||||
|
$d = '';
|
||||||
|
$_s = split('=', $s, 2);
|
||||||
|
if (count($_s) > 1) {
|
||||||
|
$v = trim($_s[0]);
|
||||||
|
$d = trim($_s[1]);
|
||||||
|
} else {
|
||||||
|
$v = trim($_s[0]);
|
||||||
|
}
|
||||||
|
$auto .= sprintf('{ name: "%s", to: "%s" }, ',
|
||||||
|
Pluf_esc($d), Pluf_esc($v));
|
||||||
|
}
|
||||||
|
return substr($auto, 0, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display the summary of a page, then on a new line, display the
|
||||||
|
* list of labels.
|
||||||
|
*/
|
||||||
|
function IDF_Views_Wiki_SummaryAndLabels($field, $page, $extra='')
|
||||||
|
{
|
||||||
|
$tags = array();
|
||||||
|
foreach ($page->get_tags_list() as $tag) {
|
||||||
|
$tags[] = Pluf_esc((string) $tag);
|
||||||
|
}
|
||||||
|
$out = '';
|
||||||
|
if (count($tags)) {
|
||||||
|
$out = '<br /><span class="note label">'.implode(', ', $tags).'</span>';
|
||||||
|
}
|
||||||
|
return Pluf_esc($page->summary).$out;
|
||||||
|
}
|
192
src/IDF/WikiPage.php
Normal file
192
src/IDF/WikiPage.php
Normal file
@ -0,0 +1,192 @@
|
|||||||
|
<?php
|
||||||
|
/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||||
|
/*
|
||||||
|
# ***** BEGIN LICENSE BLOCK *****
|
||||||
|
# This file is part of InDefero, an open source project management application.
|
||||||
|
# Copyright (C) 2008 Céondo Ltd and contributors.
|
||||||
|
#
|
||||||
|
# InDefero is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# InDefero is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
#
|
||||||
|
# ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
Pluf::loadFunction('Pluf_HTTP_URL_urlForView');
|
||||||
|
Pluf::loadFunction('Pluf_Template_dateAgo');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base definition of a wiki page.
|
||||||
|
*
|
||||||
|
* A wiki page can have tags and be starred by the users. The real
|
||||||
|
* content of the page is stored in the IDF_WikiRevision
|
||||||
|
* object. Several revisions are associated to a given page.
|
||||||
|
*/
|
||||||
|
class IDF_WikiPage extends Pluf_Model
|
||||||
|
{
|
||||||
|
public $_model = __CLASS__;
|
||||||
|
|
||||||
|
function init()
|
||||||
|
{
|
||||||
|
$this->_a['table'] = 'idf_wikipages';
|
||||||
|
$this->_a['model'] = __CLASS__;
|
||||||
|
$this->_a['cols'] = array(
|
||||||
|
// It is mandatory to have an "id" column.
|
||||||
|
'id' =>
|
||||||
|
array(
|
||||||
|
'type' => 'Pluf_DB_Field_Sequence',
|
||||||
|
'blank' => true,
|
||||||
|
),
|
||||||
|
'project' =>
|
||||||
|
array(
|
||||||
|
'type' => 'Pluf_DB_Field_Foreignkey',
|
||||||
|
'model' => 'IDF_Project',
|
||||||
|
'blank' => false,
|
||||||
|
'verbose' => __('project'),
|
||||||
|
'relate_name' => 'wikipages',
|
||||||
|
),
|
||||||
|
'title' =>
|
||||||
|
array(
|
||||||
|
'type' => 'Pluf_DB_Field_Varchar',
|
||||||
|
'blank' => false,
|
||||||
|
'size' => 250,
|
||||||
|
'verbose' => __('title'),
|
||||||
|
'help_text' => __('The title of the page must only contain letters, digits or the dash character. For example: My-new-Wiki-Page.'),
|
||||||
|
),
|
||||||
|
'summary' =>
|
||||||
|
array(
|
||||||
|
'type' => 'Pluf_DB_Field_Varchar',
|
||||||
|
'blank' => false,
|
||||||
|
'size' => 250,
|
||||||
|
'verbose' => __('summary'),
|
||||||
|
'help_text' => __('A one line description of the page content.'),
|
||||||
|
),
|
||||||
|
'submitter' =>
|
||||||
|
array(
|
||||||
|
'type' => 'Pluf_DB_Field_Foreignkey',
|
||||||
|
'model' => 'Pluf_User',
|
||||||
|
'blank' => false,
|
||||||
|
'verbose' => __('submitter'),
|
||||||
|
'relate_name' => 'submitted_wikipages',
|
||||||
|
),
|
||||||
|
'interested' =>
|
||||||
|
array(
|
||||||
|
'type' => 'Pluf_DB_Field_Manytomany',
|
||||||
|
'model' => 'Pluf_User',
|
||||||
|
'blank' => true,
|
||||||
|
'verbose' => __('interested users'),
|
||||||
|
'help_text' => 'Interested users will get an email notification when the wiki page is changed.',
|
||||||
|
),
|
||||||
|
'tags' =>
|
||||||
|
array(
|
||||||
|
'type' => 'Pluf_DB_Field_Manytomany',
|
||||||
|
'blank' => true,
|
||||||
|
'model' => 'IDF_Tag',
|
||||||
|
'verbose' => __('labels'),
|
||||||
|
),
|
||||||
|
'creation_dtime' =>
|
||||||
|
array(
|
||||||
|
'type' => 'Pluf_DB_Field_Datetime',
|
||||||
|
'blank' => true,
|
||||||
|
'verbose' => __('creation date'),
|
||||||
|
),
|
||||||
|
'modif_dtime' =>
|
||||||
|
array(
|
||||||
|
'type' => 'Pluf_DB_Field_Datetime',
|
||||||
|
'blank' => true,
|
||||||
|
'verbose' => __('modification date'),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
$this->_a['idx'] = array(
|
||||||
|
'modif_dtime_idx' =>
|
||||||
|
array(
|
||||||
|
'col' => 'modif_dtime',
|
||||||
|
'type' => 'normal',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
$table = $this->_con->pfx.'idf_tag_idf_wikipage_assoc';
|
||||||
|
$this->_a['views'] = array(
|
||||||
|
'join_tags' =>
|
||||||
|
array(
|
||||||
|
'join' => 'LEFT JOIN '.$table
|
||||||
|
.' ON idf_wikipage_id=id',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function __toString()
|
||||||
|
{
|
||||||
|
return $this->title.' - '.$this->summary;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _toIndex()
|
||||||
|
{
|
||||||
|
$rev = $this->get_current_revision()->_toIndex();
|
||||||
|
$str = str_repeat($this->summary.' ', 4).' '.$rev;
|
||||||
|
return Pluf_Text::cleanString(html_entity_decode($str, ENT_QUOTES, 'UTF-8'));
|
||||||
|
}
|
||||||
|
|
||||||
|
function get_current_revision()
|
||||||
|
{
|
||||||
|
$db = $this->getDbConnection();
|
||||||
|
$true = Pluf_DB_BooleanToDb(true, $db);
|
||||||
|
$rev = $this->get_revisions_list(array('filter' => 'is_head='.$true,
|
||||||
|
'nb' => 1));
|
||||||
|
return ($rev->count() == 1) ? $rev[0] : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function preSave($create=false)
|
||||||
|
{
|
||||||
|
if ($this->id == '') {
|
||||||
|
$this->creation_dtime = gmdate('Y-m-d H:i:s');
|
||||||
|
}
|
||||||
|
$this->modif_dtime = gmdate('Y-m-d H:i:s');
|
||||||
|
}
|
||||||
|
|
||||||
|
function postSave($create=false)
|
||||||
|
{
|
||||||
|
// Note: No indexing is performed here. The indexing is
|
||||||
|
// triggered in the postSave step of the revision to ensure
|
||||||
|
// that the page as a given revision in the database when
|
||||||
|
// doing the indexing.
|
||||||
|
if ($create) {
|
||||||
|
IDF_Timeline::insert($this, $this->get_project(),
|
||||||
|
$this->get_submitter());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an HTML fragment used to display this wikipage in the
|
||||||
|
* timeline.
|
||||||
|
*
|
||||||
|
* The request object is given to be able to check the rights and
|
||||||
|
* as such create links to other items etc. You can consider that
|
||||||
|
* if displayed, you can create a link to it.
|
||||||
|
*
|
||||||
|
* @param Pluf_HTTP_Request
|
||||||
|
* @return Pluf_Template_SafeString
|
||||||
|
*/
|
||||||
|
public function timelineFragment($request)
|
||||||
|
{
|
||||||
|
$url = Pluf_HTTP_URL_urlForView('IDF_Views_Wiki::view',
|
||||||
|
array($request->project->shortname,
|
||||||
|
$this->title));
|
||||||
|
$out = '<tr class="log"><td><a href="'.$url.'">'.
|
||||||
|
Pluf_esc(Pluf_Template_dateAgo($this->creation_dtime, 'without')).
|
||||||
|
'</a></td><td>';
|
||||||
|
$submitter = $this->get_submitter();
|
||||||
|
$out .= sprintf(__('<a href="%1$s" title="View page">%2$s</a>, %3$s'), $url, Pluf_esc($this->title), Pluf_esc($this->summary)).'</td>';
|
||||||
|
$out .= "\n".'<tr class="extra"><td colspan="2">
|
||||||
|
<div class="helptext right">'.sprintf(__('Creation of <a href="%s">page %s</a>'), $url, Pluf_esc($this->title)).', '.__('by').' '.Pluf_esc($submitter).'</div></td></tr>';
|
||||||
|
return Pluf_Template::markSafe($out);
|
||||||
|
}
|
||||||
|
}
|
183
src/IDF/WikiRevision.php
Normal file
183
src/IDF/WikiRevision.php
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
<?php
|
||||||
|
/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||||
|
/*
|
||||||
|
# ***** BEGIN LICENSE BLOCK *****
|
||||||
|
# This file is part of InDefero, an open source project management application.
|
||||||
|
# Copyright (C) 2008 Céondo Ltd and contributors.
|
||||||
|
#
|
||||||
|
# InDefero is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# InDefero is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
#
|
||||||
|
# ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A revision of a wiki page.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class IDF_WikiRevision extends Pluf_Model
|
||||||
|
{
|
||||||
|
public $_model = __CLASS__;
|
||||||
|
|
||||||
|
function init()
|
||||||
|
{
|
||||||
|
$this->_a['table'] = 'idf_wikirevisions';
|
||||||
|
$this->_a['model'] = __CLASS__;
|
||||||
|
$this->_a['cols'] = array(
|
||||||
|
// It is mandatory to have an "id" column.
|
||||||
|
'id' =>
|
||||||
|
array(
|
||||||
|
'type' => 'Pluf_DB_Field_Sequence',
|
||||||
|
'blank' => true,
|
||||||
|
),
|
||||||
|
'wikipage' =>
|
||||||
|
array(
|
||||||
|
'type' => 'Pluf_DB_Field_Foreignkey',
|
||||||
|
'model' => 'IDF_WikiPage',
|
||||||
|
'blank' => false,
|
||||||
|
'verbose' => __('page'),
|
||||||
|
'relate_name' => 'revisions',
|
||||||
|
),
|
||||||
|
'is_head' =>
|
||||||
|
array(
|
||||||
|
'type' => 'Pluf_DB_Field_Boolean',
|
||||||
|
'blank' => false,
|
||||||
|
'default' => false,
|
||||||
|
'help_text' => 'If this revision is the latest, we mark it as being the head revision.',
|
||||||
|
'index' => true,
|
||||||
|
|
||||||
|
),
|
||||||
|
'summary' =>
|
||||||
|
array(
|
||||||
|
'type' => 'Pluf_DB_Field_Varchar',
|
||||||
|
'blank' => false,
|
||||||
|
'size' => 250,
|
||||||
|
'verbose' => __('summary'),
|
||||||
|
'help_text' => __('A one line description of the changes.'),
|
||||||
|
),
|
||||||
|
'content' =>
|
||||||
|
array(
|
||||||
|
'type' => 'Pluf_DB_Field_Compressed',
|
||||||
|
'blank' => false,
|
||||||
|
'verbose' => __('content'),
|
||||||
|
),
|
||||||
|
'submitter' =>
|
||||||
|
array(
|
||||||
|
'type' => 'Pluf_DB_Field_Foreignkey',
|
||||||
|
'model' => 'Pluf_User',
|
||||||
|
'blank' => false,
|
||||||
|
'verbose' => __('submitter'),
|
||||||
|
),
|
||||||
|
'changes' =>
|
||||||
|
array(
|
||||||
|
'type' => 'Pluf_DB_Field_Serialized',
|
||||||
|
'blank' => true,
|
||||||
|
'verbose' => __('changes'),
|
||||||
|
'help_text' => 'Serialized array of the changes in the issue.',
|
||||||
|
),
|
||||||
|
'creation_dtime' =>
|
||||||
|
array(
|
||||||
|
'type' => 'Pluf_DB_Field_Datetime',
|
||||||
|
'blank' => true,
|
||||||
|
'verbose' => __('creation date'),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
$this->_a['idx'] = array(
|
||||||
|
'creation_dtime_idx' =>
|
||||||
|
array(
|
||||||
|
'col' => 'creation_dtime',
|
||||||
|
'type' => 'normal',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function changedRevision()
|
||||||
|
{
|
||||||
|
return (is_array($this->changes) and count($this->changes) > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
function _toIndex()
|
||||||
|
{
|
||||||
|
return $this->content;
|
||||||
|
}
|
||||||
|
|
||||||
|
function preSave($create=false)
|
||||||
|
{
|
||||||
|
if ($this->id == '') {
|
||||||
|
$this->creation_dtime = gmdate('Y-m-d H:i:s');
|
||||||
|
$this->is_head = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function postSave($create=false)
|
||||||
|
{
|
||||||
|
if ($create) {
|
||||||
|
// Check if more than one revision for this page. We do
|
||||||
|
// not want to insert the first revision in the timeline
|
||||||
|
// as the page itself is inserted. We do not insert on
|
||||||
|
// update as update is performed to change the is_head
|
||||||
|
// flag.
|
||||||
|
$sql = new Pluf_SQL('wikipage=%s', array($this->wikipage));
|
||||||
|
$rev = Pluf::factory('IDF_WikiRevision')->getList(array('filter'=>$sql->gen()));
|
||||||
|
if ($rev->count() > 1) {
|
||||||
|
IDF_Timeline::insert($this, $this->get_wikipage()->get_project(),
|
||||||
|
$this->get_submitter());
|
||||||
|
foreach ($rev as $r) {
|
||||||
|
if ($r->id != $this->id and $r->is_head) {
|
||||||
|
$r->is_head = false;
|
||||||
|
$r->update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$page = $this->get_wikipage();
|
||||||
|
$page->update(); // Will update the modification timestamp.
|
||||||
|
IDF_Search::index($page);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function timelineFragment($request)
|
||||||
|
{
|
||||||
|
$page = $this->get_wikipage();
|
||||||
|
$url = Pluf_HTTP_URL_urlForView('IDF_Views_Wiki::view',
|
||||||
|
array($request->project->shortname,
|
||||||
|
$page->title));
|
||||||
|
$out = "\n".'<tr class="log"><td><a href="'.$url.'">'.
|
||||||
|
Pluf_esc(Pluf_Template_dateAgo($this->creation_dtime, 'without')).
|
||||||
|
'</a></td><td>';
|
||||||
|
$submitter = $this->get_submitter();
|
||||||
|
$out .= sprintf(__('<a href="%1$s" title="View page">%2$s</a>, %3$s'), $url, Pluf_esc($page->title), Pluf_esc($this->summary));
|
||||||
|
//$out .= '<strong>'.__('Summary:').'</strong> '.Pluf_esc($this->summary).' ';
|
||||||
|
if ($this->changedRevision()) {
|
||||||
|
$out .= '<div class="issue-changes-timeline">';
|
||||||
|
foreach ($this->changes as $w => $v) {
|
||||||
|
$out .= '<strong>';
|
||||||
|
switch ($w) {
|
||||||
|
case 'lb':
|
||||||
|
$out .= __('Labels:'); break;
|
||||||
|
}
|
||||||
|
$out .= '</strong> ';
|
||||||
|
if ($w == 'lb') {
|
||||||
|
$out .= Pluf_esc(implode(', ', $v));
|
||||||
|
} else {
|
||||||
|
$out .= Pluf_esc($v);
|
||||||
|
}
|
||||||
|
$out .= ' ';
|
||||||
|
}
|
||||||
|
$out .= '</div>';
|
||||||
|
}
|
||||||
|
$out .= '</td></tr>';
|
||||||
|
$out .= "\n".'<tr class="extra"><td colspan="2">
|
||||||
|
<div class="helptext right">'.sprintf(__('Change of <a href="%s">%s</a>'), $url, Pluf_esc($page->title)).', '.__('by').' '.Pluf_esc($submitter).'</div></td></tr>';
|
||||||
|
return Pluf_Template::markSafe($out);
|
||||||
|
}
|
||||||
|
}
|
@ -161,10 +161,10 @@ $cfg['template_tags'] = array(
|
|||||||
'hotkey' => 'IDF_Template_HotKey',
|
'hotkey' => 'IDF_Template_HotKey',
|
||||||
'issuetext' => 'IDF_Template_IssueComment',
|
'issuetext' => 'IDF_Template_IssueComment',
|
||||||
'timeline' => 'IDF_Template_TimelineFragment',
|
'timeline' => 'IDF_Template_TimelineFragment',
|
||||||
|
'markdown' => 'IDF_Template_Markdown',
|
||||||
);
|
);
|
||||||
$cfg['template_modifiers'] = array(
|
$cfg['template_modifiers'] = array(
|
||||||
'size' => 'IDF_Views_Source_PrettySize',
|
'size' => 'IDF_Views_Source_PrettySize',
|
||||||
'markdown' => 'IDF_Template_Markdown_filter',
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// available languages
|
// available languages
|
||||||
|
@ -147,37 +147,37 @@ $ctl[] = array('regex' => '#^/p/([\-\w]+)/issues/attachment/(\d+)/(.*)$#',
|
|||||||
|
|
||||||
// ---------- SCM ----------------------------------------
|
// ---------- SCM ----------------------------------------
|
||||||
|
|
||||||
$ctl[] = array('regex' => '#^/p/([\-\w]+)/source/tree/(\w+)/$#',
|
$ctl[] = array('regex' => '#^/p/([\-\w]+)/source/tree/([\S^/]+)/$#',
|
||||||
'base' => $base,
|
'base' => $base,
|
||||||
'priority' => 4,
|
'priority' => 4,
|
||||||
'model' => 'IDF_Views_Source',
|
'model' => 'IDF_Views_Source',
|
||||||
'method' => 'treeBase');
|
'method' => 'treeBase');
|
||||||
|
|
||||||
$ctl[] = array('regex' => '#^/p/([\-\w]+)/source/tree/(\w+)/(.*)$#',
|
$ctl[] = array('regex' => '#^/p/([\-\w]+)/source/tree/([\S^/]+)/(.*)$#',
|
||||||
'base' => $base,
|
'base' => $base,
|
||||||
'priority' => 4,
|
'priority' => 4,
|
||||||
'model' => 'IDF_Views_Source',
|
'model' => 'IDF_Views_Source',
|
||||||
'method' => 'tree');
|
'method' => 'tree');
|
||||||
|
|
||||||
$ctl[] = array('regex' => '#^/p/([\-\w]+)/source/changes/(\w+)/$#',
|
$ctl[] = array('regex' => '#^/p/([\-\w]+)/source/changes/([\S^/]+)/$#',
|
||||||
'base' => $base,
|
'base' => $base,
|
||||||
'priority' => 4,
|
'priority' => 4,
|
||||||
'model' => 'IDF_Views_Source',
|
'model' => 'IDF_Views_Source',
|
||||||
'method' => 'changeLog');
|
'method' => 'changeLog');
|
||||||
|
|
||||||
$ctl[] = array('regex' => '#^/p/([\-\w]+)/source/commit/(\w+)/$#',
|
$ctl[] = array('regex' => '#^/p/([\-\w]+)/source/commit/([\S^/]+)/$#',
|
||||||
'base' => $base,
|
'base' => $base,
|
||||||
'priority' => 4,
|
'priority' => 4,
|
||||||
'model' => 'IDF_Views_Source',
|
'model' => 'IDF_Views_Source',
|
||||||
'method' => 'commit');
|
'method' => 'commit');
|
||||||
|
|
||||||
$ctl[] = array('regex' => '#^/p/([\-\w]+)/source/download/(\w+)/$#',
|
$ctl[] = array('regex' => '#^/p/([\-\w]+)/source/download/([\S^/]+)/$#',
|
||||||
'base' => $base,
|
'base' => $base,
|
||||||
'priority' => 4,
|
'priority' => 4,
|
||||||
'model' => 'IDF_Views_Source',
|
'model' => 'IDF_Views_Source',
|
||||||
'method' => 'download');
|
'method' => 'download');
|
||||||
|
|
||||||
$ctl[] = array('regex' => '#^/p/([\-\w]+)/source/file/(\w+)/(.*)$#',
|
$ctl[] = array('regex' => '#^/p/([\-\w]+)/source/file/([\S^/]+)/(.*)$#',
|
||||||
'base' => $base,
|
'base' => $base,
|
||||||
'priority' => 4,
|
'priority' => 4,
|
||||||
'model' => 'IDF_Views_Source',
|
'model' => 'IDF_Views_Source',
|
||||||
@ -195,6 +195,32 @@ $ctl[] = array('regex' => '#^/p/([\-\w]+)/source/changesrev/$#',
|
|||||||
'model' => 'IDF_Views_Source_Svn',
|
'model' => 'IDF_Views_Source_Svn',
|
||||||
'method' => 'changelogRev');
|
'method' => 'changelogRev');
|
||||||
|
|
||||||
|
// ---------- WIKI -----------------------------------------
|
||||||
|
|
||||||
|
$ctl[] = array('regex' => '#^/p/([\-\w]+)/doc/$#',
|
||||||
|
'base' => $base,
|
||||||
|
'priority' => 4,
|
||||||
|
'model' => 'IDF_Views_Wiki',
|
||||||
|
'method' => 'index');
|
||||||
|
|
||||||
|
$ctl[] = array('regex' => '#^/p/([\-\w]+)/doc/create/$#',
|
||||||
|
'base' => $base,
|
||||||
|
'priority' => 4,
|
||||||
|
'model' => 'IDF_Views_Wiki',
|
||||||
|
'method' => 'create');
|
||||||
|
|
||||||
|
$ctl[] = array('regex' => '#^/p/([\-\w]+)/doc/update/(.*)/$#',
|
||||||
|
'base' => $base,
|
||||||
|
'priority' => 4,
|
||||||
|
'model' => 'IDF_Views_Wiki',
|
||||||
|
'method' => 'update');
|
||||||
|
|
||||||
|
$ctl[] = array('regex' => '#^/p/([\-\w]+)/page/(.*)/$#',
|
||||||
|
'base' => $base,
|
||||||
|
'priority' => 4,
|
||||||
|
'model' => 'IDF_Views_Wiki',
|
||||||
|
'method' => 'view');
|
||||||
|
|
||||||
// ---------- Downloads ------------------------------------
|
// ---------- Downloads ------------------------------------
|
||||||
|
|
||||||
$ctl[] = array('regex' => '#^/p/([\-\w]+)/downloads/$#',
|
$ctl[] = array('regex' => '#^/p/([\-\w]+)/downloads/$#',
|
||||||
@ -254,6 +280,12 @@ $ctl[] = array('regex' => '#^/p/([\-\w]+)/admin/downloads/$#',
|
|||||||
'model' => 'IDF_Views_Project',
|
'model' => 'IDF_Views_Project',
|
||||||
'method' => 'adminDownloads');
|
'method' => 'adminDownloads');
|
||||||
|
|
||||||
|
$ctl[] = array('regex' => '#^/p/([\-\w]+)/admin/wiki/$#',
|
||||||
|
'base' => $base,
|
||||||
|
'priority' => 4,
|
||||||
|
'model' => 'IDF_Views_Project',
|
||||||
|
'method' => 'adminWiki');
|
||||||
|
|
||||||
$ctl[] = array('regex' => '#^/p/([\-\w]+)/admin/source/$#',
|
$ctl[] = array('regex' => '#^/p/([\-\w]+)/admin/source/$#',
|
||||||
'base' => $base,
|
'base' => $base,
|
||||||
'priority' => 4,
|
'priority' => 4,
|
||||||
|
@ -30,5 +30,8 @@ $m['IDF_IssueFile'] = array('relate_to' => array('IDF_IssueComment', 'Pluf_User'
|
|||||||
$m['IDF_Upload'] = array('relate_to' => array('IDF_Project', 'Pluf_User'),
|
$m['IDF_Upload'] = array('relate_to' => array('IDF_Project', 'Pluf_User'),
|
||||||
'relate_to_many' => array('IDF_Tag'));
|
'relate_to_many' => array('IDF_Tag'));
|
||||||
$m['IDF_Search_Occ'] = array('relate_to' => array('IDF_Project'),);
|
$m['IDF_Search_Occ'] = array('relate_to' => array('IDF_Project'),);
|
||||||
|
$m['IDF_WikiPage'] = array('relate_to' => array('IDF_Project', 'Pluf_User'),
|
||||||
|
'relate_to_many' => array('IDF_Tag', 'Pluf_User'));
|
||||||
|
$m['IDF_WikiRevision'] = array('relate_to' => array('IDF_WikiPage', 'Pluf_User'));
|
||||||
|
|
||||||
return $m;
|
return $m;
|
||||||
|
@ -3,8 +3,9 @@
|
|||||||
{block subtabs}
|
{block subtabs}
|
||||||
<div id="sub-tabs">
|
<div id="sub-tabs">
|
||||||
<a {if $inSummary}class="active" {/if}href="{url 'IDF_Views_Project::admin', array($project.shortname)}">{trans 'Project Summary'}</a> |
|
<a {if $inSummary}class="active" {/if}href="{url 'IDF_Views_Project::admin', array($project.shortname)}">{trans 'Project Summary'}</a> |
|
||||||
<a {if $inIssueTracking}class="active" {/if}href="{url 'IDF_Views_Project::adminIssues', array($project.shortname)}">{trans 'Issue Tracking'}</a> |
|
|
||||||
<a {if $inDownloads}class="active" {/if}href="{url 'IDF_Views_Project::adminDownloads', array($project.shortname)}">{trans 'Downloads'}</a> |
|
<a {if $inDownloads}class="active" {/if}href="{url 'IDF_Views_Project::adminDownloads', array($project.shortname)}">{trans 'Downloads'}</a> |
|
||||||
|
<a {if $inWiki}class="active" {/if}href="{url 'IDF_Views_Project::adminWiki', array($project.shortname)}">{trans 'Documentation'}</a> |
|
||||||
|
<a {if $inIssueTracking}class="active" {/if}href="{url 'IDF_Views_Project::adminIssues', array($project.shortname)}">{trans 'Issue Tracking'}</a> |
|
||||||
<a {if $inSource}class="active" {/if}href="{url 'IDF_Views_Project::adminSource', array($project.shortname)}">{trans 'Source'}</a> |
|
<a {if $inSource}class="active" {/if}href="{url 'IDF_Views_Project::adminSource', array($project.shortname)}">{trans 'Source'}</a> |
|
||||||
<a {if $inMembers}class="active" {/if}href="{url 'IDF_Views_Project::adminMembers', array($project.shortname)}">{trans 'Project Members'}</a> |
|
<a {if $inMembers}class="active" {/if}href="{url 'IDF_Views_Project::adminMembers', array($project.shortname)}">{trans 'Project Members'}</a> |
|
||||||
<a {if $inTabs}class="active" {/if}href="{url 'IDF_Views_Project::adminTabs', array($project.shortname)}">{trans 'Tabs Access'}</a>
|
<a {if $inTabs}class="active" {/if}href="{url 'IDF_Views_Project::adminTabs', array($project.shortname)}">{trans 'Tabs Access'}</a>
|
||||||
|
@ -18,6 +18,12 @@
|
|||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
<th><strong>{$form.f.wiki_access_rights.labelTag}:</strong></th>
|
||||||
|
<td>{if $form.f.wiki_access_rights.errors}{$form.f.wiki_access_rights.fieldErrors}{/if}
|
||||||
|
{$form.f.wiki_access_rights|unsafe}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
<th><strong>{$form.f.issues_access_rights.labelTag}:</strong></th>
|
<th><strong>{$form.f.issues_access_rights.labelTag}:</strong></th>
|
||||||
<td>{if $form.f.issues_access_rights.errors}{$form.f.issues_access_rights.fieldErrors}{/if}
|
<td>{if $form.f.issues_access_rights.errors}{$form.f.issues_access_rights.fieldErrors}{/if}
|
||||||
{$form.f.issues_access_rights|unsafe}
|
{$form.f.issues_access_rights|unsafe}
|
||||||
|
34
src/IDF/templates/idf/admin/wiki.html
Normal file
34
src/IDF/templates/idf/admin/wiki.html
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
{extends "idf/admin/base.html"}
|
||||||
|
{block docclass}yui-t1{assign $inWiki = true}{/block}
|
||||||
|
{block body}
|
||||||
|
<form method="post" action=".">
|
||||||
|
<table class="form" summary="">
|
||||||
|
<tr>
|
||||||
|
<td colspan="2"><strong>{$form.f.labels_wiki_predefined.labelTag}:</strong><br />
|
||||||
|
{if $form.f.labels_wiki_predefined.errors}{$form.f.labels_wiki_predefined.fieldErrors}{/if}
|
||||||
|
{$form.f.labels_wiki_predefined|unsafe}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">{$form.f.labels_wiki_one_max.labelTag}:<br />
|
||||||
|
{if $form.f.labels_wiki_one_max.errors}{$form.f.labels_wiki_one_max.fieldErrors}{/if}
|
||||||
|
{$form.f.labels_wiki_one_max|unsafe}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">
|
||||||
|
<input type="submit" value="{trans 'Save Changes'}" name="submit" />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</form>
|
||||||
|
{/block}
|
||||||
|
{block context}
|
||||||
|
<div class="issue-submit-info">
|
||||||
|
{blocktrans}
|
||||||
|
<p><strong>Instructions:</strong></p>
|
||||||
|
<p>List one status value per line in desired sort-order.</p>
|
||||||
|
<p>Optionally, use an equals-sign to document the meaning of each status value.</p>
|
||||||
|
{/blocktrans}
|
||||||
|
</div>
|
||||||
|
{/block}
|
@ -43,8 +43,9 @@
|
|||||||
<div id="main-tabs">
|
<div id="main-tabs">
|
||||||
{if $project}
|
{if $project}
|
||||||
<a accesskey="1" href="{url 'IDF_Views_Project::home', array($project.shortname)}"{block tabhome}{/block}>{trans 'Project Home'}</a>
|
<a accesskey="1" href="{url 'IDF_Views_Project::home', array($project.shortname)}"{block tabhome}{/block}>{trans 'Project Home'}</a>
|
||||||
{if $hasIssuesAccess} <a href="{url 'IDF_Views_Issue::index', array($project.shortname)}"{block tabissues}{/block}>{trans 'Issues'}</a>{/if}
|
|
||||||
{if $hasDownloadsAccess} <a href="{url 'IDF_Views_Download::index', array($project.shortname)}"{block tabdownloads}{/block}>{trans 'Downloads'}</a>{/if}
|
{if $hasDownloadsAccess} <a href="{url 'IDF_Views_Download::index', array($project.shortname)}"{block tabdownloads}{/block}>{trans 'Downloads'}</a>{/if}
|
||||||
|
{if $hasWikiAccess} <a href="{url 'IDF_Views_Wiki::index', array($project.shortname)}"{block tabwiki}{/block}>{trans 'Documentation'}</a>{/if}
|
||||||
|
{if $hasIssuesAccess} <a href="{url 'IDF_Views_Issue::index', array($project.shortname)}"{block tabissues}{/block}>{trans 'Issues'}</a>{/if}
|
||||||
{if $hasSourceAccess} <a href="{url 'IDF_Views_Source::treeBase', array($project.shortname, $project.getScmRoot())}"{block tabsource}{/block}>{trans 'Source'}</a>{/if}
|
{if $hasSourceAccess} <a href="{url 'IDF_Views_Source::treeBase', array($project.shortname, $project.getScmRoot())}"{block tabsource}{/block}>{trans 'Source'}</a>{/if}
|
||||||
{if $isOwner}
|
{if $isOwner}
|
||||||
<a href="{url 'IDF_Views_Project::admin', array($project.shortname)}"{block tabadmin}{/block}>{trans 'Administer'}</a>{/if}{/if}
|
<a href="{url 'IDF_Views_Project::admin', array($project.shortname)}"{block tabadmin}{/block}>{trans 'Administer'}</a>{/if}{/if}
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
</div>
|
</div>
|
||||||
{/block}
|
{/block}
|
||||||
{block body}
|
{block body}
|
||||||
{$project.description|markdown}
|
{markdown $project.description, $request}
|
||||||
{/block}
|
{/block}
|
||||||
{block context}
|
{block context}
|
||||||
{if count($downloads) > 0}
|
{if count($downloads) > 0}
|
||||||
|
10
src/IDF/templates/idf/wiki/base.html
Normal file
10
src/IDF/templates/idf/wiki/base.html
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
{extends "idf/base.html"}
|
||||||
|
{block tabwiki} class="active"{/block}
|
||||||
|
{block subtabs}
|
||||||
|
<div id="sub-tabs">
|
||||||
|
<a {if $inWiki}class="active" {/if}href="{url 'IDF_Views_Wiki::index', array($project.shortname)}">{trans 'List Pages'}</a>
|
||||||
|
{if !$user.isAnonymous()} | <a {if $inCreate}class="active" {/if}href="{url 'IDF_Views_Wiki::create', array($project.shortname)}">{trans 'New Page'}</a> {/if}
|
||||||
|
{if !$user.isAnonymous() and $inView} | <a href="{url 'IDF_Views_Wiki::update', array($project.shortname, $page.title)}">{trans 'Update This Page'}</a> {/if}
|
||||||
|
{superblock}
|
||||||
|
</div>
|
||||||
|
{/block}
|
68
src/IDF/templates/idf/wiki/create.html
Normal file
68
src/IDF/templates/idf/wiki/create.html
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
{extends "idf/wiki/base.html"}
|
||||||
|
{block docclass}yui-t1{assign $inCreate = true}{/block}
|
||||||
|
{block body}
|
||||||
|
|
||||||
|
{if $preview}
|
||||||
|
<h2 class="top">{trans 'Preview of the Page'}</h2>
|
||||||
|
|
||||||
|
{markdown $preview, $request}
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{if $form.errors}
|
||||||
|
<div class="px-message-error">
|
||||||
|
<p>{trans 'The form contains some errors. Please correct them to create the page.'}</p>
|
||||||
|
{if $form.get_top_errors}
|
||||||
|
{$form.render_top_errors|unsafe}
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<form method="post" enctype="multipart/form-data" action="." >
|
||||||
|
<table class="form" summary="">
|
||||||
|
<tr>
|
||||||
|
<th><strong>{$form.f.title.labelTag}:</strong></th>
|
||||||
|
<td>{if $form.f.title.errors}{$form.f.title.fieldErrors}{/if}
|
||||||
|
{$form.f.title|unsafe}<br />
|
||||||
|
<span class="helptext">{$form.f.title.help_text}</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th><strong>{$form.f.summary.labelTag}:</strong></th>
|
||||||
|
<td>{if $form.f.summary.errors}{$form.f.summary.fieldErrors}{/if}
|
||||||
|
{$form.f.summary|unsafe}<br />
|
||||||
|
<span class="helptext">{$form.f.summary.help_text}</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th><strong>{$form.f.content.labelTag}:</strong></th>
|
||||||
|
<td>{if $form.f.content.errors}{$form.f.content.fieldErrors}{/if}
|
||||||
|
{$form.f.content|unsafe}
|
||||||
|
</td>
|
||||||
|
</tr>{if $isOwner or $isMember}
|
||||||
|
<tr>
|
||||||
|
<th>{$form.f.label1.labelTag}:</th>
|
||||||
|
<td>
|
||||||
|
{if $form.f.label1.errors}{$form.f.label1.fieldErrors}{/if}{$form.f.label1|unsafe}
|
||||||
|
{if $form.f.label2.errors}{$form.f.label2.fieldErrors}{/if}{$form.f.label2|unsafe}
|
||||||
|
{if $form.f.label3.errors}{$form.f.label3.fieldErrors}{/if}{$form.f.label3|unsafe}
|
||||||
|
</td>
|
||||||
|
</tr>{/if}
|
||||||
|
<tr>
|
||||||
|
<td> </td>
|
||||||
|
<td><input type="submit" value="{trans 'Preview'}" name="preview" /> <input type="submit" value="{trans 'Create Page'}" name="submit" /> | <a href="{url 'IDF_Views_Wiki::index', array($project.shortname)}">{trans 'Cancel'}</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</form>
|
||||||
|
{/block}
|
||||||
|
{block context}
|
||||||
|
<div class="issue-submit-info">
|
||||||
|
{include 'idf/wiki/edit-info.html'}
|
||||||
|
</div>
|
||||||
|
{/block}
|
||||||
|
{block javascript}
|
||||||
|
<script type="text/javascript">
|
||||||
|
document.getElementById('id_title').focus()
|
||||||
|
</script>
|
||||||
|
{include 'idf/wiki/js-autocomplete.html'}{/block}
|
||||||
|
|
6
src/IDF/templates/idf/wiki/edit-info.html
Normal file
6
src/IDF/templates/idf/wiki/edit-info.html
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{assign $url = 'http://daringfireball.net/projects/markdown/syntax'}
|
||||||
|
{blocktrans}
|
||||||
|
<p><strong>Instructions:</strong></p>
|
||||||
|
<p>The content of the page can use the <a href="{$url}">Markdown syntax</a>.</p>
|
||||||
|
<p>Website addresses are automatically linked and you can link to another page in the documentation using double square brackets like that [[AnotherPage]].</p>
|
||||||
|
{/blocktrans}
|
13
src/IDF/templates/idf/wiki/index.html
Normal file
13
src/IDF/templates/idf/wiki/index.html
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
{extends "idf/wiki/base.html"}
|
||||||
|
{block docclass}yui-t1{assign $inWiki=true}{/block}
|
||||||
|
{block body}
|
||||||
|
{$pages.render}
|
||||||
|
{if !$user.isAnonymous()}
|
||||||
|
{aurl 'url', 'IDF_Views_Wiki::create', array($project.shortname)}
|
||||||
|
<p><a href="{$url}"><img style="vertical-align: text-bottom;" src="{media '/idf/img/add.png'}" alt="+" align="bottom" /></a> <a href="{$url}">{trans 'New Page'}</a></p>{/if}
|
||||||
|
|
||||||
|
{/block}
|
||||||
|
{block context}
|
||||||
|
<p><strong>{trans 'Number of pages:'}</strong> {$pages.nb_items}</p>
|
||||||
|
{/block}
|
||||||
|
|
27
src/IDF/templates/idf/wiki/js-autocomplete.html
Normal file
27
src/IDF/templates/idf/wiki/js-autocomplete.html
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
{if $isOwner or $isMember}
|
||||||
|
<script type="text/javascript" src="{media '/idf/js/jquery.bgiframe.min.js'}"></script>
|
||||||
|
<script type="text/javascript" src="{media '/idf/js/jquery.autocomplete.min.js'}"></script>
|
||||||
|
<script type="text/javascript" charset="utf-8">
|
||||||
|
// <!-- {literal}
|
||||||
|
$(document).ready(function(){
|
||||||
|
var auto_labels = [{/literal}{$auto_labels|safe}{literal}];
|
||||||
|
var j=0;
|
||||||
|
for (j=1;j<4;j=j+1) {
|
||||||
|
$("#id_label"+j).autocomplete(auto_labels, {
|
||||||
|
minChars: 0,
|
||||||
|
width: 310,
|
||||||
|
matchContains: true,
|
||||||
|
max: 50,
|
||||||
|
highlightItem: false,
|
||||||
|
formatItem: function(row, i, max, term) {
|
||||||
|
return row.to.replace(new RegExp("(" + term + ")", "gi"), "<strong>$1</strong>") + " <span style='font-size: 80%;'>" + row.name + "</span>";
|
||||||
|
},
|
||||||
|
formatResult: function(row) {
|
||||||
|
return row.to;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
{/literal} //-->
|
||||||
|
</script>
|
||||||
|
{/if}
|
72
src/IDF/templates/idf/wiki/update.html
Normal file
72
src/IDF/templates/idf/wiki/update.html
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
{extends "idf/wiki/base.html"}
|
||||||
|
{block docclass}yui-t2{/block}
|
||||||
|
{block body}
|
||||||
|
|
||||||
|
{if $preview}
|
||||||
|
<h2 class="top">{trans 'Preview of the Page'}</h2>
|
||||||
|
|
||||||
|
{markdown $preview, $request}
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{if $form.errors}
|
||||||
|
<div class="px-message-error">
|
||||||
|
<p>{trans 'The form contains some errors. Please correct them to update the page.'}</p>
|
||||||
|
{if $form.get_top_errors}
|
||||||
|
{$form.render_top_errors|unsafe}
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<form method="post" enctype="multipart/form-data" action="." >
|
||||||
|
<table class="form" summary="">{if $isOwner or $isMember}
|
||||||
|
<tr>
|
||||||
|
<th><strong>{$form.f.title.labelTag}:</strong></th>
|
||||||
|
<td>{if $form.f.title.errors}{$form.f.title.fieldErrors}{/if}
|
||||||
|
{$form.f.title|unsafe}<br />
|
||||||
|
<span class="helptext">{$form.f.title.help_text}</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th><strong>{$form.f.summary.labelTag}:</strong></th>
|
||||||
|
<td>{if $form.f.summary.errors}{$form.f.summary.fieldErrors}{/if}
|
||||||
|
{$form.f.summary|unsafe}<br />
|
||||||
|
<span class="helptext">{$form.f.summary.help_text}</span>
|
||||||
|
</td>
|
||||||
|
</tr>{/if}
|
||||||
|
<tr>
|
||||||
|
<th><strong>{$form.f.content.labelTag}:</strong></th>
|
||||||
|
<td>{if $form.f.content.errors}{$form.f.content.fieldErrors}{/if}
|
||||||
|
{$form.f.content|unsafe}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th><strong>{$form.f.comment.labelTag}:</strong></th>
|
||||||
|
<td>{if $form.f.comment.errors}{$form.f.comment.fieldErrors}{/if}
|
||||||
|
{$form.f.comment|unsafe}<br />
|
||||||
|
<span class="helptext">{$form.f.comment.help_text}</span>
|
||||||
|
</td>
|
||||||
|
</tr>{if $isOwner or $isMember}
|
||||||
|
<tr>
|
||||||
|
<th>{$form.f.label1.labelTag}:</th>
|
||||||
|
<td>
|
||||||
|
{if $form.f.label1.errors}{$form.f.label1.fieldErrors}{/if}{$form.f.label1|unsafe}
|
||||||
|
{if $form.f.label2.errors}{$form.f.label2.fieldErrors}{/if}{$form.f.label2|unsafe}
|
||||||
|
{if $form.f.label3.errors}{$form.f.label3.fieldErrors}{/if}{$form.f.label3|unsafe}
|
||||||
|
</td>
|
||||||
|
</tr>{/if}
|
||||||
|
<tr>
|
||||||
|
<td> </td>
|
||||||
|
<td><input type="submit" value="{trans 'Preview'}" name="preview" /> <input type="submit" value="{trans 'Update Page'}" name="submit" /> | <a href="{url 'IDF_Views_Wiki::index', array($project.shortname)}">{trans 'Cancel'}</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</form>
|
||||||
|
{/block}
|
||||||
|
{block context}
|
||||||
|
<div class="issue-submit-info">
|
||||||
|
{include 'idf/wiki/edit-info.html'}
|
||||||
|
</div>
|
||||||
|
{/block}
|
||||||
|
{block javascript}
|
||||||
|
{include 'idf/wiki/js-autocomplete.html'}{/block}
|
||||||
|
|
22
src/IDF/templates/idf/wiki/view.html
Normal file
22
src/IDF/templates/idf/wiki/view.html
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
{extends "idf/wiki/base.html"}
|
||||||
|
{block docclass}yui-t3{assign $inView=true}{/block}
|
||||||
|
{block body}
|
||||||
|
|
||||||
|
<p class="desc">{$page.summary}</p>
|
||||||
|
|
||||||
|
{markdown $rev.content, $request}
|
||||||
|
|
||||||
|
{/block}
|
||||||
|
{block context}
|
||||||
|
{assign $submitter = $page.get_submitter()}
|
||||||
|
<p><strong>{trans 'Created:'}</strong> <span class="nobrk">{$page.creation_dtime|dateago}</span><br /><span class="nobrk">{blocktrans}by {$submitter}{/blocktrans}</span></p>
|
||||||
|
{if $rev.creation_dtime != $page.creation_dtime}<p>{assign $submitter = $rev.get_submitter()}
|
||||||
|
<strong>{trans 'Updated:'}</strong> <span class="nobrk">{$rev.creation_dtime|dateago}</span><br /><span class="nobrk">{blocktrans}by {$submitter}{/blocktrans}</span></p>{/if}
|
||||||
|
{if $tags.count()}
|
||||||
|
<p>
|
||||||
|
<strong>{trans 'Labels:'}</strong><br />
|
||||||
|
{foreach $tags as $tag}
|
||||||
|
<span class="label"><strong>{$tag.class}:</strong>{$tag.name}</span><br />
|
||||||
|
{/foreach}
|
||||||
|
</p>{/if}
|
||||||
|
{/block}
|
@ -578,3 +578,14 @@ div.download-file {
|
|||||||
-moz-border-radius: 5px;
|
-moz-border-radius: 5px;
|
||||||
-webkit-border-radius: 5px;
|
-webkit-border-radius: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wiki
|
||||||
|
*/
|
||||||
|
p.desc {
|
||||||
|
background-color: #eeeeec;
|
||||||
|
-moz-border-radius: 3px;
|
||||||
|
-webkit-border-radius: 3px;
|
||||||
|
padding: 4px;
|
||||||
|
width: 60%;
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user