Passed
Push — hypernext ( 670104...c80301 )
by Nico
14:24
created

UnfinishedSteps::read()   A

Complexity

Conditions 5
Paths 8

Size

Total Lines 31
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
eloc 15
c 1
b 0
f 0
nc 8
nop 1
dl 0
loc 31
rs 9.4555
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