Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 156
0.00% covered (danger)
0.00%
0 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
OlzRoleDetailParams
n/a
0 / 0
n/a
0 / 0
0
n/a
0 / 0
OlzRoleDetail
0.00% covered (danger)
0.00%
0 / 156
0.00% covered (danger)
0.00%
0 / 5
552
0.00% covered (danger)
0.00%
0 / 1
 hasAccess
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 searchSqlWhenHasAccess
0.00% covered (danger)
0.00%
0 / 17
0.00% covered (danger)
0.00%
0 / 1
2
 getPageTitle
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getPageDescription
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getHtmlWhenHasAccess
0.00% covered (danger)
0.00%
0 / 136
0.00% covered (danger)
0.00%
0 / 1
380
1<?php
2
3namespace Olz\Roles\Components\OlzRoleDetail;
4
5use Olz\Components\Common\OlzRootComponent;
6use Olz\Components\Page\OlzFooter\OlzFooter;
7use Olz\Components\Page\OlzHeader\OlzHeader;
8use Olz\Entity\Roles\Role;
9use Olz\Users\Components\OlzUserInfoModal\OlzUserInfoModal;
10use Olz\Utils\HttpParams;
11
12/** @extends HttpParams<array{von?: ?string}> */
13class OlzRoleDetailParams extends HttpParams {
14}
15
16/** @extends OlzRootComponent<array<string, mixed>> */
17class OlzRoleDetail extends OlzRootComponent {
18    public function hasAccess(): bool {
19        return true;
20    }
21
22    public function searchSqlWhenHasAccess(array $terms): string|array|null {
23        $code_href = $this->envUtils()->getCodeHref();
24        $where = implode(' AND ', array_map(function ($term) {
25            return <<<ZZZZZZZZZZ
26                (
27                    r.username LIKE '%{$term}%'
28                    OR r.old_username LIKE '%{$term}%'
29                    OR r.name LIKE '%{$term}%'
30                    OR r.description LIKE '%{$term}%'
31                    OR EXISTS(
32                        SELECT id
33                        FROM users u
34                            JOIN users_roles ur ON (ur.role_id = r.id AND ur.user_id = u.id)
35                        WHERE u.first_name LIKE '%{$term}%' OR u.last_name LIKE '%{$term}%'
36                    )
37                )
38                ZZZZZZZZZZ;
39        }, $terms));
40        return <<<ZZZZZZZZZZ
41            SELECT
42                CONCAT('{$code_href}verein/', r.username) AS link,
43                '{$code_href}assets/icns/link_role_16.svg' AS icon,
44                NULL AS date,
45                CONCAT('Ressort: ', IF(rpp.name IS NULL, '', CONCAT(rpp.name, ' &gt; ')), IF(rp.name IS NULL, '', CONCAT(rp.name, ' &gt; ')), r.name) AS title,
46                CONCAT(IFNULL(r.username, ''), ' ', IFNULL(r.old_username, ''), ' ', IFNULL(r.description, ''), ' Verantwortlich: ', (
47                    SELECT GROUP_CONCAT(CONCAT(u.first_name, ' ', u.last_name) SEPARATOR ', ')
48                    FROM
49                        users_roles ur
50                        JOIN users u ON (u.id = ur.user_id)
51                    WHERE ur.role_id = r.id
52                    GROUP BY r.id
53                )) AS text,
54                1.0 AS time_relevance
55            FROM roles r
56                LEFT JOIN roles rp ON (rp.id = r.parent_role)
57                LEFT JOIN roles rpp ON (rpp.id = rp.parent_role)
58            WHERE
59                r.on_off = '1'
60                AND {$where}
61            ZZZZZZZZZZ;
62    }
63
64    public function getPageTitle(): string {
65        return "";
66    }
67
68    public function getPageDescription(): string {
69        return "";
70    }
71
72    public function getHtmlWhenHasAccess(mixed $args): string {
73        $this->httpUtils()->validateGetParams(OlzRoleDetailParams::class);
74        $is_member = $this->authUtils()->hasPermission('member');
75        $entityManager = $this->dbUtils()->getEntityManager();
76        $code_href = $this->envUtils()->getCodeHref();
77        $role_username = $args['ressort'];
78        $role_repo = $entityManager->getRepository(Role::class);
79        $role = $role_repo->findOneBy(['username' => $role_username, 'on_off' => 1]);
80        if (!$role) {
81            $old_role = $role_repo->findOneBy(['old_username' => $role_username, 'on_off' => 1]);
82            if ($old_role) {
83                $redirect_url = "{$code_href}verein/{$old_role->getUsername()}";
84                $this->httpUtils()->redirect($redirect_url, 308);
85                throw new \Exception('should already have terminated');
86            }
87            $this->httpUtils()->dieWithHttpError(404);
88            throw new \Exception('should already have terminated');
89        }
90
91        // TODO: Remove again, after all ressort descriptions have been updated.
92        // This is just temporary logic!
93        $no_robots = ($role->getGuide() === '');
94
95        $role_description = $role->getDescription();
96        $end_of_first_line = strpos($role_description, "\n");
97        $first_line = $end_of_first_line
98            ? substr($role_description, 0, $end_of_first_line)
99            : $role_description;
100        $description_html = $this->htmlUtils()->renderMarkdown($first_line);
101        $role_short_description = strip_tags($description_html);
102
103        $role_id = $role->getId();
104        $role_name = $role->getName();
105        $role_description = $role->getDescription();
106        $parent_role_id = $role->getParentRoleId();
107        $parent_role = $role_repo->findOneBy(['id' => $parent_role_id]);
108        $can_have_child_roles = $role->getCanHaveChildRoles();
109
110        $parent_chain = [];
111        $parent = $role;
112        while ($parent) {
113            $parent_id = $parent->getParentRoleId();
114            if ($parent_id) {
115                $parent = $role_repo->findOneBy(['id' => $parent_id]);
116                array_unshift($parent_chain, $parent);
117            } else {
118                $parent = null;
119            }
120        }
121
122        $out = OlzHeader::render([
123            'back_link' => "{$code_href}verein",
124            'title' => $role_name,
125            'description' => "{$role_short_description} - Ressort {$role_name} der OL Zimmerberg.",
126            'norobots' => $no_robots,
127            'canonical_url' => "{$code_href}verein/{$role_username}",
128        ]);
129
130        $out .= "<div class='content-full olz-role-page'>";
131        $out .= "<nav aria-label='breadcrumb'>";
132        $out .= "<ol class='breadcrumb'>";
133        $out .= "<li class='breadcrumb-item'><a href='{$code_href}verein'>OL Zimmerberg</a></li>";
134        foreach ($parent_chain as $breadcrumb) {
135            $username = $breadcrumb?->getUsername();
136            $name = $breadcrumb?->getName();
137            $out .= "<li class='breadcrumb-item'><a href='{$code_href}verein/{$username}'>{$name}</a></li>";
138        }
139        $out .= "<li class='breadcrumb-item active' aria-current='page'>{$role_name}</li>";
140        $out .= "</ol>";
141        $out .= "</nav>";
142
143        $edit_admin = '';
144        $add_membership_admin = '';
145        $add_child_role_admin = '';
146        $is_parent_superior = $this->authUtils()->hasRoleEditPermission($parent_role_id);
147        $is_parent_owner = $parent_role && $this->entityUtils()->canUpdateOlzEntity($parent_role, null, 'roles');
148        $can_parent_edit = $is_parent_superior || $is_parent_owner;
149        $is_superior = $this->authUtils()->hasRoleEditPermission($role_id);
150        $is_owner = $this->entityUtils()->canUpdateOlzEntity($role, null, 'roles');
151        $can_edit = $is_superior || $is_owner;
152        if ($can_edit) {
153            $json_id = json_encode($role_id);
154            $json_can_parent_edit = json_encode(boolval($can_parent_edit));
155            $edit_admin = <<<ZZZZZZZZZZ
156                <div>
157                    <button
158                        id='edit-role-button'
159                        class='btn btn-primary'
160                        onclick='return olz.editRole({$json_id}{$json_can_parent_edit})'
161                    >
162                        <img src='{$code_href}assets/icns/edit_white_16.svg' class='noborder' />
163                        Bearbeiten
164                    </button>
165                </div>
166                ZZZZZZZZZZ;
167            $add_membership_admin = <<<ZZZZZZZZZZ
168                <div>
169                    <button
170                        id='add-role-user-button'
171                        class='btn btn-primary'
172                        onclick='return olz.addRoleUser({$json_id})'
173                    >
174                        <img src='{$code_href}assets/icns/new_white_16.svg' class='noborder' />
175                        Neuer Verantwortlicher
176                    </button>
177                </div>
178                ZZZZZZZZZZ;
179            if ($can_have_child_roles) {
180                $add_child_role_admin = <<<ZZZZZZZZZZ
181                    <div>
182                        <button
183                            id='add-sub-role-button'
184                            class='btn btn-primary'
185                            onclick='return olz.addChildRole({$json_id})'
186                        >
187                            <img src='{$code_href}assets/icns/new_white_16.svg' class='noborder' />
188                            Neues Unter-Ressort
189                        </button>
190                    </div>
191                    ZZZZZZZZZZ;
192            }
193        }
194
195        $out .= "<div>{$edit_admin}</div>";
196        $description_html = $this->htmlUtils()->renderMarkdown($role->getDescription());
197        $description_html = $role->replaceImagePaths($description_html);
198        $description_html = $role->replaceFilePaths($description_html);
199        $out .= $description_html;
200
201        $assignees = $role->getUsers();
202        $num_assignees = count($assignees);
203        $out .= "<br/><h2>Verantwortlich</h2>";
204        if ($num_assignees === 0) {
205            $out .= "<p><i>Keine Ressort-Verantwortlichen</i></p>";
206            $out .= $add_membership_admin;
207        } else {
208            $out .= "<div class='role-assignees'>";
209            foreach ($assignees as $assignee) {
210                $out .= "<div class='assignee'>";
211                if ($is_superior || $is_owner) {
212                    $json_role_id = json_encode(intval($role_id));
213                    $json_user_id = json_encode(intval($assignee->getId()));
214                    $out .= <<<ZZZZZZZZZZ
215                            <button
216                                id='delete-role-user-button'
217                                class='btn btn-sm btn-danger'
218                                onclick='return olz.deleteRoleUser({$json_role_id}{$json_user_id})'
219                            >
220                                <img src='{$code_href}assets/icns/delete_white_16.svg' class='noborder' />
221                            </button>
222                        ZZZZZZZZZZ;
223                }
224                $out .= OlzUserInfoModal::render([
225                    'user' => $assignee,
226                    'mode' => 'name_picture',
227                ]);
228                $out .= "</div>";
229            }
230            $out .= $add_membership_admin;
231            $out .= "</div>";
232        }
233
234        $child_roles = $role_repo->findBy([
235            'parent_role' => $role_id,
236            'on_off' => 1,
237        ], ['position_within_parent' => 'ASC']);
238        $num_child_roles = count($child_roles);
239        $out .= "<br/><h2>Unter-Ressorts</h2>";
240        if ($num_child_roles === 0) {
241            $out .= "<p id='sub-roles'><i>Keine Unter-Ressorts</i></p>";
242        } else {
243            $out .= "<ul id='sub-roles' class='no-style'>";
244            foreach ($child_roles as $child_role) {
245                $child_role_name = $child_role->getName();
246                $child_role_username = $child_role->getUsername();
247                $out .= "<li><a href='{$code_href}verein/{$child_role_username}' class='linkint'><b>{$child_role_name}</b></a></li>";
248            }
249            $out .= "</ul>";
250            $out .= $add_child_role_admin;
251        }
252
253        if ($is_member) {
254            $guide_html = $this->htmlUtils()->renderMarkdown($role->getGuide());
255            $guide_html = $role->replaceImagePaths($guide_html);
256            $guide_html = $role->replaceFilePaths($guide_html);
257            $out .= "<br/><br/><h2>Aufgaben (nur für OLZ-Mitglieder sichtbar)</h2>";
258            $out .= $guide_html;
259        }
260
261        $out .= "</div>";
262        $out .= OlzFooter::render();
263
264        return $out;
265    }
266}