diff --git a/htdocs/core/actions_comments.inc.php b/htdocs/core/actions_comments.inc.php
new file mode 100644
index 00000000000..185973cb258
--- /dev/null
+++ b/htdocs/core/actions_comments.inc.php
@@ -0,0 +1,76 @@
+
+ *
+ * This program 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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, see .
+ * or see http://www.gnu.org/
+ *
+ * $elementype must be defined.
+ */
+
+/**
+ * \file htdocs/core/actions_comments.inc.php
+ * \brief Code for actions on comments pages
+ */
+
+
+require_once DOL_DOCUMENT_ROOT.'/core/class/comment.class.php';
+
+$varpage=empty($contextpage)?$_SERVER["PHP_SELF"]:$contextpage;
+$comment = new Comment($db);
+
+/*
+ * Actions
+ */
+
+if ($action == 'addcomment')
+{
+ $description = GETPOST('comment_description');
+ if (!empty($description))
+ {
+ $comment->description = $description;
+ $comment->datec = time();
+ $comment->fk_element = GETPOST('id');
+ $comment->element_type = GETPOST('comment_element_type');
+ $comment->fk_user_author = $user->id;
+ $comment->entity = $conf->entity;
+ if ($comment->create($user) > 0)
+ {
+ setEventMessages($langs->trans("CommentAdded"), null, 'mesgs');
+ header('Location: '.$varpage.'?id='.$id.($withproject?'&withproject=1':''));
+ exit;
+ }
+ else
+ {
+ setEventMessages($comment->error, $comment->errors,'errors');
+ $action='';
+ }
+ }
+}
+if ($action == 'deletecomment')
+{
+ if ($comment->fetch($idcomment) >= 0)
+ {
+ if ($comment->delete($user) > 0)
+ {
+ setEventMessages($langs->trans("CommentDeleted"), null, 'mesgs');
+ header('Location: '.$varpage.'?id='.$id.($withproject?'&withproject=1':''));
+ exit;
+ }
+ else
+ {
+ setEventMessages($comment->error, $comment->errors,'errors');
+ $action='';
+ }
+ }
+}
\ No newline at end of file
diff --git a/htdocs/core/class/comment.class.php b/htdocs/core/class/comment.class.php
new file mode 100644
index 00000000000..0ec77405721
--- /dev/null
+++ b/htdocs/core/class/comment.class.php
@@ -0,0 +1,322 @@
+db = $db;
+ }
+
+
+ /**
+ * Create into database
+ *
+ * @param User $user User that create
+ * @param int $notrigger 0=launch triggers after, 1=disable triggers
+ * @return int <0 if KO, Id of created object if OK
+ */
+ function create($user, $notrigger=0)
+ {
+ global $conf, $langs;
+
+ $error=0;
+
+ // Insert request
+ $sql = "INSERT INTO ".MAIN_DB_PREFIX."comment (";
+ $sql.= "description";
+ $sql.= ", datec";
+ $sql.= ", fk_element";
+ $sql.= ", element_type";
+ $sql.= ", fk_user_author";
+ $sql.= ", entity";
+ $sql.= ", import_key";
+ $sql.= ") VALUES (";
+ $sql.= "'".$this->db->escape($this->description)."'";
+ $sql.= ", ".($this->datec!=''?"'".$this->db->idate($this->datec)."'":'null');
+ $sql.= ", '".(isset($this->fk_element)?$this->fk_element:"null")."'";
+ $sql.= ", '".$this->db->escape($this->element_type)."'";
+ $sql.= ", '".(isset($this->fk_user_author)?$this->fk_user_author:"null")."'";
+ $sql.= ", ".(!empty($this->entity)?$this->entity:'1');
+ $sql.= ", ".(!empty($this->import_key)?"'".$this->db->escape($this->import_key)."'":"null");
+ $sql.= ")";
+
+ //var_dump($this->db);
+ //echo $sql;
+
+ $this->db->begin();
+
+ dol_syslog(get_class($this)."::create", LOG_DEBUG);
+ $resql=$this->db->query($sql);
+ if (! $resql) { $error++; $this->errors[]="Error ".$this->db->lasterror(); }
+
+ if (! $error)
+ {
+ $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."projet_task_comment");
+
+ if (! $notrigger)
+ {
+ // Call trigger
+ $result=$this->call_trigger('TASK_COMMENT_CREATE',$user);
+ if ($result < 0) { $error++; }
+ // End call triggers
+ }
+ }
+
+ // Commit or rollback
+ if ($error)
+ {
+ foreach($this->errors as $errmsg)
+ {
+ dol_syslog(get_class($this)."::create ".$errmsg, LOG_ERR);
+ $this->error.=($this->error?', '.$errmsg:$errmsg);
+ }
+ $this->db->rollback();
+ return -1*$error;
+ }
+ else
+ {
+ $this->db->commit();
+ return $this->id;
+ }
+ }
+
+
+ /**
+ * Load object in memory from database
+ *
+ * @param int $id Id object
+ * @param int $ref ref object
+ * @return int <0 if KO, 0 if not found, >0 if OK
+ */
+ function fetch($id, $ref='')
+ {
+ global $langs;
+
+ $sql = "SELECT";
+ $sql.= " c.rowid,";
+ $sql.= " c.description,";
+ $sql.= " c.datec,";
+ $sql.= " c.tms,";
+ $sql.= " c.fk_element,";
+ $sql.= " c.element_type,";
+ $sql.= " c.fk_user_author,";
+ $sql.= " c.entity,";
+ $sql.= " c.import_key";
+ $sql.= " FROM ".MAIN_DB_PREFIX."comment as c";
+ $sql.= " WHERE c.rowid = ".$id;
+
+ dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
+ $resql=$this->db->query($sql);
+ if ($resql)
+ {
+ $num_rows = $this->db->num_rows($resql);
+
+ if ($num_rows)
+ {
+ $obj = $this->db->fetch_object($resql);
+
+ $this->id = $obj->rowid;
+ $this->description = $obj->description;
+ $this->element_type = $obj->element_type;
+ $this->datec = $this->db->jdate($obj->datec);
+ $this->tms = $obj->tms;
+ $this->fk_user_author = $obj->fk_user_author;
+ $this->fk_element = $obj->fk_element;
+ $this->entity = $obj->entity;
+ $this->import_key = $obj->import_key;
+ }
+
+ $this->db->free($resql);
+
+ if ($num_rows) return 1;
+ else return 0;
+ }
+ else
+ {
+ $this->error="Error ".$this->db->lasterror();
+ return -1;
+ }
+ }
+
+
+ /**
+ * Update database
+ *
+ * @param User $user User that modify
+ * @param int $notrigger 0=launch triggers after, 1=disable triggers
+ * @return int <=0 if KO, >0 if OK
+ */
+ function update(User $user, $notrigger=0)
+ {
+ global $conf, $langs;
+ $error=0;
+
+ // Clean parameters
+ if (isset($this->fk_element)) $this->fk_project=(int) trim($this->fk_element);
+ if (isset($this->fk_user_author)) $this->fk_user_author=(int) trim($this->fk_user_author);
+ if (isset($this->description)) $this->description=trim($this->description);
+
+
+ // Update request
+ $sql = "UPDATE ".MAIN_DB_PREFIX."projet_task_comment SET";
+ $sql.= " description=".(isset($this->description)?"'".$this->db->escape($this->description)."'":"null").",";
+ $sql.= " datec=".($this->datec!=''?"'".$this->db->idate($this->datec)."'":'null').",";
+ $sql.= " fk_element=".(isset($this->fk_element)?$this->fk_element:"null").",";
+ $sql.= " element_type='".$this->element_type."',";
+ $sql.= " fk_user_author=".(isset($this->fk_user_author)?$this->fk_user_author:"null").",";
+ $sql.= " entity=".(!empty($this->entity)?$this->entity:'1').",";
+ $sql.= " import_key=".(!empty($this->import_key)?"'".$this->db->escape($this->import_key)."'":"null");
+ $sql.= " WHERE rowid=".$this->id;
+
+ $this->db->begin();
+
+ dol_syslog(get_class($this)."::update", LOG_DEBUG);
+ $resql = $this->db->query($sql);
+ if (! $resql) { $error++; $this->errors[]="Error ".$this->db->lasterror(); }
+
+ if (! $error)
+ {
+ if (! $notrigger)
+ {
+ // Call trigger
+ $result=$this->call_trigger('TASK_COMMENT_MODIFY',$user);
+ if ($result < 0) { $error++; }
+ // End call triggers
+ }
+ }
+
+ // Commit or rollback
+ if ($error)
+ {
+ foreach($this->errors as $errmsg)
+ {
+ dol_syslog(get_class($this)."::update ".$errmsg, LOG_ERR);
+ $this->error.=($this->error?', '.$errmsg:$errmsg);
+ }
+ $this->db->rollback();
+ return -1*$error;
+ }
+ else
+ {
+ $this->db->commit();
+ return 1;
+ }
+ }
+
+
+ /**
+ * Delete task from database
+ *
+ * @param User $user User that delete
+ * @param int $notrigger 0=launch triggers after, 1=disable triggers
+ * @return int <0 if KO, >0 if OK
+ */
+ function delete($user, $notrigger=0)
+ {
+ global $conf, $langs;
+ require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php';
+
+ $error=0;
+
+ $this->db->begin();
+
+ $sql = "DELETE FROM ".MAIN_DB_PREFIX."comment";
+ $sql.= " WHERE rowid=".$this->id;
+
+ $resql = $this->db->query($sql);
+ if (! $resql) { $error++; $this->errors[]="Error ".$this->db->lasterror(); }
+
+ if (! $error)
+ {
+ if (! $notrigger)
+ {
+ // Call trigger
+ $result=$this->call_trigger('TASK_COMMENT_DELETE',$user);
+ if ($result < 0) { $error++; }
+ // End call triggers
+ }
+ }
+
+ // Commit or rollback
+ if ($error)
+ {
+ foreach($this->errors as $errmsg)
+ {
+ dol_syslog(get_class($this)."::delete ".$errmsg, LOG_ERR);
+ $this->error.=($this->error?', '.$errmsg:$errmsg);
+ }
+ $this->db->rollback();
+ return -1*$error;
+ }else{
+ $this->db->commit();
+ return 1;
+ }
+ }
+
+
+ /**
+ * Load comments linked with current task
+ *
+ * @return array Comment array
+ */
+ public static function fetchAllFor($element_type, $fk_element)
+ {
+ global $db,$conf;
+ $TComments = array();
+ if(!empty($element_type) && !empty($fk_element)) {
+ $sql = "SELECT";
+ $sql.= " c.rowid";
+ $sql.= " FROM ".MAIN_DB_PREFIX."comment as c";
+ $sql.= " WHERE c.fk_element = ".$fk_element;
+ $sql.= " AND c.element_type = '".$element_type."'";
+ $sql.= " AND c.entity = ".$conf->entity;
+ $sql.= " ORDER BY c.tms DESC";
+
+ dol_syslog("Comment::fetchAllFor", LOG_DEBUG);
+ $resql=$db->query($sql);
+ if ($resql)
+ {
+ $num_rows = $db->num_rows($resql);
+ if ($num_rows > 0)
+ {
+ while($obj = $db->fetch_object($resql))
+ {
+ $comment = new self($db);
+ $comment->fetch($obj->rowid);
+ $TComments[] = $comment;
+ }
+ }
+ $db->free($resql);
+ }
+ }
+ return $TComments;
+ }
+}
\ No newline at end of file
diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php
index ac2c1482682..b8f80c23c15 100644
--- a/htdocs/core/class/commonobject.class.php
+++ b/htdocs/core/class/commonobject.class.php
@@ -308,6 +308,12 @@ abstract class CommonObject
* @var CommonObjectLine[]
*/
public $lines;
+
+ /**
+ * @var mixed Contains comments
+ * @see fetchComments()
+ */
+ public $comments=array();
/**
* @var int
@@ -5288,5 +5294,28 @@ abstract class CommonObject
// TODO...
}
+
+ /**
+ * Load comments linked with current task
+ * @return boolean 1 if ok
+ */
+ public function fetchComments()
+ {
+ require_once DOL_DOCUMENT_ROOT.'/core/class/comment.class.php';
+
+ $comment = new Comment($this->db);
+ $this->comments = Comment::fetchAllFor($this->element, $this->id);
+ return 1;
+ }
+
+ /**
+ * Return nb comments already posted
+ *
+ * @return int
+ */
+ public function getNbComments()
+ {
+ return count($this->comments);
+ }
}
diff --git a/htdocs/core/lib/project.lib.php b/htdocs/core/lib/project.lib.php
index af49fa6b27d..7f809fadd77 100644
--- a/htdocs/core/lib/project.lib.php
+++ b/htdocs/core/lib/project.lib.php
@@ -66,7 +66,19 @@ function project_prepare_head($object)
// $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__'); to add new tab
// $this->tabs = array('entity:-tabname); to remove a tab
complete_head_from_modules($conf,$langs,$object,$head,$h,'project');
-
+
+
+ // Manage discussion
+ if (!empty($conf->global->PROJECT_ALLOW_COMMENT_ON_PROJECT))
+ {
+ $nbComments = $object->getNbComments();
+ $head[$h][0] = DOL_URL_ROOT.'/projet/comment.php?id='.$object->id;
+ $head[$h][1] = $langs->trans("CommentLink");
+ if ($nbComments > 0) $head[$h][1].= ' '.$nbComments.'';
+ $head[$h][2] = 'project_comment';
+ $h++;
+ }
+
if (empty($conf->global->MAIN_DISABLE_NOTES_TAB))
{
$nbNote = 0;
@@ -179,9 +191,9 @@ function task_prepare_head($object)
// Manage discussion
if (!empty($conf->global->PROJECT_ALLOW_COMMENT_ON_TASK))
{
- $nbComments= $object->getNbComments();
+ $nbComments = $object->getNbComments();
$head[$h][0] = DOL_URL_ROOT.'/projet/tasks/comment.php?id='.$object->id.(GETPOST('withproject')?'&withproject=1':'');
- $head[$h][1] = $langs->trans("TaskCommentLinks");
+ $head[$h][1] = $langs->trans("CommentLink");
if ($nbComments > 0) $head[$h][1].= ' '.$nbComments.'';
$head[$h][2] = 'task_comment';
$h++;
diff --git a/htdocs/core/tpl/bloc_comment.tpl.php b/htdocs/core/tpl/bloc_comment.tpl.php
new file mode 100644
index 00000000000..b28699744d2
--- /dev/null
+++ b/htdocs/core/tpl/bloc_comment.tpl.php
@@ -0,0 +1,105 @@
+';
+print '
';
diff --git a/htdocs/install/mysql/migration/6.0.0-7.0.0.sql b/htdocs/install/mysql/migration/6.0.0-7.0.0.sql
index ff9f4e0a2f8..fb9e5f8749f 100644
--- a/htdocs/install/mysql/migration/6.0.0-7.0.0.sql
+++ b/htdocs/install/mysql/migration/6.0.0-7.0.0.sql
@@ -302,14 +302,15 @@ insert into llx_c_action_trigger (code,label,description,elementtype,rang) value
insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROPOSAL_SUPPLIER_CLOSE_SIGNED','Price request closed signed','Executed when a customer proposal is closed signed','proposal_supplier',10);
insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROPOSAL_SUPPLIER_CLOSE_REFUSED','Price request closed refused','Executed when a customer proposal is closed refused','proposal_supplier',10);
-
-CREATE TABLE llx_projet_task_comment (
+DROP TABLE `llx_projet_task_comment`;
+CREATE TABLE IF NOT EXISTS llx_comment (
rowid integer AUTO_INCREMENT PRIMARY KEY,
datec datetime DEFAULT NULL,
tms timestamp,
description text NOT NULL,
- fk_user integer DEFAULT NULL,
- fk_task integer DEFAULT NULL,
+ fk_user_author integer DEFAULT NULL,
+ fk_element integer DEFAULT NULL,
+ element_type varchar(50) DEFAULT NULL,
entity integer DEFAULT 1,
import_key varchar(125) DEFAULT NULL
)ENGINE=innodb;
diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang
index bfcbb5a2010..fbbd8dbaabd 100644
--- a/htdocs/langs/en_US/main.lang
+++ b/htdocs/langs/en_US/main.lang
@@ -873,3 +873,8 @@ SearchIntoContracts=Contracts
SearchIntoCustomerShipments=Customer shipments
SearchIntoExpenseReports=Expense reports
SearchIntoLeaves=Leaves
+CommentLink=Comments
+NbComments=Number of comments
+CommentPage=Comments space
+CommentAdded=Comment added
+CommentDeleted=Comment deleted
diff --git a/htdocs/langs/en_US/projects.lang b/htdocs/langs/en_US/projects.lang
index 408c3db5e7a..f9eb6c00477 100644
--- a/htdocs/langs/en_US/projects.lang
+++ b/htdocs/langs/en_US/projects.lang
@@ -210,8 +210,4 @@ OppStatusLOST=Lost
Budget=Budget
# Comments trans
AllowCommentOnTask=Allow user comments on tasks
-TaskCommentLinks=Comments
-TaskNbComments=Number of comments
-TaskComment=Task's comments space
-CommentAdded=Comment added
-CommentDeleted=Comment deleted
+AllowCommentOnProject=Allow user comments on projects
diff --git a/htdocs/langs/fr_FR/main.lang b/htdocs/langs/fr_FR/main.lang
index 6a6c80a78bf..7a47c934a80 100644
--- a/htdocs/langs/fr_FR/main.lang
+++ b/htdocs/langs/fr_FR/main.lang
@@ -842,3 +842,8 @@ SearchIntoContracts=Contrats
SearchIntoCustomerShipments=Expéditions clients
SearchIntoExpenseReports=Notes de frais
SearchIntoLeaves=Congés
+CommentLink=Commentaires
+NbComments=Nombre de commentaires
+CommentPage=Espace commentaires
+CommentAdded=Commentaire ajouté avec succès
+CommentDeleted=Commentaire supprimé avec succès
diff --git a/htdocs/langs/fr_FR/projects.lang b/htdocs/langs/fr_FR/projects.lang
index 154c1138ab9..c235230eb2f 100644
--- a/htdocs/langs/fr_FR/projects.lang
+++ b/htdocs/langs/fr_FR/projects.lang
@@ -209,8 +209,4 @@ OppStatusLOST=Perdu
Budget=Budget
#Comments trans
AllowCommentOnTask=Autoriser les commentaires entre utilisateurs sur les tâches
-TaskCommentLinks=Commentaires
-TaskNbComments=Nombre de commentaires
-TaskComment=Tâches espace commentaires
-CommentAdded=Commentaire ajouté avec succès
-CommentDeleted=Commentaire supprimé avec succès
+AllowCommentOnProject=Autoriser les commentaires entre utilisateurs sur les projets
diff --git a/htdocs/projet/admin/project.php b/htdocs/projet/admin/project.php
index 0c0da27457e..54e864e1bf6 100644
--- a/htdocs/projet/admin/project.php
+++ b/htdocs/projet/admin/project.php
@@ -918,6 +918,15 @@ print '';
print ' | ';
print '';
+print '';
+print '| '.$langs->trans("AllowCommentOnProject").' | ';
+
+print '';
+echo ajax_constantonoff('PROJECT_ALLOW_COMMENT_ON_PROJECT');
+print ' | ';
+print ' | ';
+print '
';
+
print '';
print '| '.$langs->trans("AllowCommentOnTask").' | ';
diff --git a/htdocs/projet/class/project.class.php b/htdocs/projet/class/project.class.php
index af55063c66a..18aa3fe1f52 100644
--- a/htdocs/projet/class/project.class.php
+++ b/htdocs/projet/class/project.class.php
@@ -441,6 +441,7 @@ class Project extends CommonObject
// Retreive all extrafield for thirdparty
$this->fetch_optionals();
+ $this->fetchComments();
return 1;
}
diff --git a/htdocs/projet/class/task.class.php b/htdocs/projet/class/task.class.php
index 32ae678b016..0758dce2acb 100644
--- a/htdocs/projet/class/task.class.php
+++ b/htdocs/projet/class/task.class.php
@@ -1832,332 +1832,4 @@ class Task extends CommonObject
return ($datetouse > 0 && ($datetouse < ($now - $conf->projet->task->warning_delay)));
}
-
- /**
- * Return nb comments already posted
- *
- * @return int
- */
- public function getNbComments()
- {
- return count($this->comments);
- }
-
- /**
- * Load comments linked with current task
- *
- * @return int <0 if KO, 0 if not found, >0 if OK
- */
- public function fetchComments()
- {
- $this->comments = array();
- $sql = "SELECT";
- $sql.= " c.rowid";
- $sql.= " FROM ".MAIN_DB_PREFIX."projet_task_comment as c";
- $sql.= " WHERE c.fk_task = ".$this->id;
- $sql.= " ORDER BY c.tms DESC";
-
- dol_syslog(get_class($this)."::fetchComments", LOG_DEBUG);
- $resql=$this->db->query($sql);
- if ($resql)
- {
- $num_rows = $this->db->num_rows($resql);
- if ($num_rows > 0)
- {
- while($obj = $this->db->fetch_object($resql))
- {
- $comment = new TaskComment($this->db);
- $comment->fetch($obj->rowid);
- $this->comments[] = $comment;
- }
- return $num_rows;
- }else{
- return 0;
- }
- }
- else
- {
- $this->error="Error ".$this->db->lasterror();
- return -1;
- }
- }
-}
-
-/**
- * Class to manage tasks
- */
-class TaskComment extends CommonObject
-{
- public $element='project_task_comment'; //!< Id that identify managed objects
- public $table_element='projet_task_comment'; //!< Name of table without prefix where object is stored
- public $fk_element='fk_task';
- public $picto = 'task';
-
- var $fk_task;
-
- var $description;
-
- var $tms;
-
- var $datec;
-
- var $fk_user;
-
- var $entity;
-
- var $import_key;
-
- public $oldcopy;
-
-
- /**
- * Constructor
- *
- * @param DoliDB $db Database handler
- */
- function __construct($db)
- {
- $this->db = $db;
- }
-
-
- /**
- * Create into database
- *
- * @param User $user User that create
- * @param int $notrigger 0=launch triggers after, 1=disable triggers
- * @return int <0 if KO, Id of created object if OK
- */
- function create($user, $notrigger=0)
- {
- global $conf, $langs;
-
- $error=0;
-
- // Insert request
- $sql = "INSERT INTO ".MAIN_DB_PREFIX."projet_task_comment (";
- $sql.= "description";
- $sql.= ", datec";
- $sql.= ", fk_task";
- $sql.= ", fk_user";
- $sql.= ", entity";
- $sql.= ", import_key";
- $sql.= ") VALUES (";
- $sql.= "'".$this->db->escape($this->description)."'";
- $sql.= ", ".($this->datec!=''?"'".$this->db->idate($this->datec)."'":'null');
- $sql.= ", '".(isset($this->fk_task)?$this->fk_task:"null")."'";
- $sql.= ", '".(isset($this->fk_user)?$this->fk_user:"null")."'";
- $sql.= ", ".(!empty($this->entity)?$this->entity:'1');
- $sql.= ", ".(!empty($this->import_key)?"'".$this->db->escape($this->import_key)."'":"null");
- $sql.= ")";
-
- //var_dump($this->db);
- //echo $sql;
-
- $this->db->begin();
-
- dol_syslog(get_class($this)."::create", LOG_DEBUG);
- $resql=$this->db->query($sql);
- if (! $resql) { $error++; $this->errors[]="Error ".$this->db->lasterror(); }
-
- if (! $error)
- {
- $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."projet_task_comment");
-
- if (! $notrigger)
- {
- // Call trigger
- $result=$this->call_trigger('TASK_COMMENT_CREATE',$user);
- if ($result < 0) { $error++; }
- // End call triggers
- }
- }
-
- // Commit or rollback
- if ($error)
- {
- foreach($this->errors as $errmsg)
- {
- dol_syslog(get_class($this)."::create ".$errmsg, LOG_ERR);
- $this->error.=($this->error?', '.$errmsg:$errmsg);
- }
- $this->db->rollback();
- return -1*$error;
- }
- else
- {
- $this->db->commit();
- return $this->id;
- }
- }
-
-
- /**
- * Load object in memory from database
- *
- * @param int $id Id object
- * @param int $ref ref object
- * @return int <0 if KO, 0 if not found, >0 if OK
- */
- function fetch($id, $ref='')
- {
- global $langs;
-
- $sql = "SELECT";
- $sql.= " c.rowid,";
- $sql.= " c.description,";
- $sql.= " c.datec,";
- $sql.= " c.tms,";
- $sql.= " c.fk_task,";
- $sql.= " c.fk_user,";
- $sql.= " c.entity,";
- $sql.= " c.import_key";
- $sql.= " FROM ".MAIN_DB_PREFIX."projet_task_comment as c";
- $sql.= " WHERE c.rowid = ".$id;
-
- dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
- $resql=$this->db->query($sql);
- if ($resql)
- {
- $num_rows = $this->db->num_rows($resql);
-
- if ($num_rows)
- {
- $obj = $this->db->fetch_object($resql);
-
- $this->id = $obj->rowid;
- $this->description = $obj->description;
- $this->datec = $this->db->jdate($obj->datec);
- $this->tms = $obj->tms;
- $this->fk_user = $obj->fk_user;
- $this->fk_task = $obj->fk_task;
- $this->entity = $obj->entity;
- $this->import_key = $obj->import_key;
- }
-
- $this->db->free($resql);
-
- if ($num_rows) return 1;
- else return 0;
- }
- else
- {
- $this->error="Error ".$this->db->lasterror();
- return -1;
- }
- }
-
-
- /**
- * Update database
- *
- * @param User $user User that modify
- * @param int $notrigger 0=launch triggers after, 1=disable triggers
- * @return int <=0 if KO, >0 if OK
- */
- function update(User $user, $notrigger=0)
- {
- global $conf, $langs;
- $error=0;
-
- // Clean parameters
- if (isset($this->fk_task)) $this->fk_project=(int) trim($this->fk_task);
- if (isset($this->fk_user)) $this->fk_user=(int) trim($this->fk_user);
- if (isset($this->description)) $this->description=trim($this->description);
-
-
- // Update request
- $sql = "UPDATE ".MAIN_DB_PREFIX."projet_task_comment SET";
- $sql.= " description=".(isset($this->description)?"'".$this->db->escape($this->description)."'":"null").",";
- $sql.= " datec=".($this->datec!=''?"'".$this->db->idate($this->datec)."'":'null').",";
- $sql.= " fk_task=".(isset($this->fk_task)?$this->fk_task:"null").",";
- $sql.= " fk_user=".(isset($this->fk_user)?$this->fk_user:"null").",";
- $sql.= " entity=".(!empty($this->entity)?$this->entity:'1').",";
- $sql.= " import_key=".(!empty($this->import_key)?"'".$this->db->escape($this->import_key)."'":"null");
- $sql.= " WHERE rowid=".$this->id;
-
- $this->db->begin();
-
- dol_syslog(get_class($this)."::update", LOG_DEBUG);
- $resql = $this->db->query($sql);
- if (! $resql) { $error++; $this->errors[]="Error ".$this->db->lasterror(); }
-
- if (! $error)
- {
- if (! $notrigger)
- {
- // Call trigger
- $result=$this->call_trigger('TASK_COMMENT_MODIFY',$user);
- if ($result < 0) { $error++; }
- // End call triggers
- }
- }
-
- // Commit or rollback
- if ($error)
- {
- foreach($this->errors as $errmsg)
- {
- dol_syslog(get_class($this)."::update ".$errmsg, LOG_ERR);
- $this->error.=($this->error?', '.$errmsg:$errmsg);
- }
- $this->db->rollback();
- return -1*$error;
- }
- else
- {
- $this->db->commit();
- return 1;
- }
- }
-
-
- /**
- * Delete task from database
- *
- * @param User $user User that delete
- * @param int $notrigger 0=launch triggers after, 1=disable triggers
- * @return int <0 if KO, >0 if OK
- */
- function delete($user, $notrigger=0)
- {
- global $conf, $langs;
- require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php';
-
- $error=0;
-
- $this->db->begin();
-
- $sql = "DELETE FROM ".MAIN_DB_PREFIX."projet_task_comment";
- $sql.= " WHERE rowid=".$this->id;
-
- $resql = $this->db->query($sql);
- if (! $resql) { $error++; $this->errors[]="Error ".$this->db->lasterror(); }
-
- if (! $error)
- {
- if (! $notrigger)
- {
- // Call trigger
- $result=$this->call_trigger('TASK_COMMENT_DELETE',$user);
- if ($result < 0) { $error++; }
- // End call triggers
- }
- }
-
- // Commit or rollback
- if ($error)
- {
- foreach($this->errors as $errmsg)
- {
- dol_syslog(get_class($this)."::delete ".$errmsg, LOG_ERR);
- $this->error.=($this->error?', '.$errmsg:$errmsg);
- }
- $this->db->rollback();
- return -1*$error;
- }else{
- $this->db->commit();
- return 1;
- }
- }
}
\ No newline at end of file
diff --git a/htdocs/projet/comment.php b/htdocs/projet/comment.php
new file mode 100644
index 00000000000..4e3d52a2f37
--- /dev/null
+++ b/htdocs/projet/comment.php
@@ -0,0 +1,189 @@
+
+ * Copyright (C) 2006-2017 Laurent Destailleur
+ * Copyright (C) 2010-2012 Regis Houssin
+ *
+ * This program 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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, see .
+ */
+
+/**
+ * \file htdocs/projet/tasks/task.php
+ * \ingroup project
+ * \brief Page of a project task
+ */
+
+require '../main.inc.php';
+require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
+require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php';
+require_once DOL_DOCUMENT_ROOT.'/core/lib/project.lib.php';
+require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
+require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
+require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
+require_once DOL_DOCUMENT_ROOT.'/core/modules/project/modules_project.php';
+require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
+require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
+
+$langs->load("projects");
+$langs->load("companies");
+
+$id=GETPOST('id','int');
+$idcomment=GETPOST('idcomment','int');
+$ref=GETPOST("ref",'alpha',1); // task ref
+$objectref=GETPOST("taskref",'alpha'); // task ref
+$action=GETPOST('action','alpha');
+$confirm=GETPOST('confirm','alpha');
+$withproject=GETPOST('withproject','int');
+$project_ref=GETPOST('project_ref','alpha');
+$planned_workload=((GETPOST('planned_workloadhour','int')!='' || GETPOST('planned_workloadmin','int')!='') ? (GETPOST('planned_workloadhour','int')>0?GETPOST('planned_workloadhour','int')*3600:0) + (GETPOST('planned_workloadmin','int')>0?GETPOST('planned_workloadmin','int')*60:0) : '');
+
+// Security check
+$socid=0;
+//if ($user->societe_id > 0) $socid = $user->societe_id; // For external user, no check is done on company because readability is managed by public status of project and assignement.
+if (! $user->rights->projet->lire) accessforbidden();
+
+// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
+$hookmanager->initHooks(array('projectcard','globalcard'));
+
+$object = new Project($db);
+$extrafields = new ExtraFields($db);
+$object = new Project($db);
+
+// fetch optionals attributes and labels
+$extralabels=$extrafields->fetch_name_optionals_label($object->table_element);
+
+// Load object
+if ($id > 0 || ! empty($ref))
+{
+ $ret = $object->fetch($id,$ref); // If we create project, ref may be defined into POST but record does not yet exists into database
+ if ($ret > 0) {
+ $object->fetch_thirdparty();
+ $id=$object->id;
+ }
+}
+
+// include comment actions
+include DOL_DOCUMENT_ROOT . '/core/actions_comments.inc.php';
+
+/*
+ * View
+*/
+
+
+llxHeader('', $langs->trans("CommentPage"));
+
+$form = new Form($db);
+$formother = new FormOther($db);
+$formfile = new FormFile($db);
+
+// Tabs for project
+$tab = 'project_comment';
+$head = project_prepare_head($object);
+dol_fiche_head($head, $tab, $langs->trans("Project"), - 1, ($object->public ? 'projectpub' : 'project'));
+
+$param = ($mode == 'mine' ? '&mode=mine' : '');
+
+// Project card
+
+$linkback = '' . $langs->trans("BackToList") . '';
+
+$morehtmlref = '';
+// Title
+$morehtmlref .= $object->title;
+// Thirdparty
+if ($object->thirdparty->id > 0) {
+ $morehtmlref .= '
' . $langs->trans('ThirdParty') . ' : ' . $object->thirdparty->getNomUrl(1, 'project');
+}
+$morehtmlref .= '
';
+
+// Define a complementary filter for search of next/prev ref.
+if (! $user->rights->projet->all->lire) {
+ $objectsListId = $object->getProjectsAuthorizedForUser($user, 0, 0);
+ $object->next_prev_filter = " rowid in (" . (count($objectsListId) ? join(',', array_keys($objectsListId)) : '0') . ")";
+}
+
+dol_banner_tab($object, 'project_ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
+
+print '';
+print '
';
+print '
';
+
+print '
';
+
+// Visibility
+print '| ' . $langs->trans("Visibility") . ' | ';
+if ($object->public) print $langs->trans('SharedProject');
+else
+ print $langs->trans('PrivateProject');
+print ' |
';
+
+// Date start - end
+print '| ' . $langs->trans("DateStart") . ' - ' . $langs->trans("DateEnd") . ' | ';
+print dol_print_date($object->date_start, 'day');
+$end = dol_print_date($object->date_end, 'day');
+if ($end) print ' - ' . $end;
+print ' |
';
+
+// Budget
+print '| ' . $langs->trans("Budget") . ' | ';
+if (strcmp($object->budget_amount, '')) print price($object->budget_amount, '', $langs, 1, 0, 0, $conf->currency);
+print ' |
';
+
+// Other attributes
+$cols = 2;
+// include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_view.tpl.php';
+
+print '
';
+
+print '
';
+print '
';
+print '
';
+print '
';
+
+print '
';
+
+// Description
+print '| ' . $langs->trans("Description") . ' | ';
+print nl2br($object->description);
+print ' | ';
+
+// Categories
+if ($conf->categorie->enabled) {
+ print '| ' . $langs->trans("Categories") . ' | ';
+ print $form->showCategories($object->id, 'project', 1);
+ print " |
";
+}
+
+// Nb comments
+print ''.$langs->trans("NbComments").' | ';
+print $object->getNbComments();
+print ' | ';
+
+print '
';
+
+print '
';
+print '
';
+print '
';
+
+print '';
+
+dol_fiche_end();
+
+print '
';
+
+// Include comment tpl view
+include DOL_DOCUMENT_ROOT . '/core/tpl/bloc_comment.tpl.php';
+
+
+llxFooter();
+$db->close();
diff --git a/htdocs/projet/tasks/comment.php b/htdocs/projet/tasks/comment.php
index a36337c324d..e4250bad062 100644
--- a/htdocs/projet/tasks/comment.php
+++ b/htdocs/projet/tasks/comment.php
@@ -33,7 +33,6 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/modules/project/task/modules_task.php';
-require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
$langs->load("projects");
$langs->load("companies");
@@ -41,7 +40,7 @@ $langs->load("companies");
$id=GETPOST('id','int');
$idcomment=GETPOST('idcomment','int');
$ref=GETPOST("ref",'alpha',1); // task ref
-$taskref=GETPOST("taskref",'alpha'); // task ref
+$objectref=GETPOST("taskref",'alpha'); // task ref
$action=GETPOST('action','alpha');
$confirm=GETPOST('confirm','alpha');
$withproject=GETPOST('withproject','int');
@@ -56,69 +55,25 @@ if (! $user->rights->projet->lire) accessforbidden();
// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
$hookmanager->initHooks(array('projecttaskcard','globalcard'));
-$task = new Task($db);
-$object = new TaskComment($db);
+$object = new Task($db);
$extrafields = new ExtraFields($db);
$projectstatic = new Project($db);
-$userstatic = new User($db);
// fetch optionals attributes and labels
-$extralabels=$extrafields->fetch_name_optionals_label($task->table_element);
+$extralabels=$extrafields->fetch_name_optionals_label($object->table_element);
-
-/*
- * Actions
- */
-
-if ($action == 'addcomment')
-{
- if (!empty($_POST['comment_description']))
- {
- $object->description = GETPOST('comment_description');
- $object->datec = time();
- $object->fk_task = $id;
- $object->fk_user = $user->id;
- $object->entity = $conf->entity;
- if ($object->create($user) > 0)
- {
- setEventMessages($langs->trans("CommentAdded"), null, 'mesgs');
- header('Location: '.DOL_URL_ROOT.'/projet/tasks/comment.php?id='.$id.($withproject?'&withproject=1':''));
- exit;
- }
- else
- {
- setEventMessages($task->error,$task->errors,'errors');
- $action='';
- }
- }
-}
-if ($action == 'deletecomment')
-{
- if ($object->fetch($idcomment) >= 0)
- {
- if ($object->delete($user) > 0)
- {
- setEventMessages($langs->trans("CommentDeleted"), null, 'mesgs');
- header('Location: '.DOL_URL_ROOT.'/projet/tasks/comment.php?id='.$id.($withproject?'&withproject=1':''));
- exit;
- }
- else
- {
- setEventMessages($task->error,$task->errors,'errors');
- $action='';
- }
- }
-}
+// include comment actions
+include DOL_DOCUMENT_ROOT . '/core/actions_comments.inc.php';
// Retreive First Task ID of Project if withprojet is on to allow project prev next to work
if (! empty($project_ref) && ! empty($withproject))
{
if ($projectstatic->fetch('',$project_ref) > 0)
{
- $tasksarray=$task->getTasksArray(0, 0, $projectstatic->id, $socid, 0);
- if (count($tasksarray) > 0)
+ $objectsarray=$object->getTasksArray(0, 0, $projectstatic->id, $socid, 0);
+ if (count($objectsarray) > 0)
{
- $id=$tasksarray[0]->id;
+ $id=$objectsarray[0]->id;
}
else
{
@@ -132,7 +87,7 @@ if (! empty($project_ref) && ! empty($withproject))
*/
-llxHeader('', $langs->trans("TaskComment"));
+llxHeader('', $langs->trans("CommentPage"));
$form = new Form($db);
$formother = new FormOther($db);
@@ -140,14 +95,14 @@ $formfile = new FormFile($db);
if ($id > 0 || ! empty($ref))
{
- if ($task->fetch($id,$ref) > 0)
+ if ($object->fetch($id,$ref) > 0)
{
- $res=$task->fetch_optionals($task->id,$extralabels);
+ $res=$object->fetch_optionals($object->id,$extralabels);
- $result=$projectstatic->fetch($task->fk_project);
+ $result=$projectstatic->fetch($object->fk_project);
if (! empty($projectstatic->socid)) $projectstatic->fetch_thirdparty();
- $task->project = clone $projectstatic;
+ $object->project = clone $projectstatic;
$userWrite = $projectstatic->restrictedProjectArea($user,'write');
@@ -177,8 +132,8 @@ if ($id > 0 || ! empty($ref))
// Define a complementary filter for search of next/prev ref.
if (! $user->rights->projet->all->lire)
{
- $tasksListId = $projectstatic->getProjectsAuthorizedForUser($user,0,0);
- $projectstatic->next_prev_filter=" rowid in (".(count($tasksListId)?join(',',array_keys($tasksListId)):'0').")";
+ $objectsListId = $projectstatic->getProjectsAuthorizedForUser($user,0,0);
+ $projectstatic->next_prev_filter=" rowid in (".(count($objectsListId)?join(',',array_keys($objectsListId)):'0').")";
}
dol_banner_tab($projectstatic, 'project_ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
@@ -245,7 +200,7 @@ if ($id > 0 || ! empty($ref))
print '
';
}
- $head=task_prepare_head($task);
+ $head=task_prepare_head($object);
/*
* Fiche tache en mode visu
@@ -263,9 +218,9 @@ if ($id > 0 || ! empty($ref))
if (! GETPOST('withproject') || empty($projectstatic->id))
{
$projectsListId = $projectstatic->getProjectsAuthorizedForUser($user,0,1);
- $task->next_prev_filter=" fk_projet in (".$projectsListId.")";
+ $object->next_prev_filter=" fk_projet in (".$projectsListId.")";
}
- else $task->next_prev_filter=" fk_projet = ".$projectstatic->id;
+ else $object->next_prev_filter=" fk_projet = ".$projectstatic->id;
$morehtmlref='';
@@ -285,7 +240,7 @@ if ($id > 0 || ! empty($ref))
$morehtmlref.='';
}
- dol_banner_tab($task, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref, $param);
+ dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref, $param);
print '';
@@ -293,8 +248,8 @@ if ($id > 0 || ! empty($ref))
print '
';
// Nb comments
- print '| '.$langs->trans("TaskNbComments").' | ';
- print $task->getNbComments();
+ print ' | '.$langs->trans("NbComments").' | ';
+ print $object->getNbComments();
print ' | ';
// Other attributes
@@ -308,102 +263,9 @@ if ($id > 0 || ! empty($ref))
dol_fiche_end();
-
- print '
';
- print '';
+
+ // Include comment tpl view
+ include DOL_DOCUMENT_ROOT . '/core/tpl/bloc_comment.tpl.php';
}
}
'; + } + print $langs->trans('User').' : '.$userstatic->getNomUrl().'
'; + print $langs->trans('Date').' : '.dol_print_date($comment->datec,'dayhoursec'); + print '