1 <?php
declare(strict_types
=1);
4 * This file is part of the Rapsys AirBundle package.
6 * (c) Raphaël Gertz <symfony@rapsys.eu>
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
12 namespace Rapsys\AirBundle\Repository
;
14 use Doctrine\ORM\AbstractQuery
;
15 use Doctrine\ORM\Query\ResultSetMapping
;
17 use Symfony\Component\Routing\Generator\UrlGeneratorInterface
;
19 use Rapsys\AirBundle\Repository
;
24 class UserRepository
extends Repository
{
26 * Find users with translated highest group and civility
28 * @return array The user ids keyed by group and pseudonym
30 public function findChoicesAsArray(): array {
44 FROM Rapsys\AirBundle\Entity\User AS u
45 JOIN Rapsys\AirBundle\Entity\UserGroup AS gu ON (gu.user_id = u.id)
46 JOIN Rapsys\AirBundle\Entity\Group AS g ON (g.id = gu.group_id)
47 WHERE g.title <> 'User'
48 ORDER BY g.id DESC, u.pseudonym ASC
55 //Replace bundle entity name by table name
56 $req = str_replace($this->tableKeys
, $this->tableValues
, $req);
58 //Get result set mapping instance
59 //XXX: DEBUG: see ../blog.orig/src/Rapsys/BlogBundle/Repository/ArticleRepository.php
60 $rsm = new ResultSetMapping();
63 //XXX: see vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/Types.php
64 //XXX: we don't use a result set as we want to translate group and civility
65 $rsm->addScalarResult('id', 'id', 'integer')
66 ->addScalarResult('pseudonym', 'pseudonym', 'string')
67 ->addScalarResult('g_id', 'g_id', 'integer')
68 ->addScalarResult('g_title', 'g_title', 'string')
69 ->addIndexByScalar('id');
73 ->createNativeQuery($req, $rsm)
80 foreach($res as $data) {
81 //Without group or simple user
82 #XXX: moved in sql by removing LEFT JOIN and excluding user group
83 #if (empty($data['g_title']) || $data['g_title'] == 'User') {
88 //Get translated group
89 $group = $this->translator
->trans($data['g_title']);
92 if (!isset($ret[$group])) {
97 //XXX: ChoiceType use display string as key
98 $ret[$group][trim($data['pseudonym'].' ('.$data['id'].')')] = intval($data['id']);
106 * Find user ids by pseudonym
108 * @param array $pseudonym The pseudonym filter
109 * @return array The user ids
111 public function findIdByPseudonymAsArray(array $pseudonym): array {
119 FROM Rapsys\AirBundle\Entity\User AS u
120 LEFT JOIN Rapsys\AirBundle\Entity\UserGroup AS gu ON (gu.user_id = u.id)
121 WHERE u.pseudonym IN (:pseudonym)
122 ORDER BY gu.group_id DESC, u.pseudonym ASC
129 //Replace bundle entity name by table name
130 $req = str_replace($this->tableKeys
, $this->tableValues
, $req);
132 //Get result set mapping instance
133 //XXX: DEBUG: see ../blog.orig/src/Rapsys/BlogBundle/Repository/ArticleRepository.php
134 $rsm = new ResultSetMapping();
137 //XXX: see vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/Types.php
138 //XXX: we don't use a result set as we want to translate group and civility
139 $rsm->addScalarResult('id', 'id', 'integer');
143 ->createNativeQuery($req, $rsm)
144 ->setParameter('pseudonym', $pseudonym)
145 //XXX: instead of array_column on the result
146 ->getResult(AbstractQuery
::HYDRATE_SCALAR_COLUMN
);
150 * Find applicant by session id
152 * @param int $sessionId The Session id
153 * @return array The pseudonym array keyed by id
155 public function findBySessionId(int $sessionId): array {
158 SELECT u.id, u.pseudonym
159 FROM Rapsys\AirBundle\Entity\Application AS a
160 JOIN Rapsys\AirBundle\Entity\User AS u ON (u.id = a.user_id)
161 WHERE a.session_id = :id
164 //Replace bundle entity name by table name
165 $req = str_replace($this->tableKeys
, $this->tableValues
, $req);
167 //Get result set mapping instance
168 //XXX: DEBUG: see ../blog.orig/src/Rapsys/BlogBundle/Repository/ArticleRepository.php
169 $rsm = new ResultSetMapping();
172 //XXX: see vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/Types.php
173 //XXX: we don't use a result set as we want to translate group and civility
174 $rsm->addScalarResult('id', 'id', 'integer')
175 ->addIndexByScalar('pseudonym');
179 ->createNativeQuery($req, $rsm)
180 ->setParameter('id', $sessionId)
186 //Iterate on each result
187 foreach($result as $id => $data) {
189 $return[$id] = $data['id'];
197 * Find user as array by id
199 * @param int $id The location id
200 * @param string $locale The locale
201 * @return array The location data
203 public function findOneByIdAsArray(int $id, string $locale): ?array {
205 //TODO: zipcode/city/country (on pourra matcher les locations avec ça ?)
217 u.civility_id AS c_id,
219 u.country_id AS o_id,
221 GROUP_CONCAT(g.id ORDER BY g.id SEPARATOR "\\n") AS ids,
222 GROUP_CONCAT(g.title ORDER BY g.id SEPARATOR "\\n") AS titles,
223 GREATEST(COALESCE(u.updated, 0), COALESCE(c.updated, 0), COALESCE(o.updated, 0)) AS modified
224 FROM Rapsys\AirBundle\Entity\User AS u
225 LEFT JOIN Rapsys\AirBundle\Entity\Civility AS c ON (c.id = u.civility_id)
226 LEFT JOIN Rapsys\AirBundle\Entity\Country AS o ON (o.id = u.country_id)
227 LEFT JOIN Rapsys\AirBundle\Entity\UserGroup AS gu ON (gu.user_id = u.id)
228 LEFT JOIN Rapsys\AirBundle\Entity\Group AS g ON (g.id = gu.group_id)
232 //Replace bundle entity name by table name
233 $req = str_replace($this->tableKeys
, $this->tableValues
, $req);
235 //Get result set mapping instance
236 //XXX: DEBUG: see ../blog.orig/src/Rapsys/BlogBundle/Repository/ArticleRepository.php
237 $rsm = new ResultSetMapping();
240 //XXX: see vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/Types.php
241 //addScalarResult($sqlColName, $resColName, $type = 'string');
242 $rsm->addScalarResult('id', 'id', 'integer')
243 ->addScalarResult('city', 'city', 'string')
244 ->addScalarResult('forename', 'forename', 'string')
245 ->addScalarResult('mail', 'mail', 'string')
246 ->addScalarResult('phone', 'phone', 'string')
247 ->addScalarResult('pseudonym', 'pseudonym', 'string')
248 ->addScalarResult('surname', 'surname', 'string')
249 ->addScalarResult('updated', 'updated', 'datetime')
250 ->addScalarResult('zipcode', 'zipcode', 'string')
251 ->addScalarResult('c_id', 'c_id', 'integer')
252 ->addScalarResult('c_title', 'c_title', 'string')
253 ->addScalarResult('o_id', 'o_id', 'integer')
254 ->addScalarResult('o_title', 'o_title', 'string')
255 //XXX: is a string because of \n separator
256 ->addScalarResult('ids', 'ids', 'string')
257 //XXX: is a string because of \n separator
258 ->addScalarResult('titles', 'titles', 'string')
259 ->addScalarResult('modified', 'modified', 'datetime')
260 ->addIndexByScalar('id');
264 ->createNativeQuery($req, $rsm)
265 ->setParameter('id', $id)
266 ->getOneOrNullResult();
269 if ($result === null) {
275 $result['alternates'] = [];
278 $route = 'rapsysair_user_view';
281 $routeParams = ['id' => $id, 'user' => $this->slugger
->slug($result['pseudonym'])];
283 //Milonga Raphaël exception
284 if ($routeParams['id'] == 1 && $routeParams['user'] == 'milonga-raphael') {
286 $route = 'rapsysair_user_milongaraphael';
291 //Iterate on each languages
292 foreach($this->languages
as $languageId => $language) {
293 //Without current locale
294 if ($languageId !== $locale) {
298 //Set route params locale
299 $routeParams['_locale'] = $languageId;
301 //Iterate on each locales
302 foreach(array_keys($this->languages
) as $other) {
303 //Without other locale
304 if ($other !== $languageId) {
305 //Set other locale title
306 $titles[$other] = $this->translator
->trans($language, [], null, $other);
310 //Add alternates locale
311 $result['alternates'][substr($languageId, 0, 2)] = $result['alternates'][str_replace('_', '-', $languageId)] = [
312 'absolute' => $this->router
->generate($route, $routeParams, UrlGeneratorInterface
::ABSOLUTE_URL
),
313 'relative' => $this->router
->generate($route, $routeParams),
314 'title' => implode('/', $titles),
315 'translated' => $this->translator
->trans($language, [], null, $languageId)
321 $titles = explode("\n", $result['titles']);
323 //Set groups and roles
324 $groups = $roles = [];
326 //Iterate on each location
327 foreach(explode("\n", $result['ids']) as $k => $id) {
329 //XXX: roles are keyes by id
330 $roles[$id] = 'ROLE_'.strtoupper($titles[$k]);
333 $groups[$id] = $this->translator
->trans($titles[$k]);
338 'id' => $result['id'],
339 'mail' => $result['mail'],
340 'pseudonym' => $result['pseudonym'],
341 'forename' => $result['forename'],
342 'surname' => $result['surname'],
343 'phone' => $result['phone'],
344 'zipcode' => $result['zipcode'],
345 'city' => $result['city'],
347 'id' => $result['c_id'],
348 'title' => $this->translator
->trans($result['c_title'])
351 'id' => $result['o_id'],
352 //XXX: without country, o_title is empty
353 'title' => $this->translator
->trans($result['o_title'])
355 'updated' => $result['updated'],
358 'modified' => $result['modified'],
359 'multimap' => $this->translator
->trans('%pseudonym% sector map', ['%pseudonym%' => $result['pseudonym']]),
360 'slug' => $this->slugger
->slug($result['pseudonym']),
361 'link' => $this->router
->generate($route, ['_locale' => $locale]+
$routeParams),
362 'alternates' => $result['alternates']
367 * Find all users grouped by translated group
369 * @return array The user mail and pseudonym keyed by group and id
371 public function findIndexByGroupId(): array {
382 GROUP_CONCAT(t.d_id ORDER BY t.d_id SEPARATOR "\\n") AS d_ids,
383 GROUP_CONCAT(t.d_name ORDER BY t.d_id SEPARATOR "\\n") AS d_names,
384 GROUP_CONCAT(t.d_type ORDER BY t.d_id SEPARATOR "\\n") AS d_types
406 FROM Rapsys\AirBundle\Entity\User AS u
407 JOIN Rapsys\AirBundle\Entity\UserGroup AS gu ON (gu.user_id = u.id)
408 JOIN Rapsys\AirBundle\Entity\Group AS g ON (g.id = gu.group_id)
412 LEFT JOIN Rapsys\AirBundle\Entity\Application AS a ON (a.user_id = c.id)
413 LEFT JOIN Rapsys\AirBundle\Entity\Dance AS d ON (d.id = a.dance_id)
418 GROUP BY t.g_id, t.id
419 ORDER BY t.g_id DESC, t.id ASC
422 //Replace bundle entity name by table name
423 $req = str_replace($this->tableKeys
, $this->tableValues
, $req);
425 //Get result set mapping instance
426 //XXX: DEBUG: see ../blog.orig/src/Rapsys/BlogBundle/Repository/ArticleRepository.php
427 $rsm = new ResultSetMapping();
430 //XXX: see vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/Types.php
431 //addScalarResult($sqlColName, $resColName, $type = 'string');
432 $rsm->addScalarResult('id', 'id', 'integer')
433 ->addScalarResult('mail', 'mail', 'string')
434 ->addScalarResult('forename', 'forename', 'string')
435 ->addScalarResult('surname', 'surname', 'string')
436 ->addScalarResult('pseudonym', 'pseudonym', 'string')
437 ->addScalarResult('g_id', 'g_id', 'integer')
438 ->addScalarResult('g_title', 'g_title', 'string')
439 //XXX: is a string because of \n separator
440 ->addScalarResult('d_ids', 'd_ids', 'string')
441 //XXX: is a string because of \n separator
442 ->addScalarResult('d_names', 'd_names', 'string')
443 //XXX: is a string because of \n separator
444 ->addScalarResult('d_types', 'd_types', 'string');
448 ->createNativeQuery($req, $rsm)
455 foreach($res as $data) {
456 //Get translated group
457 $group = $this->translator
->trans($data['g_title']);
459 //Init group subarray
460 if (!isset($ret[$group])) {
468 $ret[$group][$data['id']] = [
469 'mail' => $data['mail'],
470 'forename' => $data['forename'],
471 'surname' => $data['surname'],
472 'pseudonym' => $data['pseudonym'],
474 'slug' => $slug = $this->slugger
->slug($data['pseudonym']),
475 //Milonga Raphaël exception
476 'link' => $data['id'] == 1 && $slug == 'milonga-raphael' ? $this->router
->generate('rapsysair_user_milongaraphael', []) : $this->router
->generate('rapsysair_user_view', ['id' => $data['id'], 'user' => $slug]),
477 'edit' => $this->router
->generate('rapsysuser_edit', ['mail' => $short = $this->slugger
->short($data['mail']), 'hash' => $this->slugger
->hash($short)])
481 if (!empty($data['d_ids'])) {
483 $names = explode("\n", $data['d_names']);
486 $types = explode("\n", $data['d_types']);
488 //Iterate on each dance
489 foreach(explode("\n", $data['d_ids']) as $k => $id) {
490 //Init dance when missing
491 if (!isset($ret[$group][$data['id']]['dances'][$name = $this->translator
->trans($names[$k])])) {
492 $ret[$group][$data['id']]['dances'][$name] = [
493 'link' => $this->router
->generate('rapsysair_dance_name', ['name' => $this->slugger
->short($names[$k]), 'dance' => $this->slugger
->slug($name)]),
499 $ret[$group][$data['id']]['dances'][$name]['types'][$type = $this->translator
->trans($types[$k])] = $this->router
->generate('rapsysair_dance_view', ['id' => $id, 'name' => $this->slugger
->slug($name), 'type' => $this->slugger
->slug($type)]);