1
|
|
|
<?php declare(strict_types=1); |
2
|
|
|
/** |
3
|
|
|
* @author Nicolas CARPi <[email protected]> |
4
|
|
|
* @copyright 2012 Nicolas CARPi |
5
|
|
|
* @see https://www.elabftw.net Official website |
6
|
|
|
* @license AGPL-3.0 |
7
|
|
|
* @package elabftw |
8
|
|
|
*/ |
9
|
|
|
|
10
|
|
|
namespace Elabftw\Models; |
11
|
|
|
|
12
|
|
|
use Elabftw\Interfaces\ContentParamsInterface; |
13
|
|
|
use PDO; |
14
|
|
|
|
15
|
|
|
/** |
16
|
|
|
* Read the unfinished steps of items or experiments to display in to-do list. |
17
|
|
|
* By default the unfinished steps of a user are returned. |
18
|
|
|
* extraParams['scope'] provides a switch to return unfinished steps of the entire team. |
19
|
|
|
*/ |
20
|
|
|
class UnfinishedSteps extends Steps |
21
|
|
|
{ |
22
|
|
|
public function __construct(AbstractEntity $Entity) |
23
|
|
|
{ |
24
|
|
|
parent::__construct($Entity); |
25
|
|
|
} |
26
|
|
|
|
27
|
|
|
public function read(ContentParamsInterface $params): array |
28
|
|
|
{ |
29
|
|
|
$sql = 'SELECT entity.id, entity.title, stepst.finished, stepst.steps_body, stepst.steps_id |
30
|
|
|
FROM ' . $this->Entity->type . " as entity |
31
|
|
|
CROSS JOIN ( |
32
|
|
|
SELECT item_id, finished, |
33
|
|
|
GROUP_CONCAT(entity_steps.body ORDER BY entity_steps.ordering SEPARATOR '|') AS steps_body, |
34
|
|
|
GROUP_CONCAT(entity_steps.id ORDER BY entity_steps.ordering SEPARATOR '|') AS steps_id |
35
|
|
|
FROM " . $this->Entity->type . '_steps as entity_steps |
36
|
|
|
WHERE finished = 0 GROUP BY item_id |
37
|
|
|
) AS stepst ON (stepst.item_id = entity.id)'; |
38
|
|
|
|
39
|
|
|
if ($this->Entity->type === 'experiments' |
40
|
|
|
&& $params->getExtra('scope') === 'team') { |
41
|
|
|
$sql .= ' JOIN users2teams ON (users2teams.users_id = entity.userid AND users2teams.teams_id = :teamid)'; |
42
|
|
|
} |
43
|
|
|
|
44
|
|
|
$sql .= $params->getExtra('scope') === 'team' ? $this->getTeamWhereClause() : ' WHERE entity.userid = :userid'; |
45
|
|
|
|
46
|
|
|
$sql .= ' GROUP BY entity.id ORDER BY entity.id DESC'; |
47
|
|
|
|
48
|
|
|
$req = $this->Db->prepare($sql); |
49
|
|
|
$req->bindParam(':userid', $this->Entity->Users->userData['userid'], PDO::PARAM_INT); |
50
|
|
|
if ($params->getExtra('scope') === 'team') { |
51
|
|
|
$req->bindParam(':teamid', $this->Entity->Users->team, PDO::PARAM_INT); |
52
|
|
|
} |
53
|
|
|
$this->Db->execute($req); |
54
|
|
|
|
55
|
|
|
$res = $this->Db->fetchAll($req); |
56
|
|
|
|
57
|
|
|
return $this->cleanUpResult($res); |
58
|
|
|
} |
59
|
|
|
|
60
|
|
|
/* |
61
|
|
|
* Clean up the read result so we get a nice array with entity id/title and steps with their id/body |
62
|
|
|
* use reference to edit in place |
63
|
|
|
* |
64
|
|
|
*@param array $res Unfinished steps SQL result array |
65
|
|
|
*/ |
66
|
|
|
private function cleanUpResult(array $res): array |
67
|
|
|
{ |
68
|
|
|
foreach ($res as &$entity) { |
69
|
|
|
$stepIDs = explode('|', $entity['steps_id']); |
70
|
|
|
$stepsBodies = explode('|', $entity['steps_body']); |
71
|
|
|
|
72
|
|
|
$entitySteps = array(); |
73
|
|
|
foreach ($stepIDs as $key => $stepID) { |
74
|
|
|
$entitySteps[] = array($stepID, $stepsBodies[$key]); |
75
|
|
|
} |
76
|
|
|
$entity['steps'] = $entitySteps; |
77
|
|
|
unset($entity['steps_body'], $entity['steps_id'], $entity['finished']); |
78
|
|
|
} |
79
|
|
|
|
80
|
|
|
return $res; |
81
|
|
|
} |
82
|
|
|
|
83
|
|
|
private function getTeamWhereClause(): string |
84
|
|
|
{ |
85
|
|
|
$teamgroupsOfUser = array_column((new TeamGroups($this->Entity->Users))->readGroupsFromUser(), 'id'); |
86
|
|
|
$teamgroups = ''; |
87
|
|
|
foreach ($teamgroupsOfUser as $teamgroup) { |
88
|
|
|
$teamgroups .= " OR entity.canread = $teamgroup"; |
89
|
|
|
} |
90
|
|
|
|
91
|
|
|
return ' WHERE' . ($this->Entity->type === 'items' ? ' entity.team = :teamid AND' : '') . " ( |
92
|
|
|
entity.canread = 'public' |
93
|
|
|
OR entity.canread = 'organization' |
94
|
|
|
OR entity.canread = 'team' |
95
|
|
|
$teamgroups |
96
|
|
|
OR (entity.userid = :userid |
97
|
|
|
AND ( |
98
|
|
|
entity.canread = 'user' |
99
|
|
|
OR entity.canread = 'useronly' |
100
|
|
|
) |
101
|
|
|
) |
102
|
|
|
)"; |
103
|
|
|
} |
104
|
|
|
} |
105
|
|
|
|