From 47288c77da275404cc3d181599eb6e3b1596ccdf Mon Sep 17 00:00:00 2001
From: Laurent Destailleur <eldy@users.sourceforge.net>
Date: Sat, 18 Sep 2010 13:38:43 +0000
Subject: [PATCH] Fix: Maxi debug of project permissions

---
 .../modules/facture/pdf_crabe.modules.php     |  6 +-
 htdocs/lib/functions.lib.php                  | 22 +++++-
 htdocs/lib/project.lib.php                    | 70 +++++++++++++------
 htdocs/projet/activity/index.php              | 11 ++-
 htdocs/projet/activity/list.php               | 27 ++++---
 htdocs/projet/class/project.class.php         | 39 ++++++-----
 htdocs/projet/class/task.class.php            | 25 ++++---
 htdocs/projet/index.php                       |  2 +-
 htdocs/projet/liste.php                       | 19 ++---
 9 files changed, 140 insertions(+), 81 deletions(-)

diff --git a/htdocs/includes/modules/facture/pdf_crabe.modules.php b/htdocs/includes/modules/facture/pdf_crabe.modules.php
index 8ec90579b6b..6169a06701c 100644
--- a/htdocs/includes/modules/facture/pdf_crabe.modules.php
+++ b/htdocs/includes/modules/facture/pdf_crabe.modules.php
@@ -220,12 +220,16 @@ class pdf_crabe extends ModelePDFFactures
 
 					$pdf->SetFont('','', 9);
 					$pdf->SetXY ($this->posxdesc-1, $tab_top);
-					$pdf->MultiCell(190, 3, $outputlangs->convToOutputCharset($object->note_public), 0, 'J');
+                    //$pdf->MultiCell(190, 3, $outputlangs->convToOutputCharset($object->note_public), 0, 'J', false, 1, '', '', true, 0, false, false, 0, 'T', true);
+                    $pdf->MultiCell(190, 3, $outputlangs->convToOutputCharset($object->note_public), 0, 'J', false);    // FPDF
 					$nexY = $pdf->GetY();
 					$height_note=$nexY-$tab_top;
 
 					// Rect prend une longueur en 3eme param
 					$pdf->SetDrawColor(192,192,192);
+//print $pdf->getStringHeight(200,'SPECIMEN',false,false);
+//print "$this->marge_gauche, $tab_top-1, $this->page_largeur-$this->marge_gauche-$this->marge_droite, $height_note+1";exit;
+
 					$pdf->Rect($this->marge_gauche, $tab_top-1, $this->page_largeur-$this->marge_gauche-$this->marge_droite, $height_note+1);
 
 					$tab_height = $tab_height - $height_note;
diff --git a/htdocs/lib/functions.lib.php b/htdocs/lib/functions.lib.php
index 642106b6547..37091c3f61e 100644
--- a/htdocs/lib/functions.lib.php
+++ b/htdocs/lib/functions.lib.php
@@ -1604,6 +1604,10 @@ function restrictedArea($user, $features='societe', $objectid=0, $dbtablename=''
 		{
 			if (! $user->rights->ecm->download) $readok=0;
 		}
+        else if ($feature == 'projet')
+        {
+            if (! $user->rights->projet->lire && ! $user->rights->projet->all->lire) $readok=0;
+        }
 		else if (! empty($feature2))	// This should be used for future changes
 		{
 			if (empty($user->rights->$feature->$feature2->lire)
@@ -1684,10 +1688,11 @@ function restrictedArea($user, $features='societe', $objectid=0, $dbtablename=''
 			$sql='';
 
 			$check = array('user','usergroup','produit','service','produit|service'); // Test on entity only (Objects with no link to company)
-			$checksoc = array('societe');	// Test for societe object
-			$checkother = array('contact','projet');	// Test on entity and link to societe. Allowed if link is empty (Ex: contacts, projects...).
-			// Others: Test on entity and link to societe. Not allowed if link is empty (Ex: invoice, orders...).
+			$checksoc = array('societe');	 // Test for societe object
+			$checkother = array('contact');	 // Test on entity and link to societe. Allowed if link is empty (Ex: contacts...).
+            $checkproject = array('projet'); // Test for project object
 			$nocheck = array('categorie','barcode','stock','fournisseur');	// No test
+            $checkdefault = 'all other not already defined'; // Test on entity and link to societe. Not allowed if link is empty (Ex: invoice, orders...).
 
 			// If dbtable not defined, we use same name for table than module name
 			if (empty($dbtablename)) $dbtablename = $feature;
@@ -1756,6 +1761,17 @@ function restrictedArea($user, $features='societe', $objectid=0, $dbtablename=''
 					$sql.= " AND dbt.entity = ".$conf->entity;
 				}
 			}
+			else if (in_array($feature,$checkproject))
+            {
+                if (! $user->rights->projet->all->lire)
+                {
+                    include_once(DOL_DOCUMENT_ROOT."/projet/class/project.class.php");
+                    $projectstatic=new Project($db);
+                    $tmps=$projectstatic->getProjectsAuthorizedForUser($user,0,1,$user->societe_id);
+                    $tmparray=explode(',',$tmps);
+                    if (! in_array($objectid,$tmparray)) accessforbidden();
+                }
+            }
 			else if (!in_array($feature,$nocheck))
 			{
 				// If external user: Check permission for external users
diff --git a/htdocs/lib/project.lib.php b/htdocs/lib/project.lib.php
index 1282bf37415..109ef62671f 100644
--- a/htdocs/lib/project.lib.php
+++ b/htdocs/lib/project.lib.php
@@ -266,9 +266,10 @@ function select_projects($socid=-1, $selected='', $htmlname='projectid')
  * @param   $lines
  * @param   $level
  * @param   $projectsrole
+ * @param   $mytask         0 or 1 to enable only if task is a task i am affected to
  * @return  $inc
  */
-function PLinesb(&$inc, $parent, $lines, &$level, &$projectsrole)
+function PLinesb(&$inc, $parent, $lines, &$level, &$projectsrole, &$tasksrole, $mytask=0)
 {
 	global $user, $bc, $langs;
 	global $form;
@@ -327,19 +328,29 @@ function PLinesb(&$inc, $parent, $lines, &$level, &$projectsrole)
 			else print '--:--';
 			print "</td>\n";
 
-			$disabled=1;
+			$disabledproject=1;$disabledtask=1;
 			//print "x".$lines[$i]->fk_project;
 			//var_dump($lines[$i]);
 			//var_dump($projectsrole[$lines[$i]->fk_project]);
 			// If at least one role for project
-			if ($lines[$i]->public || ! empty($projectsrole[$lines[$i]->fk_project]) || $user->rights->projet->all->creer) $disabled=0;
+			if ($lines[$i]->public || ! empty($projectsrole[$lines[$i]->fk_project]) || $user->rights->projet->all->creer)
+			{
+			    $disabledproject=0;
+                $disabledtask=0;
+			}
+            // If mytask and no role on task
+            if ($mytask && empty($tasksrole[$lines[$i]->id]))
+            {
+                $disabledtask=1;
+            }
 
 			print '<td nowrap="nowrap">';
-			print $form->select_date('',$lines[$i]->id,'','','',"addtime",1,0,1,$disabled);
+			print $form->select_date('',$lines[$i]->id,'','','',"addtime",1,0,1,$disabledtask);
 			print '&nbsp;&nbsp;&nbsp;';
-			print $form->select_duration($lines[$i]->id,'',$disabled);
-			print '&nbsp;<input type="submit" class="button"'.($disabled?' disabled="true"':'').' value="'.$langs->trans("Add").'">';
-			if ((! $lines[$i]->public) && $disabled) print '('.$langs->trans("YouAreNotContactOfProject").')';
+			print $form->select_duration($lines[$i]->id,'',$disabledtask);
+			print '&nbsp;<input type="submit" class="button"'.($disabledtask?' disabled="true"':'').' value="'.$langs->trans("Add").'">';
+            if ($disabledtask) print '('.$langs->trans("TaskIsNotAffectedToYou").')';
+			if ((! $lines[$i]->public) && $disabledproject) print '('.$langs->trans("YouAreNotContactOfProject").')';
 			print '</td>';
 			print "<td>&nbsp;";
 			print '</td>';
@@ -347,7 +358,7 @@ function PLinesb(&$inc, $parent, $lines, &$level, &$projectsrole)
 			print "</tr>\n";
 			$inc++;
 			$level++;
-			if ($lines[$i]->id) PLinesb($inc, $lines[$i]->id, $lines, $level, $projectsrole);
+			if ($lines[$i]->id) PLinesb($inc, $lines[$i]->id, $lines, $level, $projectsrole, $tasksrole, $mytask);
 			$level--;
 		}
 		else
@@ -541,8 +552,8 @@ function SearchTaskInChild(&$inc, $parent, &$lines, &$taskrole)
 
 /**
  * Clean task not linked to a parent
- * @param unknown_type $db
- * @return		int		Nb of records deleted
+ * @param   $db     Database handler
+ * @return	int		Nb of records deleted
  */
 function clean_orphelins($db)
 {
@@ -598,12 +609,13 @@ function clean_orphelins($db)
 /**
  * Return HTML table with list of projects and number of opened tasks
  *
- * @param unknown_type $db
- * @param unknown_type $mine
- * @param unknown_type $socid
- * @param unknown_type $projectsListId
+ * @param   $db
+ * @param   $mine               Limited to project i am contact to
+ * @param   $socid
+ * @param   $projectsListId
+ * @param   $mytasks            Limited to task i am contact to
  */
-function print_projecttasks_array($db,$mine,$socid,$projectsListId)
+function print_projecttasks_array($db, $mine, $socid, $projectsListId, $mytasks=0)
 {
 	global $langs,$conf,$user,$bc;
 
@@ -623,11 +635,29 @@ function print_projecttasks_array($db,$mine,$socid,$projectsListId)
 
 	$sql = "SELECT p.rowid as projectid, p.ref, p.title, p.fk_user_creat, p.public, p.fk_statut, COUNT(t.rowid) as nb";
 	$sql.= " FROM ".MAIN_DB_PREFIX."projet as p";
-	$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."projet_task as t ON p.rowid = t.fk_projet";
+	if ($mytasks)
+	{
+        $sql.= ", ".MAIN_DB_PREFIX."projet_task as t";
+	    $sql.= ", ".MAIN_DB_PREFIX."element_contact as ec";
+        $sql.= ", ".MAIN_DB_PREFIX."c_type_contact as ctc";
+	}
+	else
+	{
+        $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."projet_task as t ON p.rowid = t.fk_projet";
+	}
 	$sql.= " WHERE p.entity = ".$conf->entity;
-	if ($mine) $sql.= " AND p.rowid IN (".$projectsListId.")";
-	if ($socid || ! $user->rights->societe->client->voir)	$sql.= "  AND (p.fk_soc IS NULL OR p.fk_soc = 0 OR p.fk_soc = ".$socid.")";
-	$sql.= " GROUP BY p.rowid, p.ref, p.title, p.fk_user_creat, p.public, p.fk_statut";
+    if (! $user->rights->projet->all->lire) $sql.= " AND p.rowid IN (".$projectsListId.")";
+	//if ($socid || ! $user->rights->societe->client->voir)	$sql.= "  AND (p.fk_soc IS NULL OR p.fk_soc = 0 OR p.fk_soc = ".$socid.")";
+    if ($socid) $sql.= "  AND (p.fk_soc IS NULL OR p.fk_soc = 0 OR p.fk_soc = ".$socid.")";
+    if ($mytasks)
+    {
+        $sql.= " AND p.rowid = t.fk_projet";
+        $sql.= " AND ec.element_id = t.rowid";
+        $sql.= " AND ctc.rowid = ec.fk_c_type_contact";
+        $sql.= " AND ctc.element = 'project_task'";
+        $sql.= " AND ec.fk_socpeople = ".$user->id;
+    }
+    $sql.= " GROUP BY p.rowid, p.ref, p.title, p.fk_user_creat, p.public, p.fk_statut";
 
 	$var=true;
 	$resql = $db->query($sql);
@@ -644,8 +674,8 @@ function print_projecttasks_array($db,$mine,$socid,$projectsListId)
 			$projectstatic->user_author_id = $objp->fk_user_creat;
 			$projectstatic->public = $objp->public;
 
+			// Check is user has read permission on project
 			$userAccess = $projectstatic->restrictedProjectArea($user,1);
-
 			if ($userAccess >= 0)
 			{
 				$var=!$var;
diff --git a/htdocs/projet/activity/index.php b/htdocs/projet/activity/index.php
index d8149b1be43..d940eeee25d 100644
--- a/htdocs/projet/activity/index.php
+++ b/htdocs/projet/activity/index.php
@@ -49,8 +49,8 @@ $langs->load("projects");
 $now = dol_now();
 
 $projectstatic=new Project($db);
-
-$projectsListId = $projectstatic->getProjectsAuthorizedForUser($user,$mine,1);
+//$projectsListId = $projectstatic->getProjectsAuthorizedForUser($user,$mine,1);
+$projectsListId = $projectstatic->getProjectsAuthorizedForUser($user,0,1);  // Return all project i have permission on. I want my tasks and some of my task may be on a public projet that is not my project
 
 $title=$langs->trans("Activities");
 if ($mine) $title=$langs->trans("MyActivities");
@@ -69,8 +69,7 @@ else
 print '<table border="0" width="100%" class="notopnoleftnoright">';
 print '<tr><td width="30%" valign="top" class="notopnoleft">';
 
-
-print_projecttasks_array($db,$mine,$socid,$projectsListId);
+print_projecttasks_array($db,0,$socid,$projectsListId,$mine);
 
 
 /* Affichage de la liste des projets d'aujourd'hui */
@@ -80,7 +79,7 @@ print '<td width="50%">'.$langs->trans('Today').'</td>';
 print '<td width="50%" align="right">'.$langs->trans("Time").'</td>';
 print "</tr>\n";
 
-$sql = "SELECT p.rowid, p.ref, p.title, sum(tt.task_duration) as nb";
+$sql = "SELECT p.rowid, p.ref, p.title, SUM(tt.task_duration) as nb";
 $sql.= " FROM ".MAIN_DB_PREFIX."projet as p";
 $sql.= ", ".MAIN_DB_PREFIX."projet_task as t";
 $sql.= ", ".MAIN_DB_PREFIX."projet_task_time as tt";
@@ -90,7 +89,7 @@ $sql.= " AND tt.fk_task = t.rowid";
 $sql.= " AND tt.fk_user = ".$user->id;
 $sql.= " AND date_format(task_date,'%d%m%y') = ".strftime("%d%m%y",time());
 $sql.= " AND p.rowid in ('".$projectsListId."')";
-$sql.= " GROUP BY p.rowid";
+$sql.= " GROUP BY p.rowid, p.ref, p.title";
 
 $resql = $db->query($sql);
 if ( $resql )
diff --git a/htdocs/projet/activity/list.php b/htdocs/projet/activity/list.php
index 52d514bd3dc..840a8f9f9f9 100644
--- a/htdocs/projet/activity/list.php
+++ b/htdocs/projet/activity/list.php
@@ -35,6 +35,9 @@ $langs->load('projects');
 
 $mode=$_REQUEST["mode"];
 
+$mine=0;
+if ($mode == 'mine') $mine=1;
+
 $projectid='';
 $projectid=isset($_GET["id"])?$_GET["id"]:$_POST["projectid"];
 
@@ -98,14 +101,18 @@ if ($_POST["action"] == 'addtime' && $user->rights->projet->creer)
  */
 
 $form=new Form($db);
+$projectstatic=new Project($db);
+$project = new Project($db);
+$taskstatic = new Task($db);
 
 $title=$langs->trans("TimeSpent");
-if ($mode == 'mine') $title=$langs->trans("MyTimeSpent");
+if ($mine) $title=$langs->trans("MyTimeSpent");
+
 
 llxHeader("",$title,"");
 
-$project = new Project($db);
-$task = new Task($db);
+//$projectsListId = $projectstatic->getProjectsAuthorizedForUser($user,$mine,1);
+$projectsListId = $projectstatic->getProjectsAuthorizedForUser($user,0,1);  // Return all project i have permission on. I want my tasks and some of my task may be on a public projet that is not my project
 
 if ($_GET["id"])
 {
@@ -113,14 +120,18 @@ if ($_GET["id"])
 	$project->societe->fetch($project->societe->id);
 }
 
+$tasksarray=$taskstatic->getTasksArray(0,0,($project->id?$project->id:$projectsListId),$socid,0);    // We want to see all task of project i am allowed to see, not only mine. Later only mine will be editable later.
+$projectsrole=$taskstatic->getUserRolesForProjectsOrTasks($user,0,($project->id?$project->id:$projectsListId),0);
+$tasksrole=$taskstatic->getUserRolesForProjectsOrTasks(0,$user,($project->id?$project->id:$projectsListId),0);
+//var_dump($tasksarray);
+//var_dump($projectsrole);
+//var_dump($taskrole);
+
+
 print_barre_liste($title, $page, $_SERVER["PHP_SELF"], "", $sortfield, $sortorder, "", $num);
 
 if ($mesg) print $mesg;
 
-$tasksarray=$task->getTasksArray(0,0,$project->id,$socid);
-$projectsrole=$task->getUserRolesForProjectsOrTasks($user,0,$project->id,0);
-//var_dump($tasksarray);
-//var_dump($projectsrole);
 
 print '<form name="addtime" method="POST" action="'.$_SERVER["PHP_SELF"].'?id='.$project->id.'">';
 print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
@@ -134,7 +145,7 @@ print '<td>'.$langs->trans("LabelTask").'</td>';
 print '<td align="right">'.$langs->trans("TimeSpent").'</td>';
 print '<td colspan="2">'.$langs->trans("AddDuration").'</td>';
 print "</tr>\n";
-PLinesb($j, 0, $tasksarray, $level, $projectsrole);
+PLinesb($j, 0, $tasksarray, $level, $projectsrole, $tasksrole, $mine);
 print '</form>';
 
 
diff --git a/htdocs/projet/class/project.class.php b/htdocs/projet/class/project.class.php
index df1befdf722..a562c206be6 100644
--- a/htdocs/projet/class/project.class.php
+++ b/htdocs/projet/class/project.class.php
@@ -699,7 +699,7 @@ class Project extends CommonObject
 	}
 
 	/**
-	 *	\brief		Check permissions
+	 *	\brief		Check if user has read permission on project
 	 * 	@param		user		Object user to evaluate
 	 * 	@param 		noprint		0=Print forbidden message if no permission, 1=Return -1 if no permission
 	 */
@@ -758,7 +758,7 @@ class Project extends CommonObject
 	}
 
 	/**
-	 * Return array of projects affected to a user, authorized to a user, or all projects
+	 * Return array of projects a user has permission on, is affected to, or all projects
 	 *
 	 * @param 	user		User object
 	 * @param 	mode		0=All project I have permission on, 1=Affected to me only, 2=Will return list of all projects
@@ -775,23 +775,17 @@ class Project extends CommonObject
 
 		$sql = "SELECT DISTINCT p.rowid, p.ref";
 		$sql.= " FROM ".MAIN_DB_PREFIX."projet as p";
-		$sql.= ", ".MAIN_DB_PREFIX."element_contact as ec";
-		$sql.= ", ".MAIN_DB_PREFIX."c_type_contact as ctc";
-		$sql.= " WHERE p.entity = ".$conf->entity;
-		if ($socid || ! $user->rights->societe->client->voir)	$sql.= " AND (p.fk_soc IS NULL OR p.fk_soc = 0 OR p.fk_soc = ".$socid.")";
-
-		if ($mode == 2)
+		if ($mode == 0 || $mode == 1)
 		{
-			// No filter. Use this if user has permission to see all project
+    		$sql.= ", ".MAIN_DB_PREFIX."element_contact as ec";
+    		$sql.= ", ".MAIN_DB_PREFIX."c_type_contact as ctc";
 		}
-		if ($mode == 1)
-		{
-			$sql.= " AND ec.element_id = p.rowid";
-			$sql.= " AND ctc.rowid = ec.fk_c_type_contact";
-			$sql.= " AND ctc.element = '".$this->element."'";
-			$sql.= " AND ec.fk_socpeople = ".$user->id;
-		}
-		if ($mode == 0)
+		$sql.= " WHERE p.entity = ".$conf->entity;
+        // Internal users must see project he is contact to even if project linked to a third party he can't see.
+		//if ($socid || ! $user->rights->societe->client->voir)	$sql.= " AND (p.fk_soc IS NULL OR p.fk_soc = 0 OR p.fk_soc = ".$socid.")";
+        if ($socid) $sql.= " AND (p.fk_soc IS NULL OR p.fk_soc = 0 OR p.fk_soc = ".$socid.")";
+
+        if ($mode == 0)
 		{
 			$sql.= " AND ( p.public = 1";
 			//$sql.= " OR p.fk_user_creat = ".$user->id;
@@ -800,6 +794,17 @@ class Project extends CommonObject
 			$sql.= " AND ctc.element = '".$this->element."'";
 			$sql.= " AND ec.fk_socpeople = ".$user->id." ) )";
 		}
+        if ($mode == 1)
+        {
+            $sql.= " AND ec.element_id = p.rowid";
+            $sql.= " AND ctc.rowid = ec.fk_c_type_contact";
+            $sql.= " AND ctc.element = '".$this->element."'";
+            $sql.= " AND ec.fk_socpeople = ".$user->id;
+        }
+        if ($mode == 2)
+        {
+            // No filter. Use this if user has permission to see all project
+        }
 
 		$resql = $this->db->query($sql);
 		if ($resql)
diff --git a/htdocs/projet/class/task.class.php b/htdocs/projet/class/task.class.php
index 62142f19740..4e7bbd01fb0 100644
--- a/htdocs/projet/class/task.class.php
+++ b/htdocs/projet/class/task.class.php
@@ -333,7 +333,7 @@ class Task extends CommonObject
 				return 0;
 			}
 		}
-		
+
 		// Delete rang of line
 		//$this->delRangOfLine($this->id, $this->element);
 
@@ -478,7 +478,7 @@ class Task extends CommonObject
 			$sql.= " WHERE t.fk_projet = p.rowid";
 			$sql.= " AND p.entity = ".$conf->entity;
 			if ($socid)	$sql.= " AND p.fk_soc = ".$socid;
-			if ($projectid) $sql.= " AND p.rowid =".$projectid;
+			if ($projectid) $sql.= " AND p.rowid in (".$projectid.")";
 		}
 		if ($mode == 1)
 		{
@@ -486,7 +486,7 @@ class Task extends CommonObject
 			$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."projet_task as t on t.fk_projet = p.rowid";
 			$sql.= " WHERE p.entity = ".$conf->entity;
 			if ($socid)	$sql.= " AND p.fk_soc = ".$socid;
-			if ($projectid) $sql.= " AND p.rowid =".$projectid;
+			if ($projectid) $sql.= " AND p.rowid in (".$projectid.")";
 		}
 		$sql.= " ORDER BY p.ref, t.label";
 
@@ -504,7 +504,7 @@ class Task extends CommonObject
 
 				$obj = $this->db->fetch_object($resql);
 
-				if ((! $obj->public) && (is_object($userp)))	// If not public and we ask a filter on project owned by a user
+				if ((! $obj->public) && (is_object($userp)))	// If not public project and we ask a filter on project owned by a user
 				{
 					if (! $this->getUserRolesForProjectsOrTasks($userp, 0, $obj->projectid, 0))
 					{
@@ -552,14 +552,13 @@ class Task extends CommonObject
 	 * Return list of roles for a user for each projects or each tasks (or a particular project or task)
 	 * @param 	userp			Return roles on project for this internal user (task id can't be defined)
 	 * @param	usert			Return roles on task for this internal user
-	 * @param 	projectid		Project id to filter on a project
+	 * @param 	projectid		Project id list separated with , to filter on project
 	 * @param 	taskid			Task id to filter on a task
 	 * @return 	array			Array (projectid => 'list of roles for project' or taskid => 'list of roles for task')
 	 */
-	function getUserRolesForProjectsOrTasks($userp,$usert,$projectid=0,$taskid=0)
+	function getUserRolesForProjectsOrTasks($userp,$usert,$projectid='',$taskid=0)
 	{
-		$projectsrole = array();
-		$tasksrole = array();
+		$arrayroles = array();
 
 		dol_syslog("Task::getUserRolesForProjectsOrTasks userp=".is_object($userp)." usert=".is_object($usert)." projectid=".$projectid." taskid=".$taskid);
 
@@ -591,8 +590,8 @@ class Task extends CommonObject
 		$sql.= " AND ctc.source = 'internal'";
 		if ($projectid)
 		{
-			if ($userp) $sql.= " AND pt.rowid = ".$projectid;
-			if ($usert) $sql.= " AND pt.fk_projet = ".$projectid;
+			if ($userp) $sql.= " AND pt.rowid in (".$projectid.")";
+			if ($usert) $sql.= " AND pt.fk_projet in (".$projectid.")";
 		}
 		if ($taskid)
 		{
@@ -610,8 +609,8 @@ class Task extends CommonObject
 			while ($i < $num)
 			{
 				$obj = $this->db->fetch_object($resql);
-				if (empty($projectsrole[$obj->pid])) $projectsrole[$obj->pid] = $obj->code;
-				else $projectsrole[$obj->pid].=','.$obj->code;
+				if (empty($arrayroles[$obj->pid])) $arrayroles[$obj->pid] = $obj->code;
+				else $arrayroles[$obj->pid].=','.$obj->code;
 				$i++;
 			}
 			$this->db->free($resql);
@@ -621,7 +620,7 @@ class Task extends CommonObject
 			dol_print_error($this->db);
 		}
 
-		return $projectsrole;
+		return $arrayroles;
 	}
 
 
diff --git a/htdocs/projet/index.php b/htdocs/projet/index.php
index 40ea4b03542..87221b24e9a 100644
--- a/htdocs/projet/index.php
+++ b/htdocs/projet/index.php
@@ -85,7 +85,7 @@ $sql.= " FROM ".MAIN_DB_PREFIX."projet as p";
 $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s on p.fk_soc = s.rowid";
 $sql.= " WHERE p.entity = ".$conf->entity;
 if (! $user->rights->projet->all->lire) $sql.= " AND p.rowid IN (".$projectsListId.")";
-if ($socid || ! $user->rights->societe->client->voir)	$sql.= "  AND (p.fk_soc IS NULL OR p.fk_soc = 0 OR p.fk_soc = ".$socid.")";
+if ($socid)	$sql.= "  AND (p.fk_soc IS NULL OR p.fk_soc = 0 OR p.fk_soc = ".$socid.")";
 $sql.= " GROUP BY s.nom, s.rowid";
 
 $var=true;
diff --git a/htdocs/projet/liste.php b/htdocs/projet/liste.php
index c1432340b54..5f159ccb28b 100644
--- a/htdocs/projet/liste.php
+++ b/htdocs/projet/liste.php
@@ -29,23 +29,18 @@
 require("../main.inc.php");
 require_once(DOL_DOCUMENT_ROOT."/projet/class/project.class.php");
 
-if (!$user->rights->projet->lire) accessforbidden();
-
-$socid = ( is_numeric($_GET["socid"]) ? $_GET["socid"] : 0 );
-
 $title = $langs->trans("Projects");
 
 // Security check
-$socid=0;
+$socid = (is_numeric($_GET["socid"]) ? $_GET["socid"] : 0 );
 if ($user->societe_id > 0) $socid=$user->societe_id;
-
-
 if ($socid > 0)
 {
 	$soc = new Societe($db);
 	$soc->fetch($socid);
 	$title .= ' (<a href="liste.php">'.$soc->nom.'</a>)';
 }
+if (!$user->rights->projet->lire) accessforbidden();
 
 
 $sortfield = isset($_GET["sortfield"])?$_GET["sortfield"]:$_POST["sortfield"];
@@ -60,6 +55,7 @@ $offset = $conf->liste_limit * $page ;
 $pageprev = $page - 1;
 $pagenext = $page + 1;
 
+$mine = $_REQUEST['mode']=='mine' ? 1 : 0;
 
 
 /*
@@ -71,7 +67,6 @@ llxHeader("",$langs->trans("Projects"),"EN:Module_Projects|FR:Module_Projets|ES:
 $projectstatic = new Project($db);
 $socstatic = new Societe($db);
 
-$mine = $_REQUEST['mode']=='mine' ? 1 : 0;
 $projectsListId = $projectstatic->getProjectsAuthorizedForUser($user,$mine,1,$socid);
 
 $sql = "SELECT p.rowid as projectid, p.ref, p.title, p.fk_statut, p.public, p.fk_user_creat";
@@ -80,9 +75,10 @@ $sql.= ", s.nom, s.rowid as socid";
 $sql.= " FROM ".MAIN_DB_PREFIX."projet as p";
 $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s on p.fk_soc = s.rowid";
 $sql.= " WHERE p.entity = ".$conf->entity;
-if ($mine) $sql.= " AND p.rowid IN (".$projectsListId.")";
-//var_dump($user->rights->societe);
-if ($socid || ! $user->rights->societe->client->voir)	$sql.= "  AND (p.fk_soc IS NULL OR p.fk_soc = 0 OR p.fk_soc = ".$socid.")";
+if (! $user->rights->projet->all->lire) $sql.= " AND p.rowid IN (".$projectsListId.")";
+// No need to check company, as filtering of projects must be done by getProjectsAuthorizedForUser
+//if ($socid || ! $user->rights->societe->client->voir)	$sql.= "  AND (p.fk_soc IS NULL OR p.fk_soc = 0 OR p.fk_soc = ".$socid.")";
+if ($socid) $sql.= "  AND (p.fk_soc IS NULL OR p.fk_soc = 0 OR p.fk_soc = ".$socid.")";
 if ($_GET["search_ref"])
 {
 	$sql.= " AND p.ref LIKE '%".addslashes($_GET["search_ref"])."%'";
@@ -98,7 +94,6 @@ if ($_GET["search_societe"])
 $sql.= $db->order($sortfield,$sortorder);
 $sql.= $db->plimit($conf->liste_limit+1, $offset);
 
-//print $sql;
 $var=true;
 $resql = $db->query($sql);
 if ($resql)
-- 
GitLab