mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-10-01 10:59:45 +00:00
Compare commits
437 Commits
fix-tests/
...
fix/person
Author | SHA1 | Date | |
---|---|---|---|
eb3e333ff7 | |||
505f2d2ad5 | |||
57d92ad7f2 | |||
6a46e99bb0 | |||
9b03f8130b | |||
6c51d6de51 | |||
0aef40f23f | |||
a1125cfd3a | |||
9816ac8ad7 | |||
87c83dd7a0 | |||
8296d60cb6 | |||
|
bfc25c50b9 | ||
|
3417aa8207 | ||
4ba93bb709 | |||
bf0ad88cf0 | |||
b07188eaaf | |||
5651efe44d | |||
52dc89c06f | |||
fa7409bdf8 | |||
|
e413a09a0f | ||
|
a04c499af0 | ||
dcf5f1ed66 | |||
6dd74287a8 | |||
2b0093a351 | |||
e905465e1b | |||
c8135e0741 | |||
831b4f354c | |||
7482c709b3 | |||
22bdf35eb0 | |||
a2e9e4cf6a | |||
|
28afe5228a | ||
|
fcbf1bd558 | ||
|
32c2d96ab6 | ||
|
eedf5f25bd | ||
|
a7dd15a411 | ||
|
24be9dbe09 | ||
39ab7057ce | |||
5606b714cd | |||
f92c500657 | |||
1146bd666f | |||
95610ffd34 | |||
7230fd9c07 | |||
7dc9021eca | |||
a63e1321b0 | |||
bfca6d2afc | |||
b392bc9e65 | |||
d6da6a5d9d | |||
|
5e5dcaefe7 | ||
|
e6a9701418 | ||
|
66a2009aea | ||
|
a1b381a3ea | ||
|
5615734123 | ||
|
2eb30d2ae8 | ||
|
48ea67968e | ||
|
c8b0d62d46 | ||
|
9fc397f048 | ||
|
a19a5803e8 | ||
|
bf155f6967 | ||
|
6a9e133256 | ||
|
fb4b586cf0 | ||
|
6b60c46ad3 | ||
|
774b5b69d9 | ||
2382e7f44b | |||
|
e2ab3bfc6e | ||
16512a1ca1 | |||
a373142827 | |||
46e552d034 | |||
b2d6c82cbe | |||
|
66c5c4c1d6 | ||
9247cd3546 | |||
|
70524c506d | ||
|
b4d21c23b2 | ||
|
d94c367e3d | ||
|
6afd8ae3cd | ||
|
e195434bf4 | ||
|
0299500cad | ||
|
952435b36f | ||
ec6828f128 | |||
7399d0aa9e | |||
19b469259d | |||
5c037ca18f | |||
|
c979de962e | ||
|
061197e52e | ||
e786c40679 | |||
e4f8ada236 | |||
21e419b338 | |||
7fabe0214e | |||
|
fa05a6856a | ||
|
1dbf29beea | ||
|
bddcdd7de2 | ||
2c0198ef78 | |||
e55e8e072d | |||
f92b4b0ea3 | |||
b904e33d9b | |||
f064e8f307 | |||
e911dd30f5 | |||
092ea4d57f | |||
f16f45f3f3 | |||
bfcd420cdf | |||
9494bdee2a | |||
0f8ca77105 | |||
9a00e13532 | |||
1a00798da0 | |||
5e2b70249e | |||
55c2aed613 | |||
19badc0062 | |||
5ce2fe3295 | |||
5111a0ff6a | |||
74df496e38 | |||
fd2d74c9f5 | |||
b615f0c79f | |||
97859e9c1f | |||
6642b87168 | |||
35d807cab0 | |||
e1677cd2b6 | |||
df0cb8596b | |||
250bd29ab3 | |||
|
8de78c7584 | ||
|
84ab4f8d1f | ||
261810374f | |||
8f541c8418 | |||
b69cee84b6 | |||
b7e0753dbf | |||
9c57d21e5a | |||
c03b925bd9 | |||
6fdbefa4c8 | |||
13b43ace39 | |||
5d7f4bde1d | |||
40c5322cba | |||
8ab0fd59f8 | |||
aa9926aa29 | |||
adac384279 | |||
2099edefc5 | |||
12c3bfa578 | |||
|
52778a7051 | ||
|
a768563cd0 | ||
|
4011fc6e77 | ||
|
51938a99db | ||
|
c1f4e77293 | ||
|
bfb219746a | ||
|
4e72bdead5 | ||
|
e52880bb53 | ||
|
0439e6a821 | ||
72337a8fba | |||
e2110691ff | |||
645603a98f | |||
cab7cc4150 | |||
c6d7de3e58 | |||
6c52233a5a | |||
8c5bf6786b | |||
58f7715643 | |||
7c5d0fce51 | |||
35154f5ae1 | |||
6911ace412 | |||
87e16ec24f | |||
765a450bb9 | |||
|
93880f7010 | ||
e7900b8b21 | |||
|
0231433a6c | ||
4d08f3583e | |||
b2fe024534 | |||
39e0e01eb8 | |||
|
2aa588037a | ||
|
addb362478 | ||
|
819fc8af46 | ||
4dbbc40473 | |||
577ed7b6be | |||
2d3549ee28 | |||
6e3cdb6f58 | |||
e7ad96aaf7 | |||
|
f4bd55262a | ||
eebff23282 | |||
2d33ae26d8 | |||
7a384f9657 | |||
|
c8bc6ac495 | ||
7d91f3bef5 | |||
b0471c4851 | |||
6d248ab47b | |||
|
999658e792 | ||
|
1646740382 | ||
71695ed793 | |||
6d5f94ab45 | |||
9e61c417e5 | |||
e62d026339 | |||
9cffe5161a | |||
cbb3ad04f0 | |||
6b31bf225a | |||
024531fbe1 | |||
bd2ee9ddc1 | |||
84dfcb2899 | |||
1d774b19e8 | |||
d06a4b1ca9 | |||
9cce62c294 | |||
d3a08149f0 | |||
5d995115ba | |||
41f815bbb9 | |||
a0940a0c85 | |||
c4ba78d076 | |||
869e442c2c | |||
94e84fbdf0 | |||
20cebfc517 | |||
e9d20a56ff | |||
a57a23dc49 | |||
576ee49da0 | |||
8214fec217 | |||
e0cb5a88bd | |||
c63b1015e1 | |||
851a246257 | |||
35a27de216 | |||
09903c2f52 | |||
6719548504 | |||
8312955391 | |||
8eedee5e91 | |||
4dc29435dc | |||
db15a3d53c | |||
b60b1cb668 | |||
e6183f6646 | |||
a9d3d2027b | |||
80594ed186 | |||
1c60a5b51e | |||
039c74a1e4 | |||
059a0b075c | |||
50fbc7fd15 | |||
1155555bb3 | |||
76d6a9b4df | |||
e1d28289f6 | |||
3a7af94058 | |||
998295dc5f | |||
4017f8db48 | |||
317ba0a095 | |||
|
046f65f5ff | ||
27db6ddf0c | |||
|
c90f9ee5bc | ||
|
0bc8986aa7 | ||
|
56019cad99 | ||
4da32dc5ca | |||
e63d645f8a | |||
97dbc4bc16 | |||
69e3a0a6cd | |||
92c1bf15cc | |||
f834bb3bd6 | |||
2cb1ad6afc | |||
83e8b117db | |||
6752a2f6d3 | |||
1d1a54f653 | |||
2bbc6bd158 | |||
aea5e9b1d7 | |||
8ff581d5fa | |||
7ad0e2f2c8 | |||
a3b203c306 | |||
4287ca37ae | |||
07ed6b0fdf | |||
c200e9909e | |||
8e0a22974b | |||
b4b661882a | |||
f4fb375fd1 | |||
691c5ffd21 | |||
a09c824726 | |||
59118c8eed | |||
c4c75199d6 | |||
333a4d94b2 | |||
326fe5f50b | |||
2a86fd12d7 | |||
3f869e9ca5 | |||
5cf94a5ed6 | |||
ccf6c7ad91 | |||
965ea528e3 | |||
6921817853 | |||
|
532efb1787 | ||
|
0fa3ff4c16 | ||
|
d2eb7b471e | ||
a20eeb6a34 | |||
9609fcb5d3 | |||
b6dd5e92fc | |||
b7466c7e85 | |||
2ef70b301f | |||
|
816855e6f8 | ||
|
f6806f7743 | ||
|
69ae252da6 | ||
|
b800b62e88 | ||
|
6a1cf4eb92 | ||
|
f44566037c | ||
c1a845e3e1 | |||
4096e0d4df | |||
00ad7a74d6 | |||
136c6f19de | |||
18ca01b0dc | |||
e7f555077e | |||
b7f3700928 | |||
f4b9942f3c | |||
97f6110be3 | |||
|
1b7cc2be7a | ||
|
526ec52c8d | ||
|
82a679c233 | ||
|
21f463ccb9 | ||
|
911e709a74 | ||
|
c46065d9c5 | ||
|
625c43c0b9 | ||
3196a8f785 | |||
05d16ec9ab | |||
bae06fcc9c | |||
2f053d3b5f | |||
c4da6a436b | |||
4d55b0582c | |||
693a2889bc | |||
|
913eb5f229 | ||
83d91e61cb | |||
d009d09215 | |||
|
8c96aae988 | ||
|
ece7ec032d | ||
|
154416cddf | ||
6ff80be88d | |||
5869236af1 | |||
|
7dc4590580 | ||
|
e24fd8aff0 | ||
|
e9322e61d4 | ||
c38196006c | |||
a754bc0abe | |||
f09329daee | |||
b40ed48776 | |||
97cf6e52ac | |||
|
92843677f9 | ||
|
e06a98e70a | ||
|
821480c06f | ||
8735602dd6 | |||
d7cf45885e | |||
|
db67ed3194 | ||
|
8962c1c05f | ||
dded4fb804 | |||
02ca9add52 | |||
3f138dc152 | |||
|
d1e2257db6 | ||
0a058bad82 | |||
8d947ea81b | |||
902c45f0cd | |||
4f21c7f219 | |||
c8762d2bc2 | |||
94c91d5825 | |||
1b0c19a68f | |||
2227d5c66f | |||
47f7837ab2 | |||
f889d43f6c | |||
eecb11436e | |||
220dafeb99 | |||
8be11314c3 | |||
f89e92e88b | |||
acdb4fdd36 | |||
b73332c4a3 | |||
8fb5a1b5e8 | |||
5d494221d2 | |||
|
fcc8f67094 | ||
|
99b99de9be | ||
|
31fd9cee57 | ||
809eb9643e | |||
89b0b94d22 | |||
e6e5bfee4f | |||
9cbac89cae | |||
8f361567ff | |||
8c87eaa46f | |||
6565e3f8e3 | |||
6876c23adb | |||
d86307327c | |||
0e18a3ada9 | |||
4677fadf6f | |||
3e4cb41f7a | |||
ada9efc75d | |||
d0dd99db9a | |||
e6845326d7 | |||
61488e9876 | |||
a4af30e542 | |||
58a8949cac | |||
c179649c56 | |||
05b2b2f9b8 | |||
6430de94a7 | |||
62d3bf8742 | |||
0437e00dcd | |||
dc7bcb5233 | |||
b3bd4a5b49 | |||
4f940b44ad | |||
4d4662a634 | |||
b418d13190 | |||
48f3c440a2 | |||
342c462ed7 | |||
49b1b6f413 | |||
7c21818f00 | |||
2d0895b83d | |||
e570f5c28e | |||
|
210c199a35 | ||
|
e4a05a1812 | ||
82ae300bd9 | |||
85538f74b7 | |||
f1773997ce | |||
ae7774ac39 | |||
|
62c0410bf5 | ||
|
f7954d5159 | ||
|
30fcdfd1f6 | ||
78b651bdc4 | |||
487103375d | |||
|
acbd6e761a | ||
|
cae3defedb | ||
|
78f66d4f14 | ||
1ffff1f72c | |||
1ded5b7c01 | |||
461b96ea37 | |||
fc237db98a | |||
43daab1f7b | |||
85e8fe59a4 | |||
262fefa92f | |||
1403ee2ba5 | |||
548247188f | |||
6a34046e93 | |||
88b8ff86d1 | |||
cc258ba164 | |||
5d69e48787 | |||
cb4059e5c3 | |||
8411c909ff | |||
41fc41b1da | |||
cb5b45cbe8 | |||
4c47a35457 | |||
34dd35f2e2 | |||
6e3ce06fcf | |||
537518b66f | |||
4ad9714e8b | |||
5a936cd20b | |||
1fb14834b7 | |||
53fc5b8399 | |||
8318458805 | |||
7515415888 | |||
27a52ce166 | |||
17b6f287dc | |||
01ae50aca7 | |||
a156bd0863 | |||
b1dbd8b011 | |||
b28b4e5fba | |||
ead96f3836 | |||
27077c9d96 | |||
8a38712525 |
@@ -15,7 +15,9 @@ before_script:
|
|||||||
- curl -sS https://getcomposer.org/installer | php
|
- curl -sS https://getcomposer.org/installer | php
|
||||||
- php -d memory_limit=2G composer.phar install
|
- php -d memory_limit=2G composer.phar install
|
||||||
- php tests/app/bin/console doctrine:migrations:migrate -n
|
- php tests/app/bin/console doctrine:migrations:migrate -n
|
||||||
- php -d memory_limit=2G tests/app/bin/console doctrine:fixtures:load -n
|
- php -d memory_limit=2G tests/app/bin/console cache:clear --env=dev
|
||||||
|
- php -d memory_limit=3G tests/app/bin/console doctrine:fixtures:load -n
|
||||||
|
- php -d memory_limit=2G tests/app/bin/console cache:clear --env=test
|
||||||
- echo "before_script finished"
|
- echo "before_script finished"
|
||||||
|
|
||||||
# Bring in any services we need http://docs.gitlab.com/ee/ci/docker/using_docker_images.html#what-is-a-service
|
# Bring in any services we need http://docs.gitlab.com/ee/ci/docker/using_docker_images.html#what-is-a-service
|
||||||
|
24
.gitlab/merge_request_templates/Default merge request.md
Normal file
24
.gitlab/merge_request_templates/Default merge request.md
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
|
||||||
|
# Description of changes
|
||||||
|
|
||||||
|
<!--
|
||||||
|
describe here the change of your MR. It can be either a text, or a bullet list
|
||||||
|
for changes
|
||||||
|
-->
|
||||||
|
|
||||||
|
|
||||||
|
# Issues related
|
||||||
|
|
||||||
|
<!--
|
||||||
|
list the issues related to this MR.
|
||||||
|
|
||||||
|
It may be client issues, or dev issues
|
||||||
|
-->
|
||||||
|
|
||||||
|
* ...
|
||||||
|
* ...
|
||||||
|
|
||||||
|
# Tests
|
||||||
|
|
||||||
|
<!-- Describe tests if any, or why no tests -->
|
||||||
|
|
107
CHANGELOG.md
107
CHANGELOG.md
@@ -10,15 +10,83 @@ and this project adheres to
|
|||||||
|
|
||||||
## Unreleased
|
## Unreleased
|
||||||
|
|
||||||
* [3party]: french translation of contact and company
|
<!-- write down unreleased development here -->
|
||||||
* [3party]: show parent in list
|
|
||||||
* [3party]: change color for badge "child"
|
* [main] fix adding multiple AddresseDeRelais (combine PickAddressType with ChillCollection)
|
||||||
|
* [person]: do not suggest the current household of the person (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/51)
|
||||||
|
* [person]: display other phone numbers in view + add message in case no others phone numbers (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/184)
|
||||||
|
* unnecessary whitespace removed from person banner after person-id + double parentheses removed (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/290)
|
||||||
|
* [person]: delete accompanying period work, including related objects (cascade) (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/36)
|
||||||
|
* [address]: Display of incomplete address adjusted.
|
||||||
|
* [household]: improve relationship graph
|
||||||
|
* add form to create/edit/delete relationship link,
|
||||||
|
* improve graph refresh mechanism
|
||||||
|
* add feature to export canvas as image (png)
|
||||||
|
* [person suggest] In widget "add person", improve the pertinence of persons when one of the names starts with the pattern;
|
||||||
|
* [person] do not ask for center any more on person creation
|
||||||
|
* [3party] do not ask for center any more on 3party creation
|
||||||
|
|
||||||
|
|
||||||
|
## Test releases
|
||||||
|
|
||||||
|
### Test release 2021-11-08
|
||||||
|
|
||||||
|
* [person]: Display the name of a user when searching after a User (TMS)
|
||||||
|
* [person]: Add civility to the person
|
||||||
|
* [person]: Various improvements on the edit person form
|
||||||
|
* [person]: Set available_languages and available_countries as parameters for use in the edit person form
|
||||||
|
* [activity] Bugfix: documents can now be added to an activity.
|
||||||
|
* [tasks] improve tasks with filter order
|
||||||
|
* [tasks] refactor singleControllerTasks: limit the number of conditions from the context
|
||||||
|
* [validations] validation of accompanying period added: no duplicate participations or resources (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/60).
|
||||||
|
* [renderbox] If gender of person is not defined, no icon is displayed instead of neuter-icon (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/129).
|
||||||
|
* [confidential information] module added to blur confidential information (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/248).
|
||||||
|
* refactor `AuthorizationHelper` and `UserACLAwareRepository` to fix constructor, and separate logic for parent role helper into `ParentRoleHelper`
|
||||||
|
* [main]: filter location and locationType in backend: exclude NULL names, only active and availableToUsers
|
||||||
|
* [activity]: perform client-side validation & show/hide fields in the "new location" modal
|
||||||
|
* [person]: normalize person with CenterResolverDispatcher and handle case where center is null or multiple in PersonRenderBox
|
||||||
|
* [docstore] voter for PersonDocument and AccompanyingCourseDocument on the 2.0 way (using VoterHelperFactory)
|
||||||
|
* [docstore] add authorization check inside controller and menu
|
||||||
|
* [activity]: fix inheritance for role `ACTIVITY FULL` and add missing acl in menu
|
||||||
|
* [person] show current address in search results
|
||||||
|
* [person] show alt names in search results
|
||||||
|
* [admin]: links to activity admin section added again.
|
||||||
|
* [household]: endDate field deleted from household edit form.
|
||||||
|
* [household]: View accompanying periods of current and old household members.
|
||||||
|
* [tasks]: different layout for task list / my tasks, and fix link to tasks in alert or in warning
|
||||||
|
* [admin]: links to activity admin section added again.
|
||||||
|
* [household]: household addresses ordered by ValidFrom date and by id to show the last created address on top.
|
||||||
|
* [socialWorkAction]: display of social issue and parent issues + banner context added.
|
||||||
|
* [DBAL dependencies] Upgrade to DBAL 3.1
|
||||||
|
|
||||||
|
### Test release 2021-10-27
|
||||||
|
|
||||||
|
* [person]: delete double actions buttons on search person page
|
||||||
|
* [person]: accompanying course work: remove creation date display the list of work + handle case when end date is null
|
||||||
|
* [main]: Add new pages with a menu for managing location and location type in the admin
|
||||||
|
* [main]: Add some fixtures for location type
|
||||||
|
* [calendar]: Pass the location when transforming a calendar item (rdv) into an activity
|
||||||
|
* [calendar]: Add a user menu for "my calendar"
|
||||||
|
|
||||||
|
### Test release 2021-10-18
|
||||||
|
|
||||||
|
* [3party]: french translation of contact and company
|
||||||
|
* [3party]: show parent in list
|
||||||
|
* [3party]: change color for badge "child"
|
||||||
|
* [3party]: fix address creation
|
||||||
|
* [household members editor] finalisation of editor
|
||||||
|
* [AccompanyingCourse banner]: replace translation referrer (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/70)
|
||||||
|
* [Location]: add location system in activity and RV (calendar). User can choose in location list or create a new location.
|
||||||
|
* [household]: add relationship page with dynamic data visualisation graph
|
||||||
|
|
||||||
## Test releases
|
## Test releases
|
||||||
|
|
||||||
### Test release 2021-10-11
|
### Test release 2021-10-11
|
||||||
|
|
||||||
|
* Address: zoom on postal code geometry + fix origin of manually entered postal code
|
||||||
|
|
||||||
|
* in the Address vue component, order the postal code and street address by alphabetic and numeric order
|
||||||
|
|
||||||
* add 3 new fields to PostalCode and adapt postal code command and fixtures
|
* add 3 new fields to PostalCode and adapt postal code command and fixtures
|
||||||
|
|
||||||
* [Aside activity] Fixes for aside activity
|
* [Aside activity] Fixes for aside activity
|
||||||
@@ -38,10 +106,14 @@ and this project adheres to
|
|||||||
|
|
||||||
* [FilterOrder]: add development kit for generating filter and ordering in list
|
* [FilterOrder]: add development kit for generating filter and ordering in list
|
||||||
* [Capitalization of names] person names are capitalized on creation, on prePersist event
|
* [Capitalization of names] person names are capitalized on creation, on prePersist event
|
||||||
|
* [On-The-Fly] modale works for showing, editing and creating person or thirdparty ;
|
||||||
|
* [AccompanyingCourse Resume page] associated persons list, can see household when hover, and with show on-the-fly modale when clicking person ;
|
||||||
|
|
||||||
### test release 2021-10-04
|
### test release 2021-10-04
|
||||||
|
|
||||||
* [Household editor][UI] Update how household suggestion and addresses are picked;
|
* [Household editor][UI] Update how household suggestion and addresses are picked;
|
||||||
|
|
||||||
|
See https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/80
|
||||||
* [AddAddress] Handle address suggestion;
|
* [AddAddress] Handle address suggestion;
|
||||||
* [CenterType][Create a person] when overriding the ACL rules, allow to show a PickCenterType
|
* [CenterType][Create a person] when overriding the ACL rules, allow to show a PickCenterType
|
||||||
when no centers are reachable by the default ACL.
|
when no centers are reachable by the default ACL.
|
||||||
@@ -60,8 +132,31 @@ and this project adheres to
|
|||||||
https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/37
|
https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/37
|
||||||
https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/221
|
https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/221
|
||||||
|
|
||||||
* [On-The-Fly] modale works for showing, editing and creating person or thirdparty ;
|
* [Household editor] suggest only temporarily addresses;
|
||||||
* [AccompanyingCourse Resume page] associated persons list, can see household when hover, and with show on-the-fly modale when clicking person ;
|
See https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/82
|
||||||
|
* On-The-Fly modale works for showing, editing and creating person and thirdparty ;
|
||||||
|
* AccompanyingCourse Resume page: list associated persons by household, see household when hover, and show on-the-fly modale when clicking on person ;
|
||||||
|
* [AddAddress] Handle address suggestion;
|
||||||
|
* [AddAddress][Entity address]: add a link between address and address reference;
|
||||||
|
* [Household editor] suggest household by comparing the temporary addresses from courses;
|
||||||
|
|
||||||
## Test release yyyy-mm-dd
|
See https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/81
|
||||||
|
* On-The-Fly modale works for showing, editing and creating person and thirdparty
|
||||||
|
|
||||||
|
|
||||||
|
## Test released
|
||||||
|
|
||||||
|
<!--
|
||||||
|
|
||||||
|
Coming soon...
|
||||||
|
|
||||||
|
DO NOT ADD unreleased items here. Add them under "Unreleased" title
|
||||||
|
|
||||||
|
### Test release yyyy-mm-dd
|
||||||
|
|
||||||
|
-->
|
||||||
|
|
||||||
|
## Stable releases
|
||||||
|
|
||||||
|
No stable releases for v2+
|
||||||
|
|
||||||
|
@@ -54,6 +54,9 @@
|
|||||||
"doctrine/doctrine-fixtures-bundle": "^3.3",
|
"doctrine/doctrine-fixtures-bundle": "^3.3",
|
||||||
"fakerphp/faker": "^1.13",
|
"fakerphp/faker": "^1.13",
|
||||||
"nelmio/alice": "^3.8",
|
"nelmio/alice": "^3.8",
|
||||||
|
"phpstan/extension-installer": "^1.1",
|
||||||
|
"phpstan/phpstan": "^1.0",
|
||||||
|
"phpstan/phpstan-strict-rules": "^1.0",
|
||||||
"phpunit/phpunit": "^7.0",
|
"phpunit/phpunit": "^7.0",
|
||||||
"symfony/debug-bundle": "^5.1",
|
"symfony/debug-bundle": "^5.1",
|
||||||
"symfony/dotenv": "^5.1",
|
"symfony/dotenv": "^5.1",
|
||||||
|
1517
phpstan-baseline.neon
Normal file
1517
phpstan-baseline.neon
Normal file
File diff suppressed because it is too large
Load Diff
21
phpstan.neon.dist
Normal file
21
phpstan.neon.dist
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
parameters:
|
||||||
|
level: 1
|
||||||
|
paths:
|
||||||
|
- src/
|
||||||
|
excludePaths:
|
||||||
|
- src/Bundle/*/Tests/*
|
||||||
|
- src/Bundle/*/Test/*
|
||||||
|
- src/Bundle/*/config/*
|
||||||
|
- src/Bundle/*/migrations/*
|
||||||
|
- src/Bundle/*/translations/*
|
||||||
|
- src/Bundle/*/Resources/*
|
||||||
|
- src/Bundle/*/src/Tests/*
|
||||||
|
- src/Bundle/*/src/Test/*
|
||||||
|
- src/Bundle/*/src/config/*
|
||||||
|
- src/Bundle/*/src/migrations/*
|
||||||
|
- src/Bundle/*/src/translations/*
|
||||||
|
- src/Bundle/*/src/Resources/*
|
||||||
|
|
||||||
|
includes:
|
||||||
|
- phpstan-baseline.neon
|
||||||
|
|
@@ -242,6 +242,11 @@ class ActivityController extends AbstractController
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (array_key_exists('location', $activityData)) {
|
||||||
|
$location = $em->getRepository(\Chill\MainBundle\Entity\Location::class)->find($activityData['location']);
|
||||||
|
$entity->setLocation($location);
|
||||||
|
}
|
||||||
|
|
||||||
if (array_key_exists('comment', $activityData)) {
|
if (array_key_exists('comment', $activityData)) {
|
||||||
$comment = new CommentEmbeddable();
|
$comment = new CommentEmbeddable();
|
||||||
$comment->setComment($activityData['comment']);
|
$comment->setComment($activityData['comment']);
|
||||||
|
@@ -22,8 +22,10 @@
|
|||||||
|
|
||||||
namespace Chill\ActivityBundle\DataFixtures\ORM;
|
namespace Chill\ActivityBundle\DataFixtures\ORM;
|
||||||
|
|
||||||
|
use Chill\PersonBundle\Entity\Person;
|
||||||
use Doctrine\Common\DataFixtures\AbstractFixture;
|
use Doctrine\Common\DataFixtures\AbstractFixture;
|
||||||
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
|
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
|
||||||
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Doctrine\Persistence\ObjectManager;
|
use Doctrine\Persistence\ObjectManager;
|
||||||
use Faker\Factory as FakerFactory;
|
use Faker\Factory as FakerFactory;
|
||||||
use Chill\ActivityBundle\Entity\Activity;
|
use Chill\ActivityBundle\Entity\Activity;
|
||||||
@@ -31,25 +33,19 @@ use Chill\MainBundle\DataFixtures\ORM\LoadUsers;
|
|||||||
use Chill\ActivityBundle\DataFixtures\ORM\LoadActivityReason;
|
use Chill\ActivityBundle\DataFixtures\ORM\LoadActivityReason;
|
||||||
use Chill\ActivityBundle\DataFixtures\ORM\LoadActivityType;
|
use Chill\ActivityBundle\DataFixtures\ORM\LoadActivityType;
|
||||||
use Chill\MainBundle\DataFixtures\ORM\LoadScopes;
|
use Chill\MainBundle\DataFixtures\ORM\LoadScopes;
|
||||||
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
|
|
||||||
|
|
||||||
/**
|
class LoadActivity extends AbstractFixture implements OrderedFixtureInterface
|
||||||
* Load reports into DB
|
|
||||||
*
|
|
||||||
* @author Champs-Libres Coop
|
|
||||||
*/
|
|
||||||
class LoadActivity extends AbstractFixture implements OrderedFixtureInterface, ContainerAwareInterface
|
|
||||||
{
|
{
|
||||||
use \Symfony\Component\DependencyInjection\ContainerAwareTrait;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var \Faker\Generator
|
* @var \Faker\Generator
|
||||||
*/
|
*/
|
||||||
private $faker;
|
private $faker;
|
||||||
|
private EntityManagerInterface $em;
|
||||||
|
|
||||||
public function __construct()
|
public function __construct(EntityManagerInterface $em)
|
||||||
{
|
{
|
||||||
$this->faker = FakerFactory::create('fr_FR');
|
$this->faker = FakerFactory::create('fr_FR');
|
||||||
|
$this->em = $em;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getOrder()
|
public function getOrder()
|
||||||
@@ -88,7 +84,7 @@ class LoadActivity extends AbstractFixture implements OrderedFixtureInterface, C
|
|||||||
{
|
{
|
||||||
$reasonRef = LoadActivityReason::$references[array_rand(LoadActivityReason::$references)];
|
$reasonRef = LoadActivityReason::$references[array_rand(LoadActivityReason::$references)];
|
||||||
|
|
||||||
if (in_array($this->getReference($reasonRef)->getId(), $excludingIds)) {
|
if (in_array($this->getReference($reasonRef)->getId(), $excludingIds, true)) {
|
||||||
// we have a reason which should be excluded. Find another...
|
// we have a reason which should be excluded. Find another...
|
||||||
return $this->getRandomActivityReason($excludingIds);
|
return $this->getRandomActivityReason($excludingIds);
|
||||||
}
|
}
|
||||||
@@ -132,21 +128,17 @@ class LoadActivity extends AbstractFixture implements OrderedFixtureInterface, C
|
|||||||
|
|
||||||
public function load(ObjectManager $manager)
|
public function load(ObjectManager $manager)
|
||||||
{
|
{
|
||||||
$persons = $this->container->get('doctrine.orm.entity_manager')
|
$persons = $this->em
|
||||||
->getRepository('ChillPersonBundle:Person')
|
->getRepository(Person::class)
|
||||||
->findAll();
|
->findAll();
|
||||||
|
|
||||||
foreach($persons as $person) {
|
foreach ($persons as $person) {
|
||||||
$activityNbr = rand(0,3);
|
$activityNbr = rand(0,3);
|
||||||
$ref = 'activity_'.$person->getFullnameCanonical();
|
|
||||||
|
|
||||||
for($i = 0; $i < $activityNbr; $i ++) {
|
for ($i = 0; $i < $activityNbr; $i ++) {
|
||||||
print "Creating an activity type for : ".$person." (ref: ".$ref.") \n";
|
|
||||||
$activity = $this->newRandomActivity($person);
|
$activity = $this->newRandomActivity($person);
|
||||||
$manager->persist($activity);
|
$manager->persist($activity);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->setReference($ref, $activity);
|
|
||||||
}
|
}
|
||||||
$manager->flush();
|
$manager->flush();
|
||||||
}
|
}
|
||||||
|
@@ -87,7 +87,9 @@ class ChillActivityExtension extends Extension implements PrependExtensionInterf
|
|||||||
ActivityVoter::UPDATE => array(ActivityVoter::SEE_DETAILS),
|
ActivityVoter::UPDATE => array(ActivityVoter::SEE_DETAILS),
|
||||||
ActivityVoter::CREATE => array(ActivityVoter::SEE_DETAILS),
|
ActivityVoter::CREATE => array(ActivityVoter::SEE_DETAILS),
|
||||||
ActivityVoter::DELETE => array(ActivityVoter::SEE_DETAILS),
|
ActivityVoter::DELETE => array(ActivityVoter::SEE_DETAILS),
|
||||||
ActivityVoter::SEE_DETAILS => array(ActivityVoter::SEE)
|
ActivityVoter::SEE_DETAILS => array(ActivityVoter::SEE),
|
||||||
|
ActivityVoter::FULL => [ActivityVoter::CREATE, ActivityVoter::DELETE,
|
||||||
|
ActivityVoter::UPDATE],
|
||||||
)
|
)
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@@ -23,6 +23,7 @@ namespace Chill\ActivityBundle\Entity;
|
|||||||
use Chill\DocStoreBundle\Entity\Document;
|
use Chill\DocStoreBundle\Entity\Document;
|
||||||
use Chill\DocStoreBundle\Entity\StoredObject;
|
use Chill\DocStoreBundle\Entity\StoredObject;
|
||||||
use Chill\MainBundle\Entity\Embeddable\CommentEmbeddable;
|
use Chill\MainBundle\Entity\Embeddable\CommentEmbeddable;
|
||||||
|
use Chill\MainBundle\Entity\Location;
|
||||||
use Chill\PersonBundle\AccompanyingPeriod\SocialIssueConsistency\AccompanyingPeriodLinkedWithSocialIssuesEntityInterface;
|
use Chill\PersonBundle\AccompanyingPeriod\SocialIssueConsistency\AccompanyingPeriodLinkedWithSocialIssuesEntityInterface;
|
||||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||||
use Chill\PersonBundle\Entity\SocialWork\SocialAction;
|
use Chill\PersonBundle\Entity\SocialWork\SocialAction;
|
||||||
@@ -157,7 +158,7 @@ class Activity implements HasCenterInterface, HasScopeInterface, AccompanyingPer
|
|||||||
private ?Collection $thirdParties = null;
|
private ?Collection $thirdParties = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\ManyToMany(targetEntity="Chill\DocStoreBundle\Entity\StoredObject")
|
* @ORM\ManyToMany(targetEntity="Chill\DocStoreBundle\Entity\StoredObject", cascade={"persist"})
|
||||||
*/
|
*/
|
||||||
private Collection $documents;
|
private Collection $documents;
|
||||||
|
|
||||||
@@ -177,6 +178,13 @@ class Activity implements HasCenterInterface, HasScopeInterface, AccompanyingPer
|
|||||||
*/
|
*/
|
||||||
private string $sentReceived = '';
|
private string $sentReceived = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\ManyToOne(targetEntity="Chill\MainBundle\Entity\Location")
|
||||||
|
* @groups({"read"})
|
||||||
|
*/
|
||||||
|
private ?Location $location = null;
|
||||||
|
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->reasons = new ArrayCollection();
|
$this->reasons = new ArrayCollection();
|
||||||
@@ -555,4 +563,22 @@ class Activity implements HasCenterInterface, HasScopeInterface, AccompanyingPer
|
|||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Location|null
|
||||||
|
*/
|
||||||
|
public function getLocation(): ?Location
|
||||||
|
{
|
||||||
|
return $this->location;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Location|null $location
|
||||||
|
* @return Activity
|
||||||
|
*/
|
||||||
|
public function setLocation(?Location $location): Activity
|
||||||
|
{
|
||||||
|
$this->location = $location;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,19 +1,19 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
* Copyright (C) 2015, Champs Libres Cooperative SCRLFS, <http://www.champs-libres.coop>
|
* Copyright (C) 2015, Champs Libres Cooperative SCRLFS, <http://www.champs-libres.coop>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as
|
* it under the terms of the GNU Affero General Public License as
|
||||||
* published by the Free Software Foundation, either version 3 of the
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
* License, or (at your option) any later version.
|
* License, or (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Affero General Public License for more details.
|
* GNU Affero General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
@@ -44,7 +44,7 @@ class ActivityReason
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array
|
* @var array
|
||||||
* @ORM\Column(type="json_array")
|
* @ORM\Column(type="json")
|
||||||
*/
|
*/
|
||||||
private $name;
|
private $name;
|
||||||
|
|
||||||
@@ -108,7 +108,7 @@ class ActivityReason
|
|||||||
return $this->name;
|
return $this->name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set category of the reason. If you set to the reason an inactive
|
* Set category of the reason. If you set to the reason an inactive
|
||||||
* category, the reason will become inactive
|
* category, the reason will become inactive
|
||||||
@@ -121,7 +121,7 @@ class ActivityReason
|
|||||||
if($this->category !== $category && ! $category->getActive()) {
|
if($this->category !== $category && ! $category->getActive()) {
|
||||||
$this->setActive(False);
|
$this->setActive(False);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->category = $category;
|
$this->category = $category;
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
|
@@ -2,17 +2,17 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2015, Champs Libres Cooperative SCRLFS, <http://www.champs-libres.coop>
|
* Copyright (C) 2015, Champs Libres Cooperative SCRLFS, <http://www.champs-libres.coop>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as
|
* it under the terms of the GNU Affero General Public License as
|
||||||
* published by the Free Software Foundation, either version 3 of the
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
* License, or (at your option) any later version.
|
* License, or (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Affero General Public License for more details.
|
* GNU Affero General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
@@ -43,7 +43,7 @@ class ActivityReasonCategory
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @var string
|
* @var string
|
||||||
* @ORM\Column(type="json_array")
|
* @ORM\Column(type="json")
|
||||||
*/
|
*/
|
||||||
private $name;
|
private $name;
|
||||||
|
|
||||||
@@ -52,7 +52,7 @@ class ActivityReasonCategory
|
|||||||
* @ORM\Column(type="boolean")
|
* @ORM\Column(type="boolean")
|
||||||
*/
|
*/
|
||||||
private $active = true;
|
private $active = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Array of ActivityReason
|
* Array of ActivityReason
|
||||||
* @var ArrayCollection
|
* @var ArrayCollection
|
||||||
@@ -61,7 +61,7 @@ class ActivityReasonCategory
|
|||||||
* mappedBy="category")
|
* mappedBy="category")
|
||||||
*/
|
*/
|
||||||
private $reasons;
|
private $reasons;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ActivityReasonCategory constructor.
|
* ActivityReasonCategory constructor.
|
||||||
*/
|
*/
|
||||||
@@ -69,7 +69,7 @@ class ActivityReasonCategory
|
|||||||
{
|
{
|
||||||
$this->reasons = new ArrayCollection();
|
$this->reasons = new ArrayCollection();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
@@ -139,9 +139,9 @@ class ActivityReasonCategory
|
|||||||
$reason->setActive($active);
|
$reason->setActive($active);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->active = $active;
|
$this->active = $active;
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -44,7 +44,7 @@ class ActivityType
|
|||||||
private ?int $id;
|
private ?int $id;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\Column(type="json_array")
|
* @ORM\Column(type="json")
|
||||||
*/
|
*/
|
||||||
private array $name = [];
|
private array $name = [];
|
||||||
|
|
||||||
@@ -248,6 +248,16 @@ class ActivityType
|
|||||||
*/
|
*/
|
||||||
private string $socialActionsLabel = '';
|
private string $socialActionsLabel = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\Column(type="smallint", nullable=false, options={"default"=1})
|
||||||
|
*/
|
||||||
|
private int $locationVisible = self::FIELD_INVISIBLE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\Column(type="string", nullable=false, options={"default"=""})
|
||||||
|
*/
|
||||||
|
private string $locationLabel = '';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\Column(type="float", options={"default"="0.0"})
|
* @ORM\Column(type="float", options={"default"="0.0"})
|
||||||
*/
|
*/
|
||||||
@@ -820,4 +830,29 @@ class ActivityType
|
|||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getLocationVisible(): ?int
|
||||||
|
{
|
||||||
|
return $this->locationVisible;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setLocationVisible(int $locationVisible): self
|
||||||
|
{
|
||||||
|
$this->locationVisible = $locationVisible;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLocationLabel(): ?string
|
||||||
|
{
|
||||||
|
return $this->locationLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setLocationLabel(string $locationLabel): self
|
||||||
|
{
|
||||||
|
$this->locationLabel = $locationLabel;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -40,7 +40,7 @@ class ActivityTypeCategory
|
|||||||
private ?int $id;
|
private ?int $id;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\Column(type="json_array")
|
* @ORM\Column(type="json")
|
||||||
*/
|
*/
|
||||||
private array $name = [];
|
private array $name = [];
|
||||||
|
|
||||||
|
@@ -29,27 +29,27 @@ use Chill\MainBundle\Templating\TranslatableStringHelper;
|
|||||||
use Doctrine\ORM\Query\Expr\Join;
|
use Doctrine\ORM\Query\Expr\Join;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @author Julien Fastré <julien.fastre@champs-libres.coop>
|
* @author Julien Fastré <julien.fastre@champs-libres.coop>
|
||||||
*/
|
*/
|
||||||
class ActivityTypeAggregator implements AggregatorInterface
|
class ActivityTypeAggregator implements AggregatorInterface
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @var EntityRepository
|
* @var EntityRepository
|
||||||
*/
|
*/
|
||||||
protected $typeRepository;
|
protected $typeRepository;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @var TranslatableStringHelper
|
* @var TranslatableStringHelper
|
||||||
*/
|
*/
|
||||||
protected $stringHelper;
|
protected $stringHelper;
|
||||||
|
|
||||||
const KEY = 'activity_type_aggregator';
|
const KEY = 'activity_type_aggregator';
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
EntityRepository $typeRepository,
|
EntityRepository $typeRepository,
|
||||||
TranslatableStringHelper $stringHelper
|
TranslatableStringHelper $stringHelper
|
||||||
@@ -57,19 +57,19 @@ class ActivityTypeAggregator implements AggregatorInterface
|
|||||||
$this->typeRepository = $typeRepository;
|
$this->typeRepository = $typeRepository;
|
||||||
$this->stringHelper = $stringHelper;
|
$this->stringHelper = $stringHelper;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function alterQuery(QueryBuilder $qb, $data)
|
public function alterQuery(QueryBuilder $qb, $data)
|
||||||
{
|
{
|
||||||
// add select element
|
// add select element
|
||||||
$qb->addSelect(sprintf('IDENTITY(activity.type) AS %s', self::KEY));
|
$qb->addSelect(sprintf('IDENTITY(activity.type) AS %s', self::KEY));
|
||||||
|
|
||||||
// add the "group by" part
|
// add the "group by" part
|
||||||
$groupBy = $qb->addGroupBy(self::KEY);
|
$groupBy = $qb->addGroupBy(self::KEY);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if a join between Activity and another alias
|
* Check if a join between Activity and another alias
|
||||||
*
|
*
|
||||||
* @param Join[] $joins
|
* @param Join[] $joins
|
||||||
* @param string $alias the alias to search for
|
* @param string $alias the alias to search for
|
||||||
* @return boolean
|
* @return boolean
|
||||||
@@ -81,7 +81,7 @@ class ActivityTypeAggregator implements AggregatorInterface
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,18 +99,18 @@ class ActivityTypeAggregator implements AggregatorInterface
|
|||||||
{
|
{
|
||||||
return "Aggregate by activity type";
|
return "Aggregate by activity type";
|
||||||
}
|
}
|
||||||
|
|
||||||
public function addRole()
|
public function addRole()
|
||||||
{
|
{
|
||||||
return new Role(ActivityStatsVoter::STATS);
|
return new Role(ActivityStatsVoter::STATS);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getLabels($key, array $values, $data)
|
public function getLabels($key, array $values, $data): \Closure
|
||||||
{
|
{
|
||||||
// for performance reason, we load data from db only once
|
// for performance reason, we load data from db only once
|
||||||
$this->typeRepository->findBy(array('id' => $values));
|
$this->typeRepository->findBy(array('id' => $values));
|
||||||
|
|
||||||
return function($value) use ($data) {
|
return function($value): string {
|
||||||
if ($value === '_header') {
|
if ($value === '_header') {
|
||||||
return 'Activity type';
|
return 'Activity type';
|
||||||
}
|
}
|
||||||
@@ -120,12 +120,11 @@ class ActivityTypeAggregator implements AggregatorInterface
|
|||||||
|
|
||||||
return $this->stringHelper->localize($t->getName());
|
return $this->stringHelper->localize($t->getName());
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getQueryKeys($data)
|
public function getQueryKeys($data): array
|
||||||
{
|
{
|
||||||
return array(self::KEY);
|
return [self::KEY];
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -6,6 +6,7 @@ use Chill\ActivityBundle\Entity\Activity;
|
|||||||
use Chill\ActivityBundle\Entity\ActivityPresence;
|
use Chill\ActivityBundle\Entity\ActivityPresence;
|
||||||
use Chill\ActivityBundle\Entity\ActivityReason;
|
use Chill\ActivityBundle\Entity\ActivityReason;
|
||||||
use Chill\DocStoreBundle\Form\StoredObjectType;
|
use Chill\DocStoreBundle\Form\StoredObjectType;
|
||||||
|
use Chill\MainBundle\Entity\Location;
|
||||||
use Chill\MainBundle\Form\Type\ChillCollectionType;
|
use Chill\MainBundle\Form\Type\ChillCollectionType;
|
||||||
use Chill\MainBundle\Form\Type\CommentType;
|
use Chill\MainBundle\Form\Type\CommentType;
|
||||||
use Chill\PersonBundle\Entity\Person;
|
use Chill\PersonBundle\Entity\Person;
|
||||||
@@ -222,7 +223,7 @@ class ActivityType extends AbstractType
|
|||||||
|
|
||||||
if ($activityType->isVisible('comment')) {
|
if ($activityType->isVisible('comment')) {
|
||||||
$builder->add('comment', CommentType::class, [
|
$builder->add('comment', CommentType::class, [
|
||||||
'label' => empty($activityType->getLabel('comment'))
|
'label' => empty($activityType->getLabel('comment'))
|
||||||
? 'activity.comment' : $activityType->getLabel('comment'),
|
? 'activity.comment' : $activityType->getLabel('comment'),
|
||||||
'required' => $activityType->isRequired('comment'),
|
'required' => $activityType->isRequired('comment'),
|
||||||
]);
|
]);
|
||||||
@@ -302,6 +303,23 @@ class ActivityType extends AbstractType
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($activityType->isVisible('location')) {
|
||||||
|
$builder->add('location', HiddenType::class)
|
||||||
|
->get('location')
|
||||||
|
->addModelTransformer(new CallbackTransformer(
|
||||||
|
function (?Location $location): string {
|
||||||
|
if (null === $location) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
return $location->getId();
|
||||||
|
},
|
||||||
|
function (?string $id): ?Location {
|
||||||
|
return $this->om->getRepository(Location::class)->findOneBy(['id' => (int) $id]);
|
||||||
|
}
|
||||||
|
))
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
if ($activityType->isVisible('emergency')) {
|
if ($activityType->isVisible('emergency')) {
|
||||||
$builder->add('emergency', CheckboxType::class, [
|
$builder->add('emergency', CheckboxType::class, [
|
||||||
'label' => $activityType->getLabel('emergency'),
|
'label' => $activityType->getLabel('emergency'),
|
||||||
|
@@ -71,7 +71,7 @@ class TranslatableActivityType extends AbstractType
|
|||||||
|
|
||||||
if ($options['active_only'] === true) {
|
if ($options['active_only'] === true) {
|
||||||
$qb->where($qb->expr()->eq('at.active', ':active'));
|
$qb->where($qb->expr()->eq('at.active', ':active'));
|
||||||
$qb->setParameter('active', true, \Doctrine\DBAL\Types\Type::BOOLEAN);
|
$qb->setParameter('active', true, \Doctrine\DBAL\Types\Types::BOOLEAN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -2,29 +2,27 @@
|
|||||||
|
|
||||||
namespace Chill\ActivityBundle\Menu;
|
namespace Chill\ActivityBundle\Menu;
|
||||||
|
|
||||||
|
use Chill\ActivityBundle\Security\Authorization\ActivityVoter;
|
||||||
use Chill\MainBundle\Routing\LocalMenuBuilderInterface;
|
use Chill\MainBundle\Routing\LocalMenuBuilderInterface;
|
||||||
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
|
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
|
||||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||||
use Knp\Menu\MenuItem;
|
use Knp\Menu\MenuItem;
|
||||||
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
|
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
|
||||||
|
use Symfony\Component\Security\Core\Security;
|
||||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||||
|
|
||||||
class AccompanyingCourseMenuBuilder implements LocalMenuBuilderInterface
|
class AccompanyingCourseMenuBuilder implements LocalMenuBuilderInterface
|
||||||
{
|
{
|
||||||
protected TokenStorageInterface $tokenStorage;
|
|
||||||
|
|
||||||
protected AuthorizationHelper $authorizationHelper;
|
|
||||||
|
|
||||||
protected TranslatorInterface $translator;
|
protected TranslatorInterface $translator;
|
||||||
|
|
||||||
|
protected Security $security;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
TokenStorageInterface $tokenStorage,
|
Security $security,
|
||||||
AuthorizationHelper $authorizationHelper,
|
|
||||||
TranslatorInterface $translator
|
TranslatorInterface $translator
|
||||||
) {
|
) {
|
||||||
|
$this->security = $security;
|
||||||
$this->translator = $translator;
|
$this->translator = $translator;
|
||||||
$this->authorizationHelper = $authorizationHelper;
|
|
||||||
$this->tokenStorage = $tokenStorage;
|
|
||||||
}
|
}
|
||||||
public static function getMenuIds(): array
|
public static function getMenuIds(): array
|
||||||
{
|
{
|
||||||
@@ -35,7 +33,8 @@ class AccompanyingCourseMenuBuilder implements LocalMenuBuilderInterface
|
|||||||
{
|
{
|
||||||
$period = $parameters['accompanyingCourse'];
|
$period = $parameters['accompanyingCourse'];
|
||||||
|
|
||||||
if (AccompanyingPeriod::STEP_DRAFT !== $period->getStep()) {
|
if (AccompanyingPeriod::STEP_DRAFT !== $period->getStep()
|
||||||
|
&& $this->security->isGranted(ActivityVoter::SEE, $period)) {
|
||||||
$menu->addChild($this->translator->trans('Activity'), [
|
$menu->addChild($this->translator->trans('Activity'), [
|
||||||
'route' => 'chill_activity_activity_list',
|
'route' => 'chill_activity_activity_list',
|
||||||
'routeParameters' => [
|
'routeParameters' => [
|
||||||
|
48
src/Bundle/ChillActivityBundle/Menu/AdminMenuBuilder.php
Normal file
48
src/Bundle/ChillActivityBundle/Menu/AdminMenuBuilder.php
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Chill\ActivityBundle\Menu;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Routing\LocalMenuBuilderInterface;
|
||||||
|
use Knp\Menu\MenuItem;
|
||||||
|
use Symfony\Component\Security\Core\Security;
|
||||||
|
|
||||||
|
final class AdminMenuBuilder implements LocalMenuBuilderInterface
|
||||||
|
{
|
||||||
|
private Security $security;
|
||||||
|
|
||||||
|
public function __construct(Security $security)
|
||||||
|
{
|
||||||
|
$this->security = $security;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getMenuIds(): array
|
||||||
|
{
|
||||||
|
return ['admin_index', 'admin_section', 'admin_activity'];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function buildMenu($menuId, MenuItem $menu, array $parameters)
|
||||||
|
{
|
||||||
|
if (!$this->security->isGranted('ROLE_ADMIN')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in_array($menuId, ['admin_index', 'admin_section'])) {
|
||||||
|
$menu->addChild('Activities', [
|
||||||
|
'route' => 'chill_admin_activity_index'
|
||||||
|
])
|
||||||
|
->setExtras([
|
||||||
|
'order' => 2000,
|
||||||
|
'explain' => "Activity configuration"
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
$menu
|
||||||
|
->addChild('Activities', [
|
||||||
|
'route' => 'chill_admin_activity_index'
|
||||||
|
])
|
||||||
|
->setExtras([
|
||||||
|
'order' => '60'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -1,17 +1,20 @@
|
|||||||
<template>
|
<template>
|
||||||
<concerned-groups></concerned-groups>
|
<concerned-groups></concerned-groups>
|
||||||
<social-issues-acc></social-issues-acc>
|
<social-issues-acc></social-issues-acc>
|
||||||
|
<location></location>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import ConcernedGroups from './components/ConcernedGroups.vue';
|
import ConcernedGroups from './components/ConcernedGroups.vue';
|
||||||
import SocialIssuesAcc from './components/SocialIssuesAcc.vue';
|
import SocialIssuesAcc from './components/SocialIssuesAcc.vue';
|
||||||
|
import Location from './components/Location.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "App",
|
name: "App",
|
||||||
components: {
|
components: {
|
||||||
ConcernedGroups,
|
ConcernedGroups,
|
||||||
SocialIssuesAcc
|
SocialIssuesAcc,
|
||||||
|
Location
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@@ -3,16 +3,61 @@ import { getSocialIssues } from 'ChillPersonAssets/vuejs/AccompanyingCourse/api.
|
|||||||
/*
|
/*
|
||||||
* Load socialActions by socialIssue (id)
|
* Load socialActions by socialIssue (id)
|
||||||
*/
|
*/
|
||||||
const getSocialActionByIssue = (id) => {
|
const getSocialActionByIssue = (id) => {
|
||||||
const url = `/api/1.0/person/social/social-action/by-social-issue/${id}.json`;
|
const url = `/api/1.0/person/social/social-action/by-social-issue/${id}.json`;
|
||||||
return fetch(url)
|
return fetch(url)
|
||||||
.then(response => {
|
.then(response => {
|
||||||
if (response.ok) { return response.json(); }
|
if (response.ok) { return response.json(); }
|
||||||
throw Error('Error with request resource response');
|
throw Error('Error with request resource response');
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Load Locations
|
||||||
|
*/
|
||||||
|
const getLocations = () => {
|
||||||
|
const url = `/api/1.0/main/location.json`;
|
||||||
|
return fetch(url)
|
||||||
|
.then(response => {
|
||||||
|
if (response.ok) { return response.json(); }
|
||||||
|
throw Error('Error with request resource response');
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Load Location Types
|
||||||
|
*/
|
||||||
|
const getLocationTypes = () => {
|
||||||
|
const url = `/api/1.0/main/location-type.json`;
|
||||||
|
return fetch(url)
|
||||||
|
.then(response => {
|
||||||
|
if (response.ok) { return response.json(); }
|
||||||
|
throw Error('Error with request resource response');
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Post a Location
|
||||||
|
*/
|
||||||
|
const postLocation = (body) => {
|
||||||
|
const url = `/api/1.0/main/location.json`;
|
||||||
|
return fetch(url, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json;charset=utf-8'
|
||||||
|
},
|
||||||
|
body: JSON.stringify(body)
|
||||||
|
})
|
||||||
|
.then(response => {
|
||||||
|
if (response.ok) { return response.json(); }
|
||||||
|
throw Error('Error with request resource response');
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
export {
|
export {
|
||||||
getSocialIssues,
|
getSocialIssues,
|
||||||
getSocialActionByIssue
|
getSocialActionByIssue,
|
||||||
|
getLocations,
|
||||||
|
getLocationTypes,
|
||||||
|
postLocation
|
||||||
};
|
};
|
||||||
|
@@ -73,9 +73,12 @@ export default {
|
|||||||
addPersons: {
|
addPersons: {
|
||||||
key: 'activity',
|
key: 'activity',
|
||||||
options: {
|
options: {
|
||||||
type: ['person', 'thirdparty', 'user'], // TODO add 'user'
|
type: ['person', 'thirdparty', 'user'],
|
||||||
priority: null,
|
priority: null,
|
||||||
uniq: false,
|
uniq: false,
|
||||||
|
button: {
|
||||||
|
size: 'btn-sm'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,74 @@
|
|||||||
|
<template>
|
||||||
|
<teleport to="#location">
|
||||||
|
<div class="mb-3 row">
|
||||||
|
<label class="col-form-label col-sm-4">
|
||||||
|
{{ $t('activity.location') }}
|
||||||
|
</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
|
||||||
|
<VueMultiselect
|
||||||
|
name="selectLocation"
|
||||||
|
id="selectLocation"
|
||||||
|
label="name"
|
||||||
|
track-by="id"
|
||||||
|
open-direction="top"
|
||||||
|
:multiple="false"
|
||||||
|
:searchable="true"
|
||||||
|
:placeholder="$t('activity.choose_location')"
|
||||||
|
:custom-label="customLabel"
|
||||||
|
:options="locations"
|
||||||
|
v-model="location">
|
||||||
|
</VueMultiselect>
|
||||||
|
|
||||||
|
<new-location v-bind:locations="locations"></new-location>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</teleport>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { mapState } from "vuex";
|
||||||
|
import VueMultiselect from 'vue-multiselect';
|
||||||
|
import NewLocation from './Location/NewLocation.vue';
|
||||||
|
import { getLocations } from '../api.js';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "Location",
|
||||||
|
components: {
|
||||||
|
NewLocation,
|
||||||
|
VueMultiselect
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
locations: []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapState(['activity']),
|
||||||
|
location: {
|
||||||
|
get() {
|
||||||
|
return this.activity.location;
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
this.$store.dispatch('updateLocation', value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.getLocationsList();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getLocationsList() {
|
||||||
|
getLocations().then(response => new Promise(resolve => {
|
||||||
|
console.log('getLocations', response);
|
||||||
|
this.locations = response.results;
|
||||||
|
resolve();
|
||||||
|
}))
|
||||||
|
},
|
||||||
|
customLabel(value) {
|
||||||
|
return `${value.locationType.title.fr} ${value.name ? value.name : ''}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
@@ -0,0 +1,271 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<ul class="record_actions">
|
||||||
|
<li>
|
||||||
|
<a class="btn btn-sm btn-create" @click="openModal">
|
||||||
|
{{ $t('activity.create_new_location') }}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<teleport to="body">
|
||||||
|
<modal v-if="modal.showModal"
|
||||||
|
:modalDialogClass="modal.modalDialogClass"
|
||||||
|
@close="modal.showModal = false">
|
||||||
|
|
||||||
|
<template v-slot:header>
|
||||||
|
<h3 class="modal-title">{{ $t('activity.create_new_location') }}</h3>
|
||||||
|
</template>
|
||||||
|
<template v-slot:body>
|
||||||
|
<form>
|
||||||
|
<div class="form-floating mb-3">
|
||||||
|
<p v-if="errors.length">
|
||||||
|
<b>{{ $t('activity.errors') }}</b>
|
||||||
|
<ul>
|
||||||
|
<li v-for="error in errors" :key="error">{{ error }}</li>
|
||||||
|
</ul>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-floating mb-3">
|
||||||
|
<select class="form-select form-select-lg" id="type" required v-model="selectType">
|
||||||
|
<option selected disabled value="">{{ $t('activity.choose_location_type') }}</option>
|
||||||
|
<option v-for="t in locationTypes" :value="t" :key="t.id">
|
||||||
|
{{ t.title.fr }}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
<label>{{ $t('activity.location_fields.type') }}</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-floating mb-3">
|
||||||
|
<input class="form-control form-control-lg" id="name" v-model="inputName" placeholder />
|
||||||
|
<label for="name">{{ $t('activity.location_fields.name') }}</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<add-address
|
||||||
|
:context="addAddress.context"
|
||||||
|
:options="addAddress.options"
|
||||||
|
:addressChangedCallback="submitNewAddress"
|
||||||
|
v-if="showAddAddress"
|
||||||
|
ref="addAddress">
|
||||||
|
</add-address>
|
||||||
|
|
||||||
|
<div class="form-floating mb-3" v-if="showContactData">
|
||||||
|
<input class="form-control form-control-lg" id="phonenumber1" v-model="inputPhonenumber1" placeholder />
|
||||||
|
<label for="phonenumber1">{{ $t('activity.location_fields.phonenumber1') }}</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-floating mb-3" v-if="hasPhonenumber1">
|
||||||
|
<input class="form-control form-control-lg" id="phonenumber2" v-model="inputPhonenumber2" placeholder />
|
||||||
|
<label for="phonenumber2">{{ $t('activity.location_fields.phonenumber2') }}</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-floating mb-3" v-if="showContactData">
|
||||||
|
<input class="form-control form-control-lg" id="email" v-model="inputEmail" placeholder />
|
||||||
|
<label for="email">{{ $t('activity.location_fields.email') }}</label>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</template>
|
||||||
|
<template v-slot:footer>
|
||||||
|
<button class="btn btn-save"
|
||||||
|
@click.prevent="saveNewLocation"
|
||||||
|
>
|
||||||
|
{{ $t('action.save') }}
|
||||||
|
</button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
</modal>
|
||||||
|
</teleport>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Modal from 'ChillMainAssets/vuejs/_components/Modal.vue';
|
||||||
|
import AddAddress from "ChillMainAssets/vuejs/Address/components/AddAddress.vue";
|
||||||
|
import { mapState } from "vuex";
|
||||||
|
import { getLocationTypes, postLocation } from "../../api";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "NewLocation",
|
||||||
|
components: {
|
||||||
|
Modal,
|
||||||
|
AddAddress,
|
||||||
|
},
|
||||||
|
props: ['locations'],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
errors: [],
|
||||||
|
selected: {
|
||||||
|
type: null,
|
||||||
|
name: null,
|
||||||
|
addressId: null,
|
||||||
|
phonenumber1: null,
|
||||||
|
phonenumber2: null,
|
||||||
|
email: null,
|
||||||
|
},
|
||||||
|
locationTypes: [],
|
||||||
|
modal: {
|
||||||
|
showModal: false,
|
||||||
|
modalDialogClass: "modal-dialog-scrollable modal-xl"
|
||||||
|
},
|
||||||
|
addAddress: {
|
||||||
|
options: {
|
||||||
|
button: {
|
||||||
|
text: { create: 'activity.create_address', edit: 'activity.edit_address' },
|
||||||
|
size: 'btn-sm'
|
||||||
|
},
|
||||||
|
title: { create: 'activity.create_address', edit: 'activity.edit_address' },
|
||||||
|
},
|
||||||
|
context: {
|
||||||
|
target: { //name, id
|
||||||
|
},
|
||||||
|
edit: false,
|
||||||
|
addressId: null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapState(['activity']),
|
||||||
|
selectType: {
|
||||||
|
get() {
|
||||||
|
return this.selected.type;
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
this.selected.type = value;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
inputName: {
|
||||||
|
get() {
|
||||||
|
return this.selected.name;
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
this.selected.name = value;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
inputEmail: {
|
||||||
|
get() {
|
||||||
|
return this.selected.email;
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
this.selected.email = value;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
inputPhonenumber1: {
|
||||||
|
get() {
|
||||||
|
return this.selected.phonenumber1;
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
this.selected.phonenumber1 = value;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
inputPhonenumber2: {
|
||||||
|
get() {
|
||||||
|
return this.selected.phonenumber2;
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
this.selected.phonenumber2 = value;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
hasPhonenumber1() {
|
||||||
|
return this.selected.phonenumber1 !== null && this.selected.phonenumber1 !== "";
|
||||||
|
},
|
||||||
|
showAddAddress() {
|
||||||
|
let cond = false;
|
||||||
|
if (this.selected.type) {
|
||||||
|
if (this.selected.type.addressRequired !== 'never') {
|
||||||
|
cond = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cond;
|
||||||
|
},
|
||||||
|
showContactData() {
|
||||||
|
let cond = false;
|
||||||
|
if (this.selected.type) {
|
||||||
|
if (this.selected.type.contactData !== 'never') {
|
||||||
|
cond = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cond;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.getLocationTypesList();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
checkForm() {
|
||||||
|
let cond = true;
|
||||||
|
this.errors = [];
|
||||||
|
if (!this.selected.type) {
|
||||||
|
this.errors.push('Type de localisation requis');
|
||||||
|
cond = false;
|
||||||
|
} else {
|
||||||
|
if (this.selected.type.addressRequired === 'required' && !this.selected.addressId) {
|
||||||
|
this.errors.push('Adresse requise');
|
||||||
|
cond = false;
|
||||||
|
}
|
||||||
|
if (this.selected.type.contactData === 'required' && !this.selected.phonenumber1) {
|
||||||
|
this.errors.push('Numéro de téléphone requis');
|
||||||
|
cond = false;
|
||||||
|
}
|
||||||
|
if (this.selected.type.contactData === 'required' && !this.selected.email) {
|
||||||
|
this.errors.push('Adresse email requise');
|
||||||
|
cond = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cond;
|
||||||
|
},
|
||||||
|
getLocationTypesList() {
|
||||||
|
getLocationTypes().then(response => new Promise(resolve => {
|
||||||
|
console.log('getLocationTypes', response);
|
||||||
|
this.locationTypes = response.results.filter(t => t.availableForUsers === true);
|
||||||
|
resolve();
|
||||||
|
}))
|
||||||
|
},
|
||||||
|
openModal() {
|
||||||
|
this.modal.showModal = true;
|
||||||
|
},
|
||||||
|
saveNewLocation() {
|
||||||
|
if (this.checkForm()) {
|
||||||
|
console.log('saveNewLocation', this.selected);
|
||||||
|
let body = {
|
||||||
|
type: 'location',
|
||||||
|
name: this.selected.name,
|
||||||
|
locationType: {
|
||||||
|
id: this.selected.type.id,
|
||||||
|
type: 'location-type'
|
||||||
|
},
|
||||||
|
phonenumber1: this.selected.phonenumber1,
|
||||||
|
phonenumber2: this.selected.phonenumber2,
|
||||||
|
email: this.selected.email,
|
||||||
|
};
|
||||||
|
if (this.selected.addressId) {
|
||||||
|
body = Object.assign(body, {
|
||||||
|
address: {
|
||||||
|
id: this.selected.addressId
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
postLocation(body)
|
||||||
|
.then(
|
||||||
|
location => new Promise(resolve => {
|
||||||
|
console.log('postLocation', location);
|
||||||
|
this.locations.push(location);
|
||||||
|
this.$store.dispatch('updateLocation', location);
|
||||||
|
resolve();
|
||||||
|
this.modal.showModal = false;
|
||||||
|
})
|
||||||
|
).catch(
|
||||||
|
err => {
|
||||||
|
this.errors.push(err.message);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
},
|
||||||
|
submitNewAddress(payload) {
|
||||||
|
console.log('submitNewAddress', payload);
|
||||||
|
this.selected.addressId = payload.addressId;
|
||||||
|
this.addAddress.context.addressId = payload.addressId;
|
||||||
|
this.addAddress.context.edit = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
@@ -1,12 +1,12 @@
|
|||||||
<template>
|
<template>
|
||||||
<teleport to="#social-issues-acc">
|
<teleport to="#social-issues-acc">
|
||||||
|
|
||||||
<div class="mb-3 row">
|
<div class="mb-3 row">
|
||||||
<div class="col-4">
|
<div class="col-4">
|
||||||
<label class="col-form-label">{{ $t('activity.social_issues') }}</label>
|
<label class="col-form-label">{{ $t('activity.social_issues') }}</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-8">
|
<div class="col-8">
|
||||||
|
|
||||||
<check-social-issue
|
<check-social-issue
|
||||||
v-for="issue in socialIssuesList"
|
v-for="issue in socialIssuesList"
|
||||||
v-bind:key="issue.id"
|
v-bind:key="issue.id"
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
v-bind:selection="socialIssuesSelected"
|
v-bind:selection="socialIssuesSelected"
|
||||||
@updateSelected="updateIssuesSelected">
|
@updateSelected="updateIssuesSelected">
|
||||||
</check-social-issue>
|
</check-social-issue>
|
||||||
|
|
||||||
<div class="my-3">
|
<div class="my-3">
|
||||||
<VueMultiselect
|
<VueMultiselect
|
||||||
name="otherIssues"
|
name="otherIssues"
|
||||||
@@ -28,16 +28,15 @@
|
|||||||
v-bind:taggable="false"
|
v-bind:taggable="false"
|
||||||
v-bind:multiple="false"
|
v-bind:multiple="false"
|
||||||
v-bind:searchable="true"
|
v-bind:searchable="true"
|
||||||
v-bind:allow-empty="true"
|
v-bind:allow-empty="true"
|
||||||
v-bind:show-labels="false"
|
v-bind:show-labels="false"
|
||||||
v-bind:loading="issueIsLoading"
|
v-bind:loading="issueIsLoading"
|
||||||
v-bind:placeholder="$t('activity.choose_other_social_issue')"
|
v-bind:placeholder="$t('activity.choose_other_social_issue')"
|
||||||
v-bind:options="socialIssuesOther"
|
v-bind:options="socialIssuesOther"
|
||||||
v-model="value"
|
|
||||||
@select="addIssueInList">
|
@select="addIssueInList">
|
||||||
</VueMultiselect>
|
</VueMultiselect>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -46,11 +45,11 @@
|
|||||||
<label class="col-form-label">{{ $t('activity.social_actions') }}</label>
|
<label class="col-form-label">{{ $t('activity.social_actions') }}</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-8">
|
<div class="col-8">
|
||||||
|
|
||||||
<div v-if="actionIsLoading === true">
|
<div v-if="actionIsLoading === true">
|
||||||
<i class="chill-green fa fa-circle-o-notch fa-spin fa-lg"></i>
|
<i class="chill-green fa fa-circle-o-notch fa-spin fa-lg"></i>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<check-social-action
|
<check-social-action
|
||||||
v-if="socialIssuesSelected.length || socialActionsSelected.length"
|
v-if="socialIssuesSelected.length || socialActionsSelected.length"
|
||||||
v-for="action in socialActionsList"
|
v-for="action in socialActionsList"
|
||||||
@@ -59,19 +58,18 @@
|
|||||||
v-bind:selection="socialActionsSelected"
|
v-bind:selection="socialActionsSelected"
|
||||||
@updateSelected="updateActionsSelected">
|
@updateSelected="updateActionsSelected">
|
||||||
</check-social-action>
|
</check-social-action>
|
||||||
|
|
||||||
<span v-else class="inline-choice chill-no-data-statement mt-3">
|
<span v-else class="inline-choice chill-no-data-statement mt-3">
|
||||||
{{ $t('activity.select_first_a_social_issue') }}
|
{{ $t('activity.select_first_a_social_issue') }}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</teleport>
|
</teleport>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { readonly } from 'vue';
|
|
||||||
import VueMultiselect from 'vue-multiselect';
|
import VueMultiselect from 'vue-multiselect';
|
||||||
import CheckSocialIssue from './SocialIssuesAcc/CheckSocialIssue.vue';
|
import CheckSocialIssue from './SocialIssuesAcc/CheckSocialIssue.vue';
|
||||||
import CheckSocialAction from './SocialIssuesAcc/CheckSocialAction.vue';
|
import CheckSocialAction from './SocialIssuesAcc/CheckSocialAction.vue';
|
||||||
@@ -113,7 +111,7 @@ export default {
|
|||||||
this.issueIsLoading = true;
|
this.issueIsLoading = true;
|
||||||
getSocialIssues().then(response => new Promise((resolve, reject) => {
|
getSocialIssues().then(response => new Promise((resolve, reject) => {
|
||||||
this.$store.commit('updateIssuesOther', response.results);
|
this.$store.commit('updateIssuesOther', response.results);
|
||||||
|
|
||||||
/* Add in list the issues already associated (if not yet listed)
|
/* Add in list the issues already associated (if not yet listed)
|
||||||
*/
|
*/
|
||||||
this.socialIssuesSelected.forEach(issue => {
|
this.socialIssuesSelected.forEach(issue => {
|
||||||
@@ -121,34 +119,34 @@ export default {
|
|||||||
this.$store.commit('addIssueInList', issue);
|
this.$store.commit('addIssueInList', issue);
|
||||||
}
|
}
|
||||||
}, this);
|
}, this);
|
||||||
|
|
||||||
/* Remove from multiselect the issues that are not yet in checkbox list
|
/* Remove from multiselect the issues that are not yet in checkbox list
|
||||||
*/
|
*/
|
||||||
this.socialIssuesList.forEach(issue => {
|
this.socialIssuesList.forEach(issue => {
|
||||||
this.$store.commit('removeIssueInOther', issue);
|
this.$store.commit('removeIssueInOther', issue);
|
||||||
}, this);
|
}, this);
|
||||||
|
|
||||||
/* Filter issues
|
/* Filter issues
|
||||||
*/
|
*/
|
||||||
this.$store.commit('filterList', 'issues');
|
this.$store.commit('filterList', 'issues');
|
||||||
|
|
||||||
/* Add in list the actions already associated (if not yet listed)
|
/* Add in list the actions already associated (if not yet listed)
|
||||||
*/
|
*/
|
||||||
this.socialActionsSelected.forEach(action => {
|
this.socialActionsSelected.forEach(action => {
|
||||||
this.$store.commit('addActionInList', action);
|
this.$store.commit('addActionInList', action);
|
||||||
}, this);
|
}, this);
|
||||||
|
|
||||||
/* Filter issues
|
/* Filter issues
|
||||||
*/
|
*/
|
||||||
this.$store.commit('filterList', 'actions');
|
this.$store.commit('filterList', 'actions');
|
||||||
|
|
||||||
this.issueIsLoading = false;
|
this.issueIsLoading = false;
|
||||||
resolve();
|
resolve();
|
||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|
||||||
/* When choosing an issue in multiselect, add it in checkboxes (as selected),
|
/* When choosing an issue in multiselect, add it in checkboxes (as selected),
|
||||||
remove it from multiselect, and add socialActions concerned
|
remove it from multiselect, and add socialActions concerned
|
||||||
*/
|
*/
|
||||||
addIssueInList(value) {
|
addIssueInList(value) {
|
||||||
@@ -171,30 +169,30 @@ export default {
|
|||||||
//console.log('updateActionsSelected', actions);
|
//console.log('updateActionsSelected', actions);
|
||||||
this.$store.dispatch('updateActionsSelected', actions);
|
this.$store.dispatch('updateActionsSelected', actions);
|
||||||
},
|
},
|
||||||
/* Add socialActions concerned: after reset, loop on each issue selected
|
/* Add socialActions concerned: after reset, loop on each issue selected
|
||||||
to get social actions concerned
|
to get social actions concerned
|
||||||
*/
|
*/
|
||||||
updateActionsList() {
|
updateActionsList() {
|
||||||
//console.log('updateActionsList');
|
//console.log('updateActionsList');
|
||||||
this.resetActionsList();
|
this.resetActionsList();
|
||||||
this.socialIssuesSelected.forEach(item => {
|
this.socialIssuesSelected.forEach(item => {
|
||||||
|
|
||||||
this.actionIsLoading = true;
|
this.actionIsLoading = true;
|
||||||
getSocialActionByIssue(item.id)
|
getSocialActionByIssue(item.id)
|
||||||
.then(actions => new Promise((resolve, reject) => {
|
.then(actions => new Promise((resolve, reject) => {
|
||||||
|
|
||||||
actions.results.forEach(action => {
|
actions.results.forEach(action => {
|
||||||
this.$store.commit('addActionInList', action);
|
this.$store.commit('addActionInList', action);
|
||||||
}, this);
|
}, this);
|
||||||
|
|
||||||
this.$store.commit('filterList', 'actions');
|
this.$store.commit('filterList', 'actions');
|
||||||
|
|
||||||
this.actionIsLoading = false;
|
this.actionIsLoading = false;
|
||||||
resolve();
|
resolve();
|
||||||
}));
|
}));
|
||||||
}, this);
|
}, this);
|
||||||
},
|
},
|
||||||
/* Reset socialActions List: flush list and restore selected actions
|
/* Reset socialActions List: flush list and restore selected actions
|
||||||
*/
|
*/
|
||||||
resetActionsList() {
|
resetActionsList() {
|
||||||
this.$store.commit('resetActionsList');
|
this.$store.commit('resetActionsList');
|
||||||
@@ -207,7 +205,7 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style src="vue-multiselect/dist/vue-multiselect.css"></style>
|
<style src="vue-multiselect/dist/vue-multiselect.css"></style>
|
||||||
<style lang="scss">
|
<style lang="scss" scoped>
|
||||||
span.multiselect__single {
|
span.multiselect__single {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
@@ -1,14 +1,15 @@
|
|||||||
import { personMessages } from 'ChillPersonAssets/vuejs/_js/i18n'
|
import { personMessages } from 'ChillPersonAssets/vuejs/_js/i18n'
|
||||||
|
|
||||||
const appMessages = {
|
const activityMessages = {
|
||||||
fr: {
|
fr: {
|
||||||
activity: {
|
activity: {
|
||||||
//
|
//
|
||||||
|
errors: "Le formulaire contient des erreurs",
|
||||||
social_issues: "Problématiques sociales",
|
social_issues: "Problématiques sociales",
|
||||||
choose_other_social_issue: "Ajouter une autre problématique sociale...",
|
choose_other_social_issue: "Ajouter une autre problématique sociale...",
|
||||||
social_actions: "Actions d'accompagnement",
|
social_actions: "Actions d'accompagnement",
|
||||||
select_first_a_social_issue: "Sélectionnez d'abord une problématique sociale",
|
select_first_a_social_issue: "Sélectionnez d'abord une problématique sociale",
|
||||||
|
|
||||||
//
|
//
|
||||||
add_persons: "Ajouter des personnes concernées",
|
add_persons: "Ajouter des personnes concernées",
|
||||||
bloc_persons: "Usagers",
|
bloc_persons: "Usagers",
|
||||||
@@ -16,12 +17,28 @@ const appMessages = {
|
|||||||
bloc_persons_not_associated: "Tiers non-pro.",
|
bloc_persons_not_associated: "Tiers non-pro.",
|
||||||
bloc_thirdparty: "Tiers professionnels",
|
bloc_thirdparty: "Tiers professionnels",
|
||||||
bloc_users: "T(M)S",
|
bloc_users: "T(M)S",
|
||||||
|
|
||||||
|
//
|
||||||
|
location: "Localisation",
|
||||||
|
choose_location: "Choisissez une localisation",
|
||||||
|
choose_location_type: "Choisissez un type de localisation",
|
||||||
|
create_new_location: "Créer une nouvelle localisation",
|
||||||
|
location_fields: {
|
||||||
|
name: "Nom",
|
||||||
|
type: "Type",
|
||||||
|
phonenumber1: "Téléphone",
|
||||||
|
phonenumber2: "Autre téléphone",
|
||||||
|
email: "Adresse courriel",
|
||||||
|
},
|
||||||
|
create_address: 'Créer une adresse',
|
||||||
|
edit_address: "Modifier l'adresse"
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Object.assign(appMessages.fr, personMessages.fr);
|
Object.assign(activityMessages.fr, personMessages.fr);
|
||||||
|
|
||||||
export {
|
export {
|
||||||
appMessages
|
activityMessages
|
||||||
};
|
};
|
||||||
|
@@ -1,11 +1,11 @@
|
|||||||
import { createApp } from 'vue';
|
import { createApp } from 'vue';
|
||||||
import { _createI18n } from 'ChillMainAssets/vuejs/_js/i18n'
|
import { _createI18n } from 'ChillMainAssets/vuejs/_js/i18n'
|
||||||
import { appMessages } from './i18n'
|
import { activityMessages } from './i18n'
|
||||||
import store from './store'
|
import store from './store'
|
||||||
|
|
||||||
import App from './App.vue';
|
import App from './App.vue';
|
||||||
|
|
||||||
const i18n = _createI18n(appMessages);
|
const i18n = _createI18n(activityMessages);
|
||||||
|
|
||||||
const app = createApp({
|
const app = createApp({
|
||||||
template: `<app></app>`,
|
template: `<app></app>`,
|
||||||
|
@@ -114,6 +114,10 @@ const store = createStore({
|
|||||||
state.activity.users = state.activity.users.filter(user => user !== payload);
|
state.activity.users = state.activity.users.filter(user => user !== payload);
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
|
},
|
||||||
|
updateLocation(state, value) {
|
||||||
|
console.log('### mutation: updateLocation', value);
|
||||||
|
state.activity.location = value;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
@@ -173,6 +177,12 @@ const store = createStore({
|
|||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
commit('removePersonInvolved', payload);
|
commit('removePersonInvolved', payload);
|
||||||
|
},
|
||||||
|
updateLocation({ commit }, value) {
|
||||||
|
console.log('### action: updateLocation', value);
|
||||||
|
let hiddenLocation = document.getElementById("chill_activitybundle_activity_location");
|
||||||
|
hiddenLocation.value = value.id;
|
||||||
|
commit('updateLocation', value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@@ -40,7 +40,6 @@
|
|||||||
},
|
},
|
||||||
{ 'title': 'Users concerned'|trans,
|
{ 'title': 'Users concerned'|trans,
|
||||||
'items': entity.users,
|
'items': entity.users,
|
||||||
'path' : 'admin_user_show',
|
|
||||||
'key' : 'id'
|
'key' : 'id'
|
||||||
},
|
},
|
||||||
] %}
|
] %}
|
||||||
@@ -58,6 +57,7 @@
|
|||||||
<ul class="list-content">
|
<ul class="list-content">
|
||||||
{% for item in bloc.items %}
|
{% for item in bloc.items %}
|
||||||
<li>
|
<li>
|
||||||
|
{% if bloc.path is defined %}
|
||||||
<a href="{{ _self.href(bloc.path, bloc.key, item.id) }}">
|
<a href="{{ _self.href(bloc.path, bloc.key, item.id) }}">
|
||||||
<span class="{% if (badge_person is defined and badge_person == true) %}badge-person{% else %}badge bg-primary{% endif %}">
|
<span class="{% if (badge_person is defined and badge_person == true) %}badge-person{% else %}badge bg-primary{% endif %}">
|
||||||
{{ item|chill_entity_render_box({
|
{{ item|chill_entity_render_box({
|
||||||
@@ -66,6 +66,14 @@
|
|||||||
}) }}
|
}) }}
|
||||||
</span>
|
</span>
|
||||||
</a>
|
</a>
|
||||||
|
{% else %}
|
||||||
|
<span class="{% if (badge_person is defined and badge_person == true) %}badge-person{% else %}badge bg-primary{% endif %}">
|
||||||
|
{{ item|chill_entity_render_box({
|
||||||
|
'render': 'raw',
|
||||||
|
'addAltNames': false
|
||||||
|
}) }}
|
||||||
|
</span>
|
||||||
|
{% endif %}
|
||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
@@ -85,6 +93,7 @@
|
|||||||
<ul class="list-content">
|
<ul class="list-content">
|
||||||
{% for item in bloc.items %}
|
{% for item in bloc.items %}
|
||||||
<li>
|
<li>
|
||||||
|
{% if bloc.path is defined %}
|
||||||
<a href="{{ _self.href(bloc.path, bloc.key, item.id) }}">
|
<a href="{{ _self.href(bloc.path, bloc.key, item.id) }}">
|
||||||
<span class="{% if (badge_person is defined and badge_person == true) %}badge-person{% else %}badge bg-primary{% endif %}">
|
<span class="{% if (badge_person is defined and badge_person == true) %}badge-person{% else %}badge bg-primary{% endif %}">
|
||||||
{{ item|chill_entity_render_box({
|
{{ item|chill_entity_render_box({
|
||||||
@@ -93,6 +102,12 @@
|
|||||||
}) }}
|
}) }}
|
||||||
</span>
|
</span>
|
||||||
</a>
|
</a>
|
||||||
|
{% else %}
|
||||||
|
{{ item|chill_entity_render_box({
|
||||||
|
'render': 'raw',
|
||||||
|
'addAltNames': false
|
||||||
|
}) }}
|
||||||
|
{% endif %}
|
||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
@@ -114,12 +129,19 @@
|
|||||||
{% for item in bloc.items %}
|
{% for item in bloc.items %}
|
||||||
|
|
||||||
<span class="wl-item {% if (badge_person is defined and badge_person == true) %}badge-person{% else %}badge bg-primary{% endif %}">
|
<span class="wl-item {% if (badge_person is defined and badge_person == true) %}badge-person{% else %}badge bg-primary{% endif %}">
|
||||||
|
{% if bloc.path is defined %}
|
||||||
<a href="{{ _self.href(bloc.path, bloc.key, item.id) }}">
|
<a href="{{ _self.href(bloc.path, bloc.key, item.id) }}">
|
||||||
{{ item|chill_entity_render_box({
|
{{ item|chill_entity_render_box({
|
||||||
'render': 'raw',
|
'render': 'raw',
|
||||||
'addAltNames': false
|
'addAltNames': false
|
||||||
}) }}
|
}) }}
|
||||||
</a>
|
</a>
|
||||||
|
{% else %}
|
||||||
|
{{ item|chill_entity_render_box({
|
||||||
|
'render': 'raw',
|
||||||
|
'addAltNames': false
|
||||||
|
}) }}
|
||||||
|
{% endif %}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
@@ -10,7 +10,7 @@
|
|||||||
'title' : 'Remove activity'|trans,
|
'title' : 'Remove activity'|trans,
|
||||||
'confirm_question' : 'Are you sure you want to remove the activity about "%name%" ?'|trans({ '%name%' : accompanyingCourse.id } ),
|
'confirm_question' : 'Are you sure you want to remove the activity about "%name%" ?'|trans({ '%name%' : accompanyingCourse.id } ),
|
||||||
'cancel_route' : 'chill_activity_activity_list',
|
'cancel_route' : 'chill_activity_activity_list',
|
||||||
'cancel_parameters' : { 'accompanying_course_id' : accompanyingCourse.id, 'id' : activity.id },
|
'cancel_parameters' : { 'accompanying_period_id' : accompanyingCourse.id, 'id' : activity.id },
|
||||||
'form' : delete_form
|
'form' : delete_form
|
||||||
} ) }}
|
} ) }}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@@ -54,7 +54,10 @@
|
|||||||
{{ form_row(edit_form.date) }}
|
{{ form_row(edit_form.date) }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{# TODO .. location #}
|
{%- if edit_form.location is defined -%}
|
||||||
|
{{ form_row(edit_form.location) }}
|
||||||
|
<div id="location"></div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
{%- if edit_form.durationTime is defined -%}
|
{%- if edit_form.durationTime is defined -%}
|
||||||
{{ form_row(edit_form.durationTime) }}
|
{{ form_row(edit_form.durationTime) }}
|
||||||
|
@@ -6,10 +6,10 @@
|
|||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="activity-edit">
|
<div class="activity-edit">
|
||||||
|
|
||||||
<div id="activity"></div> {# <=== vue component #}
|
<div id="activity"></div> {# <=== vue component #}
|
||||||
{% include 'ChillActivityBundle:Activity:edit.html.twig' %}
|
{% include 'ChillActivityBundle:Activity:edit.html.twig' %}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
@@ -18,10 +18,10 @@
|
|||||||
{{ encore_entry_link_tags('mod_async_upload') }}
|
{{ encore_entry_link_tags('mod_async_upload') }}
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
window.addEventListener('DOMContentLoaded', function (e) {
|
window.addEventListener('DOMContentLoaded', function (e) {
|
||||||
chill.displayAlertWhenLeavingModifiedForm('form[name="{{ edit_form.vars.form.vars.name }}"]',
|
chill.displayAlertWhenLeavingModifiedForm('form[name="{{ edit_form.vars.form.vars.name }}"]',
|
||||||
'{{ "You are going to leave a page with unsubmitted data. Are you sure you want to leave ?"|trans }}');
|
'{{ "You are going to leave a page with unsubmitted data. Are you sure you want to leave ?"|trans }}');
|
||||||
});
|
});
|
||||||
window.activity = {{ activity_json|json_encode|raw }};
|
window.activity = {{ activity_json|json_encode|raw }};
|
||||||
</script>
|
</script>
|
||||||
{{ encore_entry_script_tags('vue_activity') }}
|
{{ encore_entry_script_tags('vue_activity') }}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@@ -22,10 +22,10 @@
|
|||||||
|
|
||||||
{% block personcontent %}
|
{% block personcontent %}
|
||||||
<div class="activity-edit">
|
<div class="activity-edit">
|
||||||
|
|
||||||
<div id="activity"></div> {# <=== vue component #}
|
<div id="activity"></div> {# <=== vue component #}
|
||||||
{% include 'ChillActivityBundle:Activity:edit.html.twig' %}
|
{% include 'ChillActivityBundle:Activity:edit.html.twig' %}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
@@ -33,7 +33,7 @@
|
|||||||
{{ encore_entry_link_tags('mod_async_upload') }}
|
{{ encore_entry_link_tags('mod_async_upload') }}
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
window.addEventListener('DOMContentLoaded', function (e) {
|
window.addEventListener('DOMContentLoaded', function (e) {
|
||||||
chill.displayAlertWhenLeavingModifiedForm('form[name="{{ edit_form.vars.form.vars.name }}"]',
|
chill.displayAlertWhenLeavingModifiedForm('form[name="{{ edit_form.vars.form.vars.name }}"]',
|
||||||
'{{ "You are going to leave a page with unsubmitted data. Are you sure you want to leave ?"|trans }}');
|
'{{ "You are going to leave a page with unsubmitted data. Are you sure you want to leave ?"|trans }}');
|
||||||
});
|
});
|
||||||
window.activity = {{ activity_json|json_encode|raw }};
|
window.activity = {{ activity_json|json_encode|raw }};
|
||||||
|
@@ -55,7 +55,10 @@
|
|||||||
{{ form_row(form.date) }}
|
{{ form_row(form.date) }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{# TODO .. location #}
|
{%- if form.location is defined -%}
|
||||||
|
{{ form_row(form.location) }}
|
||||||
|
<div id="location"></div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
{%- if form.durationTime is defined -%}
|
{%- if form.durationTime is defined -%}
|
||||||
{{ form_row(form.durationTime) }}
|
{{ form_row(form.durationTime) }}
|
||||||
|
@@ -6,10 +6,10 @@
|
|||||||
|
|
||||||
{% block personcontent %}
|
{% block personcontent %}
|
||||||
<div class="activity-new">
|
<div class="activity-new">
|
||||||
|
|
||||||
<div id="activity"></div> {# <=== vue component #}
|
<div id="activity"></div> {# <=== vue component #}
|
||||||
{% include 'ChillActivityBundle:Activity:new.html.twig' with {'context': 'person'} %}
|
{% include 'ChillActivityBundle:Activity:new.html.twig' with {'context': 'person'} %}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
{{ encore_entry_link_tags('mod_async_upload') }}
|
{{ encore_entry_link_tags('mod_async_upload') }}
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
window.addEventListener('DOMContentLoaded', function (e) {
|
window.addEventListener('DOMContentLoaded', function (e) {
|
||||||
chill.displayAlertWhenLeavingUnsubmittedForm('form[name="{{ form.vars.form.vars.name }}"]',
|
chill.displayAlertWhenLeavingUnsubmittedForm('form[name="{{ form.vars.form.vars.name }}"]',
|
||||||
'{{ "You are going to leave a page with unsubmitted data. Are you sure you want to leave ?"|trans }}');
|
'{{ "You are going to leave a page with unsubmitted data. Are you sure you want to leave ?"|trans }}');
|
||||||
});
|
});
|
||||||
window.activity = {{ activity_json|json_encode|raw }};
|
window.activity = {{ activity_json|json_encode|raw }};
|
||||||
|
@@ -62,6 +62,21 @@
|
|||||||
<dt class="inline">{{ 'Date'|trans }}</dt>
|
<dt class="inline">{{ 'Date'|trans }}</dt>
|
||||||
<dd>{{ entity.date|format_date('long') }}</dd>
|
<dd>{{ entity.date|format_date('long') }}</dd>
|
||||||
|
|
||||||
|
{% if t.locationVisible %}
|
||||||
|
<dt class="inline">{{ 'Activity location'|trans }}</dt>
|
||||||
|
<dd>
|
||||||
|
{% if entity.location is not null %}
|
||||||
|
<p>
|
||||||
|
<span>{{ entity.location.locationType.title|localize_translatable_string }}</span>
|
||||||
|
{{ entity.location.name }}
|
||||||
|
</p>
|
||||||
|
{{ entity.location.address|chill_entity_render_box }}
|
||||||
|
{% else %}
|
||||||
|
<span class="chill-no-data-statement">{{ 'No address given'|trans }}</span>
|
||||||
|
{% endif %}
|
||||||
|
</dd>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
{% if t.durationTimeVisible %}
|
{% if t.durationTimeVisible %}
|
||||||
<dt class="inline">{{ 'Duration Time'|trans }}</dt>
|
<dt class="inline">{{ 'Duration Time'|trans }}</dt>
|
||||||
<dd>{% if entity.durationTime is not null %}
|
<dd>{% if entity.durationTime is not null %}
|
||||||
|
@@ -1,4 +1,6 @@
|
|||||||
services:
|
services:
|
||||||
Chill\ActivityBundle\DataFixtures\ORM\:
|
Chill\ActivityBundle\DataFixtures\ORM\:
|
||||||
|
autowire: true
|
||||||
|
autoconfigure: true
|
||||||
resource: ../../DataFixtures/ORM
|
resource: ../../DataFixtures/ORM
|
||||||
tags: [ 'doctrine.fixture.orm' ]
|
tags: [ 'doctrine.fixture.orm' ]
|
||||||
|
@@ -4,7 +4,7 @@ namespace Chill\Migrations\Activity;
|
|||||||
|
|
||||||
use Doctrine\Migrations\AbstractMigration;
|
use Doctrine\Migrations\AbstractMigration;
|
||||||
use Doctrine\DBAL\Schema\Schema;
|
use Doctrine\DBAL\Schema\Schema;
|
||||||
use Doctrine\DBAL\Types\Type;
|
use Doctrine\DBAL\Types\Types;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add an "active" column on activitytype table
|
* Add an "active" column on activitytype table
|
||||||
|
@@ -22,7 +22,6 @@ final class Version20210401090853 extends AbstractMigration
|
|||||||
// this up() migration is auto-generated, please modify it to your needs
|
// this up() migration is auto-generated, please modify it to your needs
|
||||||
$this->addSql('CREATE SEQUENCE activitytypecategory_id_seq INCREMENT BY 1 MINVALUE 1 START 1000');
|
$this->addSql('CREATE SEQUENCE activitytypecategory_id_seq INCREMENT BY 1 MINVALUE 1 START 1000');
|
||||||
$this->addSql('CREATE TABLE activitytypecategory (id INT NOT NULL, name JSON NOT NULL, active BOOLEAN NOT NULL, PRIMARY KEY(id))');
|
$this->addSql('CREATE TABLE activitytypecategory (id INT NOT NULL, name JSON NOT NULL, active BOOLEAN NOT NULL, PRIMARY KEY(id))');
|
||||||
$this->addSql('COMMENT ON COLUMN activitytypecategory.name IS \'(DC2Type:json_array)\'');
|
|
||||||
$this->addSql('INSERT INTO activitytypecategory VALUES(1, \'{"fr": "Défaut", "en": "Default"}\', true)');
|
$this->addSql('INSERT INTO activitytypecategory VALUES(1, \'{"fr": "Défaut", "en": "Default"}\', true)');
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -51,7 +51,6 @@ final class Version20210408122329 extends AbstractMigration
|
|||||||
$this->addSql('ALTER TABLE activitytype ADD socialDataLabel VARCHAR(255) DEFAULT \'\' NOT NULL');
|
$this->addSql('ALTER TABLE activitytype ADD socialDataLabel VARCHAR(255) DEFAULT \'\' NOT NULL');
|
||||||
$this->addSql('ALTER TABLE activitytype ALTER name SET NOT NULL');
|
$this->addSql('ALTER TABLE activitytype ALTER name SET NOT NULL');
|
||||||
$this->addSql('ALTER TABLE activitytype ALTER active DROP DEFAULT');
|
$this->addSql('ALTER TABLE activitytype ALTER active DROP DEFAULT');
|
||||||
$this->addSql('COMMENT ON COLUMN activitytype.name IS \'(DC2Type:json_array)\'');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function down(Schema $schema) : void
|
public function down(Schema $schema) : void
|
||||||
|
@@ -6,7 +6,6 @@ Duration time: Durée
|
|||||||
Duration Time: Durée
|
Duration Time: Durée
|
||||||
durationTime: durée
|
durationTime: durée
|
||||||
Travel time: Durée de déplacement
|
Travel time: Durée de déplacement
|
||||||
Reasons: Sujets
|
|
||||||
Attendee: Présence de la personne
|
Attendee: Présence de la personne
|
||||||
attendee: présence de la personne
|
attendee: présence de la personne
|
||||||
list_reasons: liste des sujets
|
list_reasons: liste des sujets
|
||||||
@@ -23,6 +22,7 @@ Update: Mettre à jour
|
|||||||
Update activity: Modifier l'activité
|
Update activity: Modifier l'activité
|
||||||
Scope: Cercle
|
Scope: Cercle
|
||||||
Activity data: Données de l'activité
|
Activity data: Données de l'activité
|
||||||
|
Activity location: Localisation de l'activité
|
||||||
No reason associated: Aucun sujet
|
No reason associated: Aucun sujet
|
||||||
No social issues associated: Aucune problématique sociale
|
No social issues associated: Aucune problématique sociale
|
||||||
No social actions associated: Aucune action d'accompagnement
|
No social actions associated: Aucune action d'accompagnement
|
||||||
@@ -99,10 +99,13 @@ CHILL_ACTIVITY_LIST: Liste des activités
|
|||||||
Activities: Activités
|
Activities: Activités
|
||||||
Activity configuration: Configuration des activités
|
Activity configuration: Configuration des activités
|
||||||
Activity configuration menu: Configuration des activités
|
Activity configuration menu: Configuration des activités
|
||||||
Activity Types: Types d'activité
|
Activity types: Types d'activité
|
||||||
|
Activity type configuration: Configuration des categories d'activités
|
||||||
Activity Reasons: Sujets d'une activité
|
Activity Reasons: Sujets d'une activité
|
||||||
Activity Reasons Category: Catégories de sujet d'activités
|
Activity Reasons Category: Catégories de sujet d'activités
|
||||||
Activity Types Categories: Catégories des types d'activité
|
Activity Types Categories: Catégories des types d'activité
|
||||||
|
Activity Presences: Presences des activités
|
||||||
|
|
||||||
|
|
||||||
# Crud
|
# Crud
|
||||||
crud:
|
crud:
|
||||||
|
@@ -19,8 +19,6 @@ final class ChillAsideActivityExtension extends Extension implements PrependExte
|
|||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*
|
|
||||||
* @phpstan-ignore-next-line
|
|
||||||
*/
|
*/
|
||||||
public function load(array $configs, ContainerBuilder $container): void
|
public function load(array $configs, ContainerBuilder $container): void
|
||||||
{
|
{
|
||||||
@@ -111,4 +109,4 @@ final class ChillAsideActivityExtension extends Extension implements PrependExte
|
|||||||
]
|
]
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -58,7 +58,7 @@ final class AsideActivityFormType extends AbstractType
|
|||||||
$builder
|
$builder
|
||||||
->add('agent', EntityType::class,
|
->add('agent', EntityType::class,
|
||||||
[
|
[
|
||||||
'label' => 'Agent',
|
'label' => 'For agent',
|
||||||
'required' => true,
|
'required' => true,
|
||||||
'class' => User::class,
|
'class' => User::class,
|
||||||
'data' => $this->storage->getToken()->getUser(),
|
'data' => $this->storage->getToken()->getUser(),
|
||||||
|
@@ -32,7 +32,7 @@ final class AdminMenuBuilder implements \Chill\MainBundle\Routing\LocalMenuBuild
|
|||||||
])
|
])
|
||||||
->setExtras([
|
->setExtras([
|
||||||
'order' => 900,
|
'order' => 900,
|
||||||
'explain' => "Configure aside activities categories"
|
'explain' => "Aside activity type configuration"
|
||||||
]);
|
]);
|
||||||
} else {
|
} else {
|
||||||
$menu
|
$menu
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
{% extends "@ChillAsideActivity/Admin/layout_asideactivity.html.twig" %}
|
{% extends "@ChillAsideActivity/Admin/layout_asideactivity.html.twig" %}
|
||||||
|
|
||||||
{% block admin_content %}
|
{% block admin_content %}
|
||||||
<h1>{{ 'Aside Activity Type list'|trans }}</h1>
|
<h1>{{ 'Aside Activity Type List'|trans }}</h1>
|
||||||
|
|
||||||
<table class="records_list table table-bordered border-dark">
|
<table class="records_list table table-bordered border-dark">
|
||||||
<thead>
|
<thead>
|
||||||
|
@@ -30,7 +30,9 @@ final class CategoryRender implements ChillEntityRenderInterface
|
|||||||
{
|
{
|
||||||
$options = array_merge(self::DEFAULT_ARGS, $options);
|
$options = array_merge(self::DEFAULT_ARGS, $options);
|
||||||
|
|
||||||
$titles[] = $this->translatableStringHelper->localize($asideActivityCategory->getTitle());
|
$titles = [
|
||||||
|
$this->translatableStringHelper->localize($asideActivityCategory->getTitle()),
|
||||||
|
];
|
||||||
|
|
||||||
while ($asideActivityCategory->hasParent()) {
|
while ($asideActivityCategory->hasParent()) {
|
||||||
$asideActivityCategory = $asideActivityCategory->getParent();
|
$asideActivityCategory = $asideActivityCategory->getParent();
|
||||||
|
@@ -3,6 +3,7 @@ Show the aside activity: Voir l'activité annexe
|
|||||||
Edit the aside activity: Modifier l'activité annexe
|
Edit the aside activity: Modifier l'activité annexe
|
||||||
Remove aside activity: Supprimer l'activité annexe
|
Remove aside activity: Supprimer l'activité annexe
|
||||||
Aside activity: Activité annexe
|
Aside activity: Activité annexe
|
||||||
|
Aside Activity Type List: Liste des catégories d'activités annexes
|
||||||
Duration time: Durée
|
Duration time: Durée
|
||||||
durationTime: durée
|
durationTime: durée
|
||||||
user_username: nom de l'utilisateur
|
user_username: nom de l'utilisateur
|
||||||
@@ -45,7 +46,7 @@ Back to the list: Retour à la liste
|
|||||||
Choose the duration: Choisir la durée
|
Choose the duration: Choisir la durée
|
||||||
Choose a category: Choisir une catégorie
|
Choose a category: Choisir une catégorie
|
||||||
Is active: Actif
|
Is active: Actif
|
||||||
Agent: Utilisateur
|
For agent: Pour l'utilisateur
|
||||||
date: Date
|
date: Date
|
||||||
Duration: Durée
|
Duration: Durée
|
||||||
Note: Note
|
Note: Note
|
||||||
@@ -156,6 +157,11 @@ The activity has been successfully removed.: L'activité a été supprimée.
|
|||||||
|
|
||||||
#Menu
|
#Menu
|
||||||
Create an aside activity: "Créer une activité annexe"
|
Create an aside activity: "Créer une activité annexe"
|
||||||
|
Aside activity categories: Catégories des activités annexes
|
||||||
Aside activity configuration menu: "Menu de configuration des activités annexes"
|
Aside activity configuration menu: "Menu de configuration des activités annexes"
|
||||||
Aside activity configuration: "Configuration des activités annexes"
|
|
||||||
Phonecall: "Appel téléphonique"
|
Phonecall: "Appel téléphonique"
|
||||||
|
|
||||||
|
# admin
|
||||||
|
Aside activities: Activités annexes
|
||||||
|
Aside activity types: Types d'activités annexes
|
||||||
|
Aside activity type configuration: Configuration des categories d'activités annexes
|
||||||
|
@@ -97,9 +97,9 @@ class CalendarController extends AbstractController
|
|||||||
'calendarItems' => $calendarItems,
|
'calendarItems' => $calendarItems,
|
||||||
'user' => $user
|
'user' => $user
|
||||||
]);
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
} elseif ($accompanyingPeriod instanceof AccompanyingPeriod) {
|
if ($accompanyingPeriod instanceof AccompanyingPeriod) {
|
||||||
|
|
||||||
$total = $this->calendarRepository->countByAccompanyingPeriod($accompanyingPeriod);
|
$total = $this->calendarRepository->countByAccompanyingPeriod($accompanyingPeriod);
|
||||||
$paginator = $this->paginator->create($total);
|
$paginator = $this->paginator->create($total);
|
||||||
$calendarItems = $this->calendarRepository->findBy(
|
$calendarItems = $this->calendarRepository->findBy(
|
||||||
@@ -117,6 +117,8 @@ class CalendarController extends AbstractController
|
|||||||
'paginator' => $paginator
|
'paginator' => $paginator
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
throw new \Exception('Unable to list actions.');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -234,6 +236,7 @@ class CalendarController extends AbstractController
|
|||||||
'professionalsId' => $professionalsId,
|
'professionalsId' => $professionalsId,
|
||||||
'date' => $entity->getStartDate()->format('Y-m-d'),
|
'date' => $entity->getStartDate()->format('Y-m-d'),
|
||||||
'durationTime' => $durationTimeInMinutes,
|
'durationTime' => $durationTimeInMinutes,
|
||||||
|
'location' => $entity->getLocation()->getId(),
|
||||||
'comment' => $entity->getComment()->getComment(),
|
'comment' => $entity->getComment()->getComment(),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@@ -5,21 +5,20 @@ namespace Chill\CalendarBundle\DataFixtures\ORM;
|
|||||||
use Chill\CalendarBundle\Entity\CalendarRange;
|
use Chill\CalendarBundle\Entity\CalendarRange;
|
||||||
use Chill\MainBundle\DataFixtures\ORM\LoadUsers;
|
use Chill\MainBundle\DataFixtures\ORM\LoadUsers;
|
||||||
use Chill\MainBundle\Entity\User;
|
use Chill\MainBundle\Entity\User;
|
||||||
|
use Chill\MainBundle\Repository\UserRepository;
|
||||||
use DateTimeImmutable;
|
use DateTimeImmutable;
|
||||||
use Doctrine\Bundle\FixturesBundle\Fixture;
|
use Doctrine\Bundle\FixturesBundle\Fixture;
|
||||||
use Doctrine\Bundle\FixturesBundle\FixtureGroupInterface;
|
use Doctrine\Bundle\FixturesBundle\FixtureGroupInterface;
|
||||||
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
|
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
|
||||||
use Doctrine\Persistence\ObjectManager;
|
use Doctrine\Persistence\ObjectManager;
|
||||||
|
|
||||||
|
|
||||||
class LoadCalendarRange extends Fixture implements FixtureGroupInterface, OrderedFixtureInterface
|
class LoadCalendarRange extends Fixture implements FixtureGroupInterface, OrderedFixtureInterface
|
||||||
{
|
{
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
EntityManagerInterface $em
|
UserRepository $userRepository
|
||||||
) {
|
) {
|
||||||
$this->userRepository = $em->getRepository(User::class);
|
$this->userRepository = $userRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getOrder(): int
|
public function getOrder(): int
|
||||||
@@ -37,7 +36,7 @@ class LoadCalendarRange extends Fixture implements FixtureGroupInterface, Ordere
|
|||||||
public function load(ObjectManager $manager): void
|
public function load(ObjectManager $manager): void
|
||||||
{
|
{
|
||||||
$arr = range(-50, 50);
|
$arr = range(-50, 50);
|
||||||
|
|
||||||
print "Creating calendar range ('plage de disponibilités')\n";
|
print "Creating calendar range ('plage de disponibilités')\n";
|
||||||
|
|
||||||
$users = $this->userRepository->findAll();
|
$users = $this->userRepository->findAll();
|
||||||
@@ -70,7 +69,7 @@ class LoadCalendarRange extends Fixture implements FixtureGroupInterface, Ordere
|
|||||||
->setUser($u)
|
->setUser($u)
|
||||||
->setStartDate($startEvent)
|
->setStartDate($startEvent)
|
||||||
->setEndDate($endEvent);
|
->setEndDate($endEvent);
|
||||||
|
|
||||||
$manager->persist($calendarRange);
|
$manager->persist($calendarRange);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,4 +78,4 @@ class LoadCalendarRange extends Fixture implements FixtureGroupInterface, Ordere
|
|||||||
}
|
}
|
||||||
$manager->flush();
|
$manager->flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace Chill\CalendarBundle\Entity;
|
namespace Chill\CalendarBundle\Entity;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Entity\Location;
|
||||||
use Doctrine\Common\Collections\ArrayCollection;
|
use Doctrine\Common\Collections\ArrayCollection;
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
use Doctrine\Common\Collections\Collection;
|
use Doctrine\Common\Collections\Collection;
|
||||||
@@ -136,6 +137,13 @@ class Calendar
|
|||||||
*/
|
*/
|
||||||
private ?bool $sendSMS;
|
private ?bool $sendSMS;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\ManyToOne(targetEntity="Chill\MainBundle\Entity\Location")
|
||||||
|
* @groups({"read"})
|
||||||
|
*/
|
||||||
|
private ?Location $location = null;
|
||||||
|
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->comment = new CommentEmbeddable();
|
$this->comment = new CommentEmbeddable();
|
||||||
@@ -354,7 +362,7 @@ class Calendar
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getPersonsAssociated(): array
|
public function getPersonsAssociated(): array
|
||||||
{
|
{
|
||||||
if (null !== $this->accompanyingPeriod) {
|
if (null !== $this->accompanyingPeriod) {
|
||||||
$personsAssociated = [];
|
$personsAssociated = [];
|
||||||
@@ -363,11 +371,11 @@ class Calendar
|
|||||||
$personsAssociated[] = $participation->getPerson();
|
$personsAssociated[] = $participation->getPerson();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return $personsAssociated;
|
return $personsAssociated;
|
||||||
}
|
}
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getPersonsNotAssociated(): array
|
public function getPersonsNotAssociated(): array
|
||||||
{
|
{
|
||||||
if (null !== $this->accompanyingPeriod) {
|
if (null !== $this->accompanyingPeriod) {
|
||||||
@@ -407,4 +415,22 @@ class Calendar
|
|||||||
]));
|
]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Location|null
|
||||||
|
*/
|
||||||
|
public function getLocation(): ?Location
|
||||||
|
{
|
||||||
|
return $this->location;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Location|null $location
|
||||||
|
* @return Calendar
|
||||||
|
*/
|
||||||
|
public function setLocation(?Location $location): Calendar
|
||||||
|
{
|
||||||
|
$this->location = $location;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -34,7 +34,7 @@ class CancelReason
|
|||||||
private $canceledBy;
|
private $canceledBy;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\Column(type="json_array")
|
* @ORM\Column(type="json")
|
||||||
*/
|
*/
|
||||||
private $name = [];
|
private $name = [];
|
||||||
|
|
||||||
|
@@ -25,7 +25,7 @@ class Invite
|
|||||||
private User $user;
|
private User $user;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\Column(type="json_array")
|
* @ORM\Column(type="json")
|
||||||
*/
|
*/
|
||||||
private array $status = [];
|
private array $status = [];
|
||||||
|
|
||||||
|
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace Chill\CalendarBundle\Form;
|
namespace Chill\CalendarBundle\Form;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Entity\Location;
|
||||||
use Symfony\Component\Form\AbstractType;
|
use Symfony\Component\Form\AbstractType;
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||||
@@ -155,7 +156,7 @@ class CalendarType extends AbstractType
|
|||||||
}
|
}
|
||||||
))
|
))
|
||||||
;
|
;
|
||||||
|
|
||||||
$builder->add('calendarRange', HiddenType::class);
|
$builder->add('calendarRange', HiddenType::class);
|
||||||
$builder->get('calendarRange')
|
$builder->get('calendarRange')
|
||||||
->addModelTransformer(new CallbackTransformer(
|
->addModelTransformer(new CallbackTransformer(
|
||||||
@@ -178,6 +179,20 @@ class CalendarType extends AbstractType
|
|||||||
))
|
))
|
||||||
;
|
;
|
||||||
|
|
||||||
|
$builder->add('location', HiddenType::class)
|
||||||
|
->get('location')
|
||||||
|
->addModelTransformer(new CallbackTransformer(
|
||||||
|
function (?Location $location): string {
|
||||||
|
if (null === $location) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
return $location->getId();
|
||||||
|
},
|
||||||
|
function (?string $id): ?Location {
|
||||||
|
return $this->om->getRepository(Location::class)->findOneBy(['id' => (int) $id]);
|
||||||
|
}
|
||||||
|
))
|
||||||
|
;
|
||||||
|
|
||||||
// $builder->add('invites', HiddenType::class);
|
// $builder->add('invites', HiddenType::class);
|
||||||
// $builder->get('invites')
|
// $builder->get('invites')
|
||||||
|
92
src/Bundle/ChillCalendarBundle/Menu/UserMenuBuilder.php
Normal file
92
src/Bundle/ChillCalendarBundle/Menu/UserMenuBuilder.php
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2018 Champs Libres Cooperative <info@champs-libres.coop>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
namespace Chill\CalendarBundle\Menu;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Entity\User;
|
||||||
|
use Chill\MainBundle\Routing\LocalMenuBuilderInterface;
|
||||||
|
use Knp\Menu\MenuItem;
|
||||||
|
use Chill\TaskBundle\Templating\UI\CountNotificationTask;
|
||||||
|
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
|
||||||
|
use Symfony\Component\Translation\TranslatorInterface;
|
||||||
|
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Champs-Libres
|
||||||
|
*/
|
||||||
|
class UserMenuBuilder implements LocalMenuBuilderInterface
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @var CountNotificationTask
|
||||||
|
*/
|
||||||
|
public $counter;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @var TokenStorageInterface
|
||||||
|
*/
|
||||||
|
public $tokenStorage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @var TranslatorInterface
|
||||||
|
*/
|
||||||
|
public $translator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @var AuthorizationCheckerInterface
|
||||||
|
*/
|
||||||
|
public $authorizationChecker;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
CountNotificationTask $counter,
|
||||||
|
TokenStorageInterface $tokenStorage,
|
||||||
|
TranslatorInterface $translator,
|
||||||
|
AuthorizationCheckerInterface $authorizationChecker
|
||||||
|
) {
|
||||||
|
$this->counter = $counter;
|
||||||
|
$this->tokenStorage = $tokenStorage;
|
||||||
|
$this->translator = $translator;
|
||||||
|
$this->authorizationChecker = $authorizationChecker;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function buildMenu($menuId, MenuItem $menu, array $parameters)
|
||||||
|
{
|
||||||
|
$user = $this->tokenStorage->getToken()->getUser();
|
||||||
|
|
||||||
|
if ($this->authorizationChecker->isGranted('ROLE_USER')){
|
||||||
|
$menu->addChild("My calendar list", [
|
||||||
|
'route' => 'chill_calendar_calendar_list'
|
||||||
|
])
|
||||||
|
->setExtras([
|
||||||
|
'order' => 9,
|
||||||
|
'icon' => 'tasks'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getMenuIds(): array
|
||||||
|
{
|
||||||
|
return [ 'user' ];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -1,9 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<concerned-groups></concerned-groups>
|
<concerned-groups></concerned-groups>
|
||||||
|
<location></location>
|
||||||
<teleport to="#calendarControls">
|
<teleport to="#calendarControls">
|
||||||
<calendar-user-selector
|
<calendar-user-selector
|
||||||
v-bind:users="users"
|
v-bind:users="users"
|
||||||
v-bind:calendarEvents="calendarEvents"
|
v-bind:calendarEvents="calendarEvents"
|
||||||
v-bind:updateEventsSource="updateEventsSource"
|
v-bind:updateEventsSource="updateEventsSource"
|
||||||
v-bind:showMyCalendar="showMyCalendar"
|
v-bind:showMyCalendar="showMyCalendar"
|
||||||
v-bind:toggleMyCalendar="toggleMyCalendar"
|
v-bind:toggleMyCalendar="toggleMyCalendar"
|
||||||
@@ -22,6 +23,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import ConcernedGroups from 'ChillActivityAssets/vuejs/Activity/components/ConcernedGroups.vue';
|
import ConcernedGroups from 'ChillActivityAssets/vuejs/Activity/components/ConcernedGroups.vue';
|
||||||
|
import Location from 'ChillActivityAssets/vuejs/Activity/components/Location.vue';
|
||||||
import CalendarUserSelector from '../_components/CalendarUserSelector/CalendarUserSelector.vue';
|
import CalendarUserSelector from '../_components/CalendarUserSelector/CalendarUserSelector.vue';
|
||||||
import '@fullcalendar/core/vdom'; // solves problem with Vite
|
import '@fullcalendar/core/vdom'; // solves problem with Vite
|
||||||
import frLocale from '@fullcalendar/core/locales/fr';
|
import frLocale from '@fullcalendar/core/locales/fr';
|
||||||
@@ -35,6 +37,7 @@ export default {
|
|||||||
name: "App",
|
name: "App",
|
||||||
components: {
|
components: {
|
||||||
ConcernedGroups,
|
ConcernedGroups,
|
||||||
|
Location,
|
||||||
CalendarUserSelector,
|
CalendarUserSelector,
|
||||||
FullCalendar
|
FullCalendar
|
||||||
},
|
},
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
import { personMessages } from 'ChillPersonAssets/vuejs/_js/i18n'
|
import { personMessages } from 'ChillPersonAssets/vuejs/_js/i18n'
|
||||||
import { calendarUserSelectorMessages } from '../_components/CalendarUserSelector/js/i18n';
|
import { calendarUserSelectorMessages } from '../_components/CalendarUserSelector/js/i18n';
|
||||||
|
import { activityMessages } from 'ChillActivityAssets/vuejs/Activity/i18n';
|
||||||
|
|
||||||
const appMessages = {
|
const appMessages = {
|
||||||
fr: {
|
fr: {
|
||||||
@@ -17,6 +18,7 @@ const appMessages = {
|
|||||||
|
|
||||||
Object.assign(appMessages.fr, personMessages.fr);
|
Object.assign(appMessages.fr, personMessages.fr);
|
||||||
Object.assign(appMessages.fr, calendarUserSelectorMessages.fr);
|
Object.assign(appMessages.fr, calendarUserSelectorMessages.fr);
|
||||||
|
Object.assign(appMessages.fr, activityMessages.fr);
|
||||||
|
|
||||||
export {
|
export {
|
||||||
appMessages
|
appMessages
|
||||||
|
@@ -66,6 +66,11 @@ const store = createStore({
|
|||||||
setEvents(state, payload) {
|
setEvents(state, payload) {
|
||||||
console.log(payload)
|
console.log(payload)
|
||||||
state.currentEvent = {start: payload.start, end: payload.end}
|
state.currentEvent = {start: payload.start, end: payload.end}
|
||||||
|
},
|
||||||
|
// Location
|
||||||
|
updateLocation(state, value) {
|
||||||
|
console.log('### mutation: updateLocation', value);
|
||||||
|
state.activity.location = value;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
@@ -130,6 +135,14 @@ const store = createStore({
|
|||||||
commit('setEvents', payload);
|
commit('setEvents', payload);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Location
|
||||||
|
updateLocation({ commit }, value) {
|
||||||
|
console.log('### action: updateLocation', value);
|
||||||
|
let hiddenLocation = document.getElementById("chill_calendarbundle_calendar_location");
|
||||||
|
hiddenLocation.value = value.id;
|
||||||
|
commit('updateLocation', value);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@@ -38,7 +38,10 @@
|
|||||||
{{ form_row(form.calendarRange) }}
|
{{ form_row(form.calendarRange) }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
.. location
|
{%- if form.location is defined -%}
|
||||||
|
{{ form_row(form.location) }}
|
||||||
|
<div id="location"></div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
{%- if form.comment is defined -%}
|
{%- if form.comment is defined -%}
|
||||||
{{ form_row(form.comment) }}
|
{{ form_row(form.comment) }}
|
||||||
@@ -56,7 +59,7 @@
|
|||||||
|
|
||||||
<ul class="record_actions sticky-form-buttons">
|
<ul class="record_actions sticky-form-buttons">
|
||||||
<li class="cancel">
|
<li class="cancel">
|
||||||
<a
|
<a
|
||||||
class="btn btn-cancel"
|
class="btn btn-cancel"
|
||||||
{%- if context == 'user' -%}
|
{%- if context == 'user' -%}
|
||||||
href="{{ chill_return_path_or('chill_calendar_calendar_list', { 'user_id': user.id } )}}"
|
href="{{ chill_return_path_or('chill_calendar_calendar_list', { 'user_id': user.id } )}}"
|
||||||
|
@@ -6,14 +6,10 @@
|
|||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="calendar-edit">
|
<div class="calendar-edit">
|
||||||
<div class="row justify-content-center">
|
|
||||||
<div class="col-md-10 col-xxl">
|
<div id="calendar"></div> {# <=== vue component #}
|
||||||
|
{% include 'ChillCalendarBundle:Calendar:edit.html.twig' with {'context': 'accompanyingCourse'} %}
|
||||||
<div id="calendar"></div> {# <=== vue component #}
|
|
||||||
{% include 'ChillCalendarBundle:Calendar:edit.html.twig' with {'context': 'accompanyingCourse'} %}
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
@@ -21,7 +17,7 @@
|
|||||||
{{ parent() }}
|
{{ parent() }}
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
window.addEventListener('DOMContentLoaded', function (e) {
|
window.addEventListener('DOMContentLoaded', function (e) {
|
||||||
chill.displayAlertWhenLeavingModifiedForm('form[name="{{ form.vars.form.vars.name }}"]',
|
chill.displayAlertWhenLeavingModifiedForm('form[name="{{ form.vars.form.vars.name }}"]',
|
||||||
'{{ "You are going to leave a page with unsubmitted data. Are you sure you want to leave ?"|trans }}');
|
'{{ "You are going to leave a page with unsubmitted data. Are you sure you want to leave ?"|trans }}');
|
||||||
});
|
});
|
||||||
window.entity = {{ entity_json|json_encode|raw }};
|
window.entity = {{ entity_json|json_encode|raw }};
|
||||||
@@ -40,4 +36,4 @@
|
|||||||
|
|
||||||
{% block block_post_menu %}
|
{% block block_post_menu %}
|
||||||
<div id="calendarControls"></div>
|
<div id="calendarControls"></div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@@ -4,14 +4,10 @@
|
|||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="calendar-edit">
|
<div class="calendar-edit">
|
||||||
<div class="row justify-content-center">
|
|
||||||
<div class="col-md-10 col-xxl">
|
<div id="calendar"></div> {# <=== vue component #}
|
||||||
|
{% include 'ChillCalendarBundle:Calendar:edit.html.twig' with {'context': 'user'} %}
|
||||||
<div id="calendar"></div> {# <=== vue component #}
|
|
||||||
{% include 'ChillCalendarBundle:Calendar:edit.html.twig' with {'context': 'user'} %}
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
@@ -19,7 +15,7 @@
|
|||||||
{{ parent() }}
|
{{ parent() }}
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
window.addEventListener('DOMContentLoaded', function (e) {
|
window.addEventListener('DOMContentLoaded', function (e) {
|
||||||
chill.displayAlertWhenLeavingModifiedForm('form[name="{{ form.vars.form.vars.name }}"]',
|
chill.displayAlertWhenLeavingModifiedForm('form[name="{{ form.vars.form.vars.name }}"]',
|
||||||
'{{ "You are going to leave a page with unsubmitted data. Are you sure you want to leave ?"|trans }}');
|
'{{ "You are going to leave a page with unsubmitted data. Are you sure you want to leave ?"|trans }}');
|
||||||
});
|
});
|
||||||
window.entity = {{ entity_json|json_encode|raw }};
|
window.entity = {{ entity_json|json_encode|raw }};
|
||||||
|
@@ -34,7 +34,10 @@
|
|||||||
{{ form_row(form.endDate) }}
|
{{ form_row(form.endDate) }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
.. location
|
{%- if form.location is defined -%}
|
||||||
|
{{ form_row(form.location) }}
|
||||||
|
<div id="location"></div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
{%- if form.comment is defined -%}
|
{%- if form.comment is defined -%}
|
||||||
{{ form_row(form.comment) }}
|
{{ form_row(form.comment) }}
|
||||||
@@ -48,9 +51,9 @@
|
|||||||
|
|
||||||
<ul class="record_actions sticky-form-buttons">
|
<ul class="record_actions sticky-form-buttons">
|
||||||
<li class="cancel">
|
<li class="cancel">
|
||||||
<a
|
<a
|
||||||
class="btn btn-cancel"
|
class="btn btn-cancel"
|
||||||
{%- if context == 'person' -%}
|
{%- if context == 'person' -%}
|
||||||
href="{{ chill_return_path_or('chill_calendar_calendar_list', { 'person_id': person.id } )}}"
|
href="{{ chill_return_path_or('chill_calendar_calendar_list', { 'person_id': person.id } )}}"
|
||||||
{%- else -%}
|
{%- else -%}
|
||||||
href="{{ chill_return_path_or('chill_calendar_calendar_list', { 'accompanying_period_id': accompanyingCourse.id } )}}"
|
href="{{ chill_return_path_or('chill_calendar_calendar_list', { 'accompanying_period_id': accompanyingCourse.id } )}}"
|
||||||
|
@@ -6,25 +6,21 @@
|
|||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="calendar-new">
|
<div class="calendar-new">
|
||||||
<div class="row justify-content-center">
|
|
||||||
<div class="col-md-10 col-xxl">
|
<div id="calendar"></div> {# <=== vue component #}
|
||||||
|
{% include 'ChillCalendarBundle:Calendar:new.html.twig' with {'context': 'accompanyingCourse'} %}
|
||||||
<div id="calendar"></div> {# <=== vue component #}
|
|
||||||
{% include 'ChillCalendarBundle:Calendar:new.html.twig' with {'context': 'accompanyingCourse'} %}
|
</div>
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block js %}
|
{% block js %}
|
||||||
{{ parent() }}
|
{{ parent() }}
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
window.addEventListener('DOMContentLoaded', function (e) {
|
window.addEventListener('DOMContentLoaded', function (e) {
|
||||||
chill.displayAlertWhenLeavingUnsubmittedForm('form[name="{{ form.vars.form.vars.name }}"]',
|
chill.displayAlertWhenLeavingUnsubmittedForm('form[name="{{ form.vars.form.vars.name }}"]',
|
||||||
'{{ "You are going to leave a page with unsubmitted data. Are you sure you want to leave ?"|trans }}');
|
'{{ "You are going to leave a page with unsubmitted data. Are you sure you want to leave ?"|trans }}');
|
||||||
});
|
});
|
||||||
window.entity = {{ entity_json|json_encode|raw }};
|
window.entity = {{ entity_json|json_encode|raw }};
|
||||||
</script>
|
</script>
|
||||||
{{ encore_entry_script_tags('vue_calendar') }}
|
{{ encore_entry_script_tags('vue_calendar') }}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@@ -36,6 +36,20 @@
|
|||||||
<dt class="inline">{{ 'status'|trans }}</dt>
|
<dt class="inline">{{ 'status'|trans }}</dt>
|
||||||
<dd>{{ entity.status }}</dd>
|
<dd>{{ entity.status }}</dd>
|
||||||
|
|
||||||
|
|
||||||
|
<dt class="inline">{{ 'calendar location'|trans }}</dt>
|
||||||
|
<dd>
|
||||||
|
{% if entity.location is not null %}
|
||||||
|
<p>
|
||||||
|
<span>{{ entity.location.locationType.title|localize_translatable_string }}</span>
|
||||||
|
{{ entity.location.name }}
|
||||||
|
</p>
|
||||||
|
{{ entity.location.address|chill_entity_render_box }}
|
||||||
|
{% else %}
|
||||||
|
<span class="chill-no-data-statement">{{ 'No address given'|trans }}</span>
|
||||||
|
{% endif %}
|
||||||
|
</dd>
|
||||||
|
|
||||||
{% if not entity.comment.isEmpty %}
|
{% if not entity.comment.isEmpty %}
|
||||||
<dt class="inline">{{ 'calendar comment'|trans }}</dt>
|
<dt class="inline">{{ 'calendar comment'|trans }}</dt>
|
||||||
<dd>{{ entity.comment|chill_entity_render_box }}</dd>
|
<dd>{{ entity.comment|chill_entity_render_box }}</dd>
|
||||||
|
@@ -6,10 +6,8 @@
|
|||||||
|
|
||||||
{% block content -%}
|
{% block content -%}
|
||||||
<div class="calendar-show">
|
<div class="calendar-show">
|
||||||
<div class="row justify-content-center">
|
|
||||||
<div class="col-md-10 col-xxl">
|
{% include 'ChillCalendarBundle:Calendar:show.html.twig' with {'context': 'accompanyingCourse'} %}
|
||||||
{% include 'ChillCalendarBundle:Calendar:show.html.twig' with {'context': 'accompanyingCourse'} %}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
|
@@ -4,10 +4,8 @@
|
|||||||
|
|
||||||
{% block content -%}
|
{% block content -%}
|
||||||
<div class="calendar-show">
|
<div class="calendar-show">
|
||||||
<div class="row justify-content-center">
|
|
||||||
<div class="col-md-10 col-xxl">
|
{% include 'ChillCalendarBundle:Calendar:show.html.twig' with {'context': 'user'} %}
|
||||||
{% include 'ChillCalendarBundle:Calendar:show.html.twig' with {'context': 'user'} %}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
|
@@ -50,10 +50,7 @@ final class Version20210715141731 extends AbstractMigration
|
|||||||
$this->addSql('COMMENT ON COLUMN chill_calendar.calendar_range.startDate IS \'(DC2Type:date_immutable)\'');
|
$this->addSql('COMMENT ON COLUMN chill_calendar.calendar_range.startDate IS \'(DC2Type:date_immutable)\'');
|
||||||
$this->addSql('COMMENT ON COLUMN chill_calendar.calendar_range.endDate IS \'(DC2Type:date_immutable)\'');
|
$this->addSql('COMMENT ON COLUMN chill_calendar.calendar_range.endDate IS \'(DC2Type:date_immutable)\'');
|
||||||
$this->addSql('CREATE TABLE chill_calendar.cancel_reason (id INT NOT NULL, active BOOLEAN NOT NULL, canceledBy JSON NOT NULL, name JSON NOT NULL, PRIMARY KEY(id))');
|
$this->addSql('CREATE TABLE chill_calendar.cancel_reason (id INT NOT NULL, active BOOLEAN NOT NULL, canceledBy JSON NOT NULL, name JSON NOT NULL, PRIMARY KEY(id))');
|
||||||
$this->addSql('COMMENT ON COLUMN chill_calendar.cancel_reason.name IS \'(DC2Type:json_array)\'');
|
|
||||||
$this->addSql('COMMENT ON COLUMN chill_calendar.cancel_reason.canceledBy IS \'(DC2Type:json_array)\'');
|
|
||||||
$this->addSql('CREATE TABLE chill_calendar.invite (id INT NOT NULL, user_id INT DEFAULT NULL, status JSON NOT NULL, PRIMARY KEY(id))');
|
$this->addSql('CREATE TABLE chill_calendar.invite (id INT NOT NULL, user_id INT DEFAULT NULL, status JSON NOT NULL, PRIMARY KEY(id))');
|
||||||
$this->addSql('COMMENT ON COLUMN chill_calendar.invite.status IS \'(DC2Type:json_array)\'');
|
|
||||||
$this->addSql('CREATE INDEX IDX_F517FFA7A76ED395 ON chill_calendar.invite (user_id)');
|
$this->addSql('CREATE INDEX IDX_F517FFA7A76ED395 ON chill_calendar.invite (user_id)');
|
||||||
$this->addSql('ALTER TABLE chill_calendar.calendar ADD CONSTRAINT FK_712315ACA76ED395 FOREIGN KEY (user_id) REFERENCES users (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
|
$this->addSql('ALTER TABLE chill_calendar.calendar ADD CONSTRAINT FK_712315ACA76ED395 FOREIGN KEY (user_id) REFERENCES users (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
|
||||||
$this->addSql('ALTER TABLE chill_calendar.calendar ADD CONSTRAINT FK_712315ACD7FA8EF0 FOREIGN KEY (accompanyingPeriod_id) REFERENCES chill_person_accompanying_period (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
|
$this->addSql('ALTER TABLE chill_calendar.calendar ADD CONSTRAINT FK_712315ACD7FA8EF0 FOREIGN KEY (accompanyingPeriod_id) REFERENCES chill_person_accompanying_period (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
|
||||||
@@ -74,7 +71,7 @@ final class Version20210715141731 extends AbstractMigration
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function down(Schema $schema): void
|
public function down(Schema $schema): void
|
||||||
{
|
{
|
||||||
$this->addSql('ALTER TABLE chill_calendar.calendar_to_persons DROP CONSTRAINT FK_AEE94715A40A2C8');
|
$this->addSql('ALTER TABLE chill_calendar.calendar_to_persons DROP CONSTRAINT FK_AEE94715A40A2C8');
|
||||||
$this->addSql('ALTER TABLE chill_calendar.calendar_to_non_professionals DROP CONSTRAINT FK_FADF2C77A40A2C8');
|
$this->addSql('ALTER TABLE chill_calendar.calendar_to_non_professionals DROP CONSTRAINT FK_FADF2C77A40A2C8');
|
||||||
$this->addSql('ALTER TABLE chill_calendar.calendar_to_thirdparties DROP CONSTRAINT FK_2BAB7EFDA40A2C8');
|
$this->addSql('ALTER TABLE chill_calendar.calendar_to_thirdparties DROP CONSTRAINT FK_2BAB7EFDA40A2C8');
|
||||||
|
@@ -34,6 +34,5 @@ final class Version20210723074557 extends AbstractMigration
|
|||||||
$this->addSql('ALTER TABLE chill_calendar.calendar_to_non_professionals ADD CONSTRAINT fk_fadf2c77217bbb47 FOREIGN KEY (person_id) REFERENCES chill_person_person (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
|
$this->addSql('ALTER TABLE chill_calendar.calendar_to_non_professionals ADD CONSTRAINT fk_fadf2c77217bbb47 FOREIGN KEY (person_id) REFERENCES chill_person_person (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
|
||||||
$this->addSql('ALTER TABLE chill_calendar.cancel_reason ALTER canceledBy TYPE JSON');
|
$this->addSql('ALTER TABLE chill_calendar.cancel_reason ALTER canceledBy TYPE JSON');
|
||||||
$this->addSql('ALTER TABLE chill_calendar.cancel_reason ALTER canceledBy DROP DEFAULT');
|
$this->addSql('ALTER TABLE chill_calendar.cancel_reason ALTER canceledBy DROP DEFAULT');
|
||||||
$this->addSql('COMMENT ON COLUMN chill_calendar.cancel_reason.canceledby IS \'(DC2Type:json_array)\'');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -14,6 +14,7 @@ start date: début du rendez-vous
|
|||||||
end date: fin du rendez-vous
|
end date: fin du rendez-vous
|
||||||
cancel reason: motif d'annulation
|
cancel reason: motif d'annulation
|
||||||
status: Statut du rendez-vous
|
status: Statut du rendez-vous
|
||||||
|
calendar location: Localistion du rendez-vous
|
||||||
calendar comment: Remarque sur le rendez-vous
|
calendar comment: Remarque sur le rendez-vous
|
||||||
sendSMS: Envoi d'un SMS
|
sendSMS: Envoi d'un SMS
|
||||||
Send s m s: Envoi d'un SMS ?
|
Send s m s: Envoi d'un SMS ?
|
||||||
|
@@ -28,27 +28,31 @@ class ChillCustomFieldsExtension extends Extension implements PrependExtensionIn
|
|||||||
$loader->load('services/fixtures.yaml');
|
$loader->load('services/fixtures.yaml');
|
||||||
$loader->load('services/controller.yaml');
|
$loader->load('services/controller.yaml');
|
||||||
$loader->load('services/command.yaml');
|
$loader->load('services/command.yaml');
|
||||||
|
|
||||||
//add at least a blank array at 'customizable_entities' options
|
//add at least a blank array at 'customizable_entities' options
|
||||||
//$customizable_entities = (isset($config['customizables_entities'])
|
//$customizable_entities = (isset($config['customizables_entities'])
|
||||||
// && $config['customizables_entities'] !== FALSE)
|
// && $config['customizables_entities'] !== FALSE)
|
||||||
// ? $config['customizables_entities'] : array();
|
// ? $config['customizables_entities'] : array();
|
||||||
|
|
||||||
$container->setParameter('chill_custom_fields.customizables_entities',
|
$container->setParameter('chill_custom_fields.customizables_entities',
|
||||||
$config['customizables_entities']);
|
$config['customizables_entities']);
|
||||||
$container->setParameter('chill_custom_fields.show_empty_values',
|
$container->setParameter('chill_custom_fields.show_empty_values',
|
||||||
$config['show_empty_values_in_views']);
|
$config['show_empty_values_in_views']);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-PHPdoc)
|
/* (non-PHPdoc)
|
||||||
* @see \Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface::prepend()
|
* @see \Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface::prepend()
|
||||||
*/
|
*/
|
||||||
public function prepend(ContainerBuilder $container)
|
public function prepend(ContainerBuilder $container)
|
||||||
{
|
{
|
||||||
// add form layout to twig resources
|
// add form layout to twig resources
|
||||||
$twigConfig['form_themes'][] = 'ChillCustomFieldsBundle:Form:fields.html.twig';
|
$twigConfig = [
|
||||||
|
'form_themes' => [
|
||||||
|
'ChillCustomFieldsBundle:Form:fields.html.twig',
|
||||||
|
],
|
||||||
|
];
|
||||||
$container->prependExtensionConfig('twig', $twigConfig);
|
$container->prependExtensionConfig('twig', $twigConfig);
|
||||||
|
|
||||||
//add routes for custom bundle
|
//add routes for custom bundle
|
||||||
$container->prependExtensionConfig('chill_main', array(
|
$container->prependExtensionConfig('chill_main', array(
|
||||||
'routing' => array(
|
'routing' => array(
|
||||||
|
@@ -40,7 +40,7 @@ class CustomField
|
|||||||
* @ORM\GeneratedValue(strategy="AUTO")
|
* @ORM\GeneratedValue(strategy="AUTO")
|
||||||
*/
|
*/
|
||||||
private $id;
|
private $id;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var string
|
* @var string
|
||||||
*
|
*
|
||||||
@@ -61,18 +61,18 @@ class CustomField
|
|||||||
* @ORM\Column(type="boolean")
|
* @ORM\Column(type="boolean")
|
||||||
*/
|
*/
|
||||||
private $active = true;
|
private $active = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array
|
* @var array
|
||||||
*
|
*
|
||||||
* @ORM\Column(type="json_array")
|
* @ORM\Column(type="json")
|
||||||
*/
|
*/
|
||||||
private $options = array();
|
private $options = array();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array
|
* @var array
|
||||||
*
|
*
|
||||||
* @ORM\Column(type="json_array")
|
* @ORM\Column(type="json")
|
||||||
*/
|
*/
|
||||||
private $name;
|
private $name;
|
||||||
|
|
||||||
@@ -82,14 +82,14 @@ class CustomField
|
|||||||
* @ORM\Column(type="float")
|
* @ORM\Column(type="float")
|
||||||
*/
|
*/
|
||||||
private $ordering;
|
private $ordering;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var boolean
|
* @var boolean
|
||||||
*
|
*
|
||||||
* @ORM\Column(type="boolean")
|
* @ORM\Column(type="boolean")
|
||||||
*/
|
*/
|
||||||
private $required = FALSE;
|
private $required = FALSE;
|
||||||
|
|
||||||
const ONE_TO_ONE = 1;
|
const ONE_TO_ONE = 1;
|
||||||
const ONE_TO_MANY = 2;
|
const ONE_TO_MANY = 2;
|
||||||
|
|
||||||
@@ -102,7 +102,7 @@ class CustomField
|
|||||||
*/
|
*/
|
||||||
private $customFieldGroup;
|
private $customFieldGroup;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get id
|
* Get id
|
||||||
*
|
*
|
||||||
@@ -112,7 +112,7 @@ class CustomField
|
|||||||
{
|
{
|
||||||
return $this->id;
|
return $this->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
@@ -120,15 +120,15 @@ class CustomField
|
|||||||
{
|
{
|
||||||
return $this->slug;
|
return $this->slug;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
function getOptions()
|
function getOptions()
|
||||||
{
|
{
|
||||||
return $this->options;
|
return $this->options;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set type
|
* Set type
|
||||||
*
|
*
|
||||||
@@ -152,7 +152,7 @@ class CustomField
|
|||||||
return $this->type;
|
return $this->type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set active
|
* Set active
|
||||||
*
|
*
|
||||||
@@ -229,9 +229,9 @@ class CustomField
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return '';
|
return '';
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
return $this->name;
|
return $this->name;
|
||||||
};
|
};
|
||||||
@@ -272,7 +272,7 @@ class CustomField
|
|||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $slug
|
* @param $slug
|
||||||
* @return $this
|
* @return $this
|
||||||
@@ -282,20 +282,20 @@ class CustomField
|
|||||||
$this->slug = $slug;
|
$this->slug = $slug;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* alias for isRequired
|
* alias for isRequired
|
||||||
*
|
*
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
public function getRequired()
|
public function getRequired()
|
||||||
{
|
{
|
||||||
return $this->isRequired();
|
return $this->isRequired();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* return true if the field required
|
* return true if the field required
|
||||||
*
|
*
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
public function isRequired()
|
public function isRequired()
|
||||||
@@ -308,5 +308,5 @@ class CustomField
|
|||||||
$this->required = $required;
|
$this->required = $required;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -39,21 +39,21 @@ class Option
|
|||||||
* @ORM\GeneratedValue(strategy="AUTO")
|
* @ORM\GeneratedValue(strategy="AUTO")
|
||||||
*/
|
*/
|
||||||
private $id;
|
private $id;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var string
|
* @var string
|
||||||
* @ORM\Column(type="string", length=15)
|
* @ORM\Column(type="string", length=15)
|
||||||
*/
|
*/
|
||||||
private $key;
|
private $key;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A json representation of text (multilingual)
|
* A json representation of text (multilingual)
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array
|
||||||
* @ORM\Column(type="json_array")
|
* @ORM\Column(type="json")
|
||||||
*/
|
*/
|
||||||
private $text;
|
private $text;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var Collection
|
* @var Collection
|
||||||
* @ORM\OneToMany(
|
* @ORM\OneToMany(
|
||||||
@@ -61,7 +61,7 @@ class Option
|
|||||||
* mappedBy="parent")
|
* mappedBy="parent")
|
||||||
*/
|
*/
|
||||||
private $children;
|
private $children;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var Option
|
* @var Option
|
||||||
* @ORM\ManyToOne(
|
* @ORM\ManyToOne(
|
||||||
@@ -70,19 +70,19 @@ class Option
|
|||||||
* @ORM\JoinColumn(nullable=true)
|
* @ORM\JoinColumn(nullable=true)
|
||||||
*/
|
*/
|
||||||
private $parent;
|
private $parent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var string
|
* @var string
|
||||||
* @ORM\Column(type="string", length=50, name="internal_key")
|
* @ORM\Column(type="string", length=50, name="internal_key")
|
||||||
*/
|
*/
|
||||||
private $internalKey = '';
|
private $internalKey = '';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var boolean
|
* @var boolean
|
||||||
* @ORM\Column(type="boolean")
|
* @ORM\Column(type="boolean")
|
||||||
*/
|
*/
|
||||||
private $active = true;
|
private $active = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
@@ -90,7 +90,7 @@ class Option
|
|||||||
{
|
{
|
||||||
return $this->id;
|
return $this->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
@@ -98,7 +98,7 @@ class Option
|
|||||||
{
|
{
|
||||||
return $this->key;
|
return $this->key;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
@@ -106,7 +106,7 @@ class Option
|
|||||||
{
|
{
|
||||||
return $this->text;
|
return $this->text;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Collection
|
* @return Collection
|
||||||
*/
|
*/
|
||||||
@@ -114,7 +114,7 @@ class Option
|
|||||||
{
|
{
|
||||||
return $this->children;
|
return $this->children;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Option
|
* @return Option
|
||||||
*/
|
*/
|
||||||
@@ -122,7 +122,7 @@ class Option
|
|||||||
{
|
{
|
||||||
return $this->parent;
|
return $this->parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $key
|
* @param $key
|
||||||
* @return $this
|
* @return $this
|
||||||
@@ -132,7 +132,7 @@ class Option
|
|||||||
$this->key = $key;
|
$this->key = $key;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array $text
|
* @param array $text
|
||||||
* @return $this
|
* @return $this
|
||||||
@@ -142,7 +142,7 @@ class Option
|
|||||||
$this->text = $text;
|
$this->text = $text;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Option|null $parent
|
* @param Option|null $parent
|
||||||
* @return $this
|
* @return $this
|
||||||
@@ -153,16 +153,16 @@ class Option
|
|||||||
$this->key = $parent->getKey();
|
$this->key = $parent->getKey();
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
public function hasParent()
|
public function hasParent()
|
||||||
{
|
{
|
||||||
return $this->parent === NULL ? false : true;
|
return $this->parent === NULL ? false : true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
@@ -170,7 +170,7 @@ class Option
|
|||||||
{
|
{
|
||||||
return $this->internalKey;
|
return $this->internalKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
@@ -178,7 +178,7 @@ class Option
|
|||||||
{
|
{
|
||||||
return $this->active;
|
return $this->active;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
@@ -186,7 +186,7 @@ class Option
|
|||||||
{
|
{
|
||||||
return $this->isActive();
|
return $this->isActive();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $internal_key
|
* @param $internal_key
|
||||||
* @return $this
|
* @return $this
|
||||||
@@ -196,7 +196,7 @@ class Option
|
|||||||
$this->internalKey = $internal_key;
|
$this->internalKey = $internal_key;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $active
|
* @param $active
|
||||||
* @return $this
|
* @return $this
|
||||||
@@ -206,5 +206,5 @@ class Option
|
|||||||
$this->active = $active;
|
$this->active = $active;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -45,7 +45,7 @@ class CustomFieldsGroup
|
|||||||
/**
|
/**
|
||||||
* @var array
|
* @var array
|
||||||
*
|
*
|
||||||
* @ORM\Column(type="json_array")
|
* @ORM\Column(type="json")
|
||||||
*/
|
*/
|
||||||
private $name;
|
private $name;
|
||||||
|
|
||||||
@@ -76,15 +76,15 @@ class CustomFieldsGroup
|
|||||||
* @var array|null
|
* @var array|null
|
||||||
*/
|
*/
|
||||||
private $activeCustomFields = null;
|
private $activeCustomFields = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array
|
* @var array
|
||||||
*
|
*
|
||||||
* @ORM\Column(type="json_array")
|
* @ORM\Column(type="json")
|
||||||
*/
|
*/
|
||||||
private $options = array();
|
private $options = array();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CustomFieldsGroup constructor.
|
* CustomFieldsGroup constructor.
|
||||||
*/
|
*/
|
||||||
@@ -115,7 +115,7 @@ class CustomFieldsGroup
|
|||||||
{
|
{
|
||||||
$this->customFields->removeElement($customField);
|
$this->customFields->removeElement($customField);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Collection
|
* @return Collection
|
||||||
*/
|
*/
|
||||||
@@ -142,7 +142,7 @@ class CustomFieldsGroup
|
|||||||
|
|
||||||
return $this->activeCustomFields;
|
return $this->activeCustomFields;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get id
|
* Get id
|
||||||
*
|
*
|
||||||
@@ -184,9 +184,9 @@ class CustomFieldsGroup
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return '';
|
return '';
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
return $this->name;
|
return $this->name;
|
||||||
}
|
}
|
||||||
@@ -214,10 +214,10 @@ class CustomFieldsGroup
|
|||||||
{
|
{
|
||||||
return $this->entity;
|
return $this->entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get options array
|
* get options array
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function getOptions()
|
public function getOptions()
|
||||||
@@ -227,7 +227,7 @@ class CustomFieldsGroup
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* set options array
|
* set options array
|
||||||
*
|
*
|
||||||
* @param array $options
|
* @param array $options
|
||||||
* @return CustomFieldsGroup
|
* @return CustomFieldsGroup
|
||||||
*/
|
*/
|
||||||
|
@@ -145,5 +145,7 @@ class DocGeneratorTemplateController extends AbstractController
|
|||||||
} catch (TransferException $e) {
|
} catch (TransferException $e) {
|
||||||
throw $e;
|
throw $e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
throw new \Exception('Unable to generate document.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -21,7 +21,7 @@ class DocGeneratorTemplate
|
|||||||
private int $id;
|
private int $id;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\Column(type="json_array")
|
* @ORM\Column(type="json")
|
||||||
* @Serializer\Groups({"read"})
|
* @Serializer\Groups({"read"})
|
||||||
*/
|
*/
|
||||||
private array $name = [];
|
private array $name = [];
|
||||||
|
@@ -22,7 +22,6 @@ final class Version20210812214310 extends AbstractMigration
|
|||||||
$this->addSql('ALTER TABLE chill_docgen_template ADD entities TEXT');
|
$this->addSql('ALTER TABLE chill_docgen_template ADD entities TEXT');
|
||||||
$this->addSql('ALTER TABLE chill_docgen_template ADD context VARCHAR(255)');
|
$this->addSql('ALTER TABLE chill_docgen_template ADD context VARCHAR(255)');
|
||||||
$this->addSql('COMMENT ON COLUMN chill_docgen_template.entities IS \'(DC2Type:simple_array)\'');
|
$this->addSql('COMMENT ON COLUMN chill_docgen_template.entities IS \'(DC2Type:simple_array)\'');
|
||||||
$this->addSql('COMMENT ON COLUMN chill_docgen_template.name IS \'(DC2Type:json_array)\'');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function down(Schema $schema): void
|
public function down(Schema $schema): void
|
||||||
|
@@ -4,6 +4,7 @@ namespace Chill\DocStoreBundle\Controller;
|
|||||||
|
|
||||||
use Chill\DocStoreBundle\Entity\AccompanyingCourseDocument;
|
use Chill\DocStoreBundle\Entity\AccompanyingCourseDocument;
|
||||||
use Chill\DocStoreBundle\Form\AccompanyingCourseDocumentType;
|
use Chill\DocStoreBundle\Form\AccompanyingCourseDocumentType;
|
||||||
|
use Chill\DocStoreBundle\Security\Authorization\AccompanyingCourseDocumentVoter;
|
||||||
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
|
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
|
||||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||||
use Chill\PersonBundle\Privacy\PrivacyEvent;
|
use Chill\PersonBundle\Privacy\PrivacyEvent;
|
||||||
@@ -16,32 +17,27 @@ use Symfony\Contracts\Translation\TranslatorInterface;
|
|||||||
use Symfony\Component\Routing\Annotation\Route;
|
use Symfony\Component\Routing\Annotation\Route;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class DocumentAccompanyingCourseController
|
|
||||||
*
|
|
||||||
* @package Chill\DocStoreBundle\Controller
|
|
||||||
* @Route("/{_locale}/parcours/{course}/document")
|
* @Route("/{_locale}/parcours/{course}/document")
|
||||||
*
|
|
||||||
* TODO faire un controller abstrait ?
|
|
||||||
*/
|
*/
|
||||||
class DocumentAccompanyingCourseController extends AbstractController
|
class DocumentAccompanyingCourseController extends AbstractController
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @var TranslatorInterface
|
* @var TranslatorInterface
|
||||||
*/
|
*/
|
||||||
protected $translator;
|
protected $translator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var EventDispatcherInterface
|
* @var EventDispatcherInterface
|
||||||
*/
|
*/
|
||||||
protected $eventDispatcher;
|
protected $eventDispatcher;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var AuthorizationHelper
|
* @var AuthorizationHelper
|
||||||
*/
|
*/
|
||||||
protected $authorizationHelper;
|
protected $authorizationHelper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DocumentAccompanyingCourseController constructor.
|
* DocumentAccompanyingCourseController constructor.
|
||||||
|
|
||||||
@@ -50,15 +46,15 @@ class DocumentAccompanyingCourseController extends AbstractController
|
|||||||
* @param AuthorizationHelper $authorizationHelper
|
* @param AuthorizationHelper $authorizationHelper
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
TranslatorInterface $translator,
|
TranslatorInterface $translator,
|
||||||
EventDispatcherInterface $eventDispatcher,
|
EventDispatcherInterface $eventDispatcher,
|
||||||
AuthorizationHelper $authorizationHelper
|
AuthorizationHelper $authorizationHelper
|
||||||
) {
|
) {
|
||||||
$this->translator = $translator;
|
$this->translator = $translator;
|
||||||
$this->eventDispatcher = $eventDispatcher;
|
$this->eventDispatcher = $eventDispatcher;
|
||||||
$this->authorizationHelper = $authorizationHelper;
|
$this->authorizationHelper = $authorizationHelper;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Route("/", name="accompanying_course_document_index", methods="GET")
|
* @Route("/", name="accompanying_course_document_index", methods="GET")
|
||||||
*/
|
*/
|
||||||
@@ -70,7 +66,7 @@ class DocumentAccompanyingCourseController extends AbstractController
|
|||||||
throw $this->createNotFoundException('Accompanying period not found');
|
throw $this->createNotFoundException('Accompanying period not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->denyAccessUnlessGranted(AccompanyingPeriodVoter::SEE, $course);
|
$this->denyAccessUnlessGranted(AccompanyingCourseDocumentVoter::SEE, $course);
|
||||||
|
|
||||||
$documents = $em
|
$documents = $em
|
||||||
->getRepository("ChillDocStoreBundle:AccompanyingCourseDocument")
|
->getRepository("ChillDocStoreBundle:AccompanyingCourseDocument")
|
||||||
@@ -78,7 +74,7 @@ class DocumentAccompanyingCourseController extends AbstractController
|
|||||||
['course' => $course],
|
['course' => $course],
|
||||||
['date' => 'DESC']
|
['date' => 'DESC']
|
||||||
);
|
);
|
||||||
|
|
||||||
return $this->render(
|
return $this->render(
|
||||||
'ChillDocStoreBundle:AccompanyingCourseDocument:index.html.twig',
|
'ChillDocStoreBundle:AccompanyingCourseDocument:index.html.twig',
|
||||||
[
|
[
|
||||||
@@ -96,13 +92,13 @@ class DocumentAccompanyingCourseController extends AbstractController
|
|||||||
throw $this->createNotFoundException('Accompanying period not found');
|
throw $this->createNotFoundException('Accompanying period not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->denyAccessUnlessGranted(AccompanyingPeriodVoter::SEE, $course);
|
|
||||||
|
|
||||||
$document = new AccompanyingCourseDocument();
|
$document = new AccompanyingCourseDocument();
|
||||||
$document->setUser($this->getUser());
|
$document->setUser($this->getUser());
|
||||||
$document->setCourse($course);
|
$document->setCourse($course);
|
||||||
$document->setDate(new \DateTime('Now'));
|
$document->setDate(new \DateTime('Now'));
|
||||||
|
|
||||||
|
$this->denyAccessUnlessGranted(AccompanyingCourseDocumentVoter::CREATE, $document);
|
||||||
|
|
||||||
$form = $this->createForm(AccompanyingCourseDocumentType::class, $document);
|
$form = $this->createForm(AccompanyingCourseDocumentType::class, $document);
|
||||||
$form->handleRequest($request);
|
$form->handleRequest($request);
|
||||||
|
|
||||||
@@ -114,7 +110,7 @@ class DocumentAccompanyingCourseController extends AbstractController
|
|||||||
$em = $this->getDoctrine()->getManager();
|
$em = $this->getDoctrine()->getManager();
|
||||||
$em->persist($document);
|
$em->persist($document);
|
||||||
$em->flush();
|
$em->flush();
|
||||||
|
|
||||||
$this->addFlash('success', $this->translator->trans("The document is successfully registered"));
|
$this->addFlash('success', $this->translator->trans("The document is successfully registered"));
|
||||||
|
|
||||||
return $this->redirectToRoute('accompanying_course_document_index', ['course' => $course->getId()]);
|
return $this->redirectToRoute('accompanying_course_document_index', ['course' => $course->getId()]);
|
||||||
@@ -134,9 +130,8 @@ class DocumentAccompanyingCourseController extends AbstractController
|
|||||||
*/
|
*/
|
||||||
public function show(AccompanyingPeriod $course, AccompanyingCourseDocument $document): Response
|
public function show(AccompanyingPeriod $course, AccompanyingCourseDocument $document): Response
|
||||||
{
|
{
|
||||||
$this->denyAccessUnlessGranted('CHILL_PERSON_ACCOMPANYING_PERIOD_SEE', $course);
|
$this->denyAccessUnlessGranted(AccompanyingCourseDocumentVoter::SEE_DETAILS, $document);
|
||||||
$this->denyAccessUnlessGranted('CHILL_ACCOMPANYING_COURSE_DOCUMENT_SEE', $document);
|
|
||||||
|
|
||||||
return $this->render(
|
return $this->render(
|
||||||
'ChillDocStoreBundle:AccompanyingCourseDocument:show.html.twig',
|
'ChillDocStoreBundle:AccompanyingCourseDocument:show.html.twig',
|
||||||
['document' => $document, 'accompanyingCourse' => $course]);
|
['document' => $document, 'accompanyingCourse' => $course]);
|
||||||
@@ -147,8 +142,7 @@ class DocumentAccompanyingCourseController extends AbstractController
|
|||||||
*/
|
*/
|
||||||
public function edit(Request $request, AccompanyingPeriod $course, AccompanyingCourseDocument $document): Response
|
public function edit(Request $request, AccompanyingPeriod $course, AccompanyingCourseDocument $document): Response
|
||||||
{
|
{
|
||||||
$this->denyAccessUnlessGranted('CHILL_PERSON_ACCOMPANYING_PERIOD_SEE', $course);
|
$this->denyAccessUnlessGranted(AccompanyingCourseDocumentVoter::UPDATE, $document);
|
||||||
$this->denyAccessUnlessGranted('CHILL_ACCOMPANYING_COURSE_DOCUMENT_UPDATE', $document);
|
|
||||||
|
|
||||||
$document->setUser($this->getUser());
|
$document->setUser($this->getUser());
|
||||||
$document->setDate(new \DateTime('Now'));
|
$document->setDate(new \DateTime('Now'));
|
||||||
@@ -159,17 +153,17 @@ class DocumentAccompanyingCourseController extends AbstractController
|
|||||||
|
|
||||||
if ($form->isSubmitted() && $form->isValid()) {
|
if ($form->isSubmitted() && $form->isValid()) {
|
||||||
$this->getDoctrine()->getManager()->flush();
|
$this->getDoctrine()->getManager()->flush();
|
||||||
|
|
||||||
$this->addFlash('success', $this->translator->trans("The document is successfully updated"));
|
$this->addFlash('success', $this->translator->trans("The document is successfully updated"));
|
||||||
|
|
||||||
return $this->redirectToRoute(
|
return $this->redirectToRoute(
|
||||||
'accompanying_course_document_edit',
|
'accompanying_course_document_edit',
|
||||||
['id' => $document->getId(), 'course' => $course->getId()]);
|
['id' => $document->getId(), 'course' => $course->getId()]);
|
||||||
|
|
||||||
} elseif ($form->isSubmitted() and !$form->isValid()) {
|
} elseif ($form->isSubmitted() and !$form->isValid()) {
|
||||||
$this->addFlash('error', $this->translator->trans("This form contains errors"));
|
$this->addFlash('error', $this->translator->trans("This form contains errors"));
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->render(
|
return $this->render(
|
||||||
'ChillDocStoreBundle:AccompanyingCourseDocument:edit.html.twig',
|
'ChillDocStoreBundle:AccompanyingCourseDocument:edit.html.twig',
|
||||||
[
|
[
|
||||||
@@ -184,8 +178,7 @@ class DocumentAccompanyingCourseController extends AbstractController
|
|||||||
*/
|
*/
|
||||||
public function delete(Request $request, AccompanyingPeriod $course, AccompanyingCourseDocument $document): Response
|
public function delete(Request $request, AccompanyingPeriod $course, AccompanyingCourseDocument $document): Response
|
||||||
{
|
{
|
||||||
$this->denyAccessUnlessGranted('CHILL_PERSON_ACCOMPANYING_PERIOD_SEE', $course);
|
$this->denyAccessUnlessGranted(AccompanyingCourseDocumentVoter::DELETE, $document);
|
||||||
$this->denyAccessUnlessGranted('CHILL_ACCOMPANYING_COURSE_DOCUMENT_DELETE', $document);
|
|
||||||
|
|
||||||
if ($this->isCsrfTokenValid('delete'.$document->getId(), $request->request->get('_token'))) {
|
if ($this->isCsrfTokenValid('delete'.$document->getId(), $request->request->get('_token'))) {
|
||||||
$em = $this->getDoctrine()->getManager();
|
$em = $this->getDoctrine()->getManager();
|
||||||
|
@@ -38,7 +38,7 @@ class LoadDocumentACL extends AbstractFixture implements OrderedFixtureInterface
|
|||||||
return 35000;
|
return 35000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function load(ObjectManager $manager)
|
public function load(ObjectManager $manager)
|
||||||
{
|
{
|
||||||
foreach (LoadPermissionsGroup::$refs as $permissionsGroupRef) {
|
foreach (LoadPermissionsGroup::$refs as $permissionsGroupRef) {
|
||||||
@@ -57,15 +57,15 @@ class LoadDocumentACL extends AbstractFixture implements OrderedFixtureInterface
|
|||||||
break;
|
break;
|
||||||
case 'administrative':
|
case 'administrative':
|
||||||
case 'direction':
|
case 'direction':
|
||||||
if (in_array($scope->getName()['en'], array('administrative', 'social'))) {
|
if (in_array($scope->getName()['en'], array('administrative', 'social'), true)) {
|
||||||
printf("denying power on %s\n", $scope->getName()['en']);
|
printf("denying power on %s\n", $scope->getName()['en']);
|
||||||
break 2; // we do not want any power on social or administrative
|
break 2; // we do not want any power on social or administrative
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Adding Person report acl to %s "
|
printf("Adding Person report acl to %s "
|
||||||
. "permission group, scope '%s' \n",
|
. "permission group, scope '%s' \n",
|
||||||
$permissionsGroup->getName(), $scope->getName()['en']);
|
$permissionsGroup->getName(), $scope->getName()['en']);
|
||||||
$roleScopeUpdate = (new RoleScope())
|
$roleScopeUpdate = (new RoleScope())
|
||||||
->setRole(PersonDocumentVoter::CREATE)
|
->setRole(PersonDocumentVoter::CREATE)
|
||||||
@@ -83,9 +83,9 @@ class LoadDocumentACL extends AbstractFixture implements OrderedFixtureInterface
|
|||||||
$manager->persist($roleScopeCreate);
|
$manager->persist($roleScopeCreate);
|
||||||
$manager->persist($roleScopeDelete);
|
$manager->persist($roleScopeDelete);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$manager->flush();
|
$manager->flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace Chill\DocStoreBundle\DependencyInjection;
|
namespace Chill\DocStoreBundle\DependencyInjection;
|
||||||
|
|
||||||
|
use Chill\DocStoreBundle\Security\Authorization\AccompanyingCourseDocumentVoter;
|
||||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||||
use Symfony\Component\Config\FileLocator;
|
use Symfony\Component\Config\FileLocator;
|
||||||
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
|
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
|
||||||
@@ -39,7 +40,7 @@ class ChillDocStoreExtension extends Extension implements PrependExtensionInterf
|
|||||||
$this->prependAuthorization($container);
|
$this->prependAuthorization($container);
|
||||||
$this->prependTwig($container);
|
$this->prependTwig($container);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function prependRoute(ContainerBuilder $container)
|
protected function prependRoute(ContainerBuilder $container)
|
||||||
{
|
{
|
||||||
//declare routes for task bundle
|
//declare routes for task bundle
|
||||||
@@ -52,7 +53,7 @@ class ChillDocStoreExtension extends Extension implements PrependExtensionInterf
|
|||||||
)
|
)
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function prependAuthorization(ContainerBuilder $container)
|
protected function prependAuthorization(ContainerBuilder $container)
|
||||||
{
|
{
|
||||||
$container->prependExtensionConfig('security', array(
|
$container->prependExtensionConfig('security', array(
|
||||||
@@ -61,10 +62,14 @@ class ChillDocStoreExtension extends Extension implements PrependExtensionInterf
|
|||||||
PersonDocumentVoter::CREATE => [PersonDocumentVoter::SEE_DETAILS],
|
PersonDocumentVoter::CREATE => [PersonDocumentVoter::SEE_DETAILS],
|
||||||
PersonDocumentVoter::DELETE => [PersonDocumentVoter::SEE_DETAILS],
|
PersonDocumentVoter::DELETE => [PersonDocumentVoter::SEE_DETAILS],
|
||||||
PersonDocumentVoter::SEE_DETAILS => [PersonDocumentVoter::SEE],
|
PersonDocumentVoter::SEE_DETAILS => [PersonDocumentVoter::SEE],
|
||||||
|
AccompanyingCourseDocumentVoter::UPDATE => [AccompanyingCourseDocumentVoter::SEE_DETAILS],
|
||||||
|
AccompanyingCourseDocumentVoter::CREATE => [AccompanyingCourseDocumentVoter::SEE_DETAILS],
|
||||||
|
AccompanyingCourseDocumentVoter::DELETE => [AccompanyingCourseDocumentVoter::SEE_DETAILS],
|
||||||
|
AccompanyingCourseDocumentVoter::SEE_DETAILS => [AccompanyingCourseDocumentVoter::SEE],
|
||||||
)
|
)
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function prependTwig(ContainerBuilder $container)
|
protected function prependTwig(ContainerBuilder $container)
|
||||||
{
|
{
|
||||||
$twigConfig = array(
|
$twigConfig = array(
|
||||||
|
@@ -34,10 +34,10 @@ class DocumentCategory
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\Column(type="json_array")
|
* @ORM\Column(type="json")
|
||||||
*/
|
*/
|
||||||
private $name;
|
private $name;
|
||||||
|
|
||||||
public function __construct($bundleId, $idInsideBundle)
|
public function __construct($bundleId, $idInsideBundle)
|
||||||
{
|
{
|
||||||
$this->bundleId = $bundleId;
|
$this->bundleId = $bundleId;
|
||||||
|
@@ -39,14 +39,14 @@ class StoredObject implements AsyncFileInterface, Document
|
|||||||
private $filename;
|
private $filename;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\Column(type="json_array", name="key")
|
* @ORM\Column(type="json", name="key")
|
||||||
*/
|
*/
|
||||||
private array $keyInfos = [];
|
private array $keyInfos = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @var int[]
|
* @var int[]
|
||||||
* @ORM\Column(type="json_array", name="iv")
|
* @ORM\Column(type="json", name="iv")
|
||||||
*/
|
*/
|
||||||
private array $iv = [];
|
private array $iv = [];
|
||||||
|
|
||||||
@@ -69,7 +69,7 @@ class StoredObject implements AsyncFileInterface, Document
|
|||||||
private string $type = '';
|
private string $type = '';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\Column(type="json_array", name="datas")
|
* @ORM\Column(type="json", name="datas")
|
||||||
* @Serializer\Groups({"read"})
|
* @Serializer\Groups({"read"})
|
||||||
*/
|
*/
|
||||||
private array $datas = [];
|
private array $datas = [];
|
||||||
|
@@ -1,8 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Chill\DocStoreBundle\Repository;
|
declare(strict_types=1);
|
||||||
|
|
||||||
use App\Entity\AccompanyingCourseDocument;
|
namespace Chill\DocStoreBundle\EntityRepository;
|
||||||
|
|
||||||
|
use Chill\DocStoreBundle\Entity\AccompanyingCourseDocument;
|
||||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||||
use Doctrine\Persistence\ManagerRegistry;
|
use Doctrine\Persistence\ManagerRegistry;
|
||||||
|
|
||||||
|
@@ -3,50 +3,27 @@
|
|||||||
*/
|
*/
|
||||||
namespace Chill\DocStoreBundle\Menu;
|
namespace Chill\DocStoreBundle\Menu;
|
||||||
|
|
||||||
|
use Chill\DocStoreBundle\Security\Authorization\AccompanyingCourseDocumentVoter;
|
||||||
use Chill\MainBundle\Routing\LocalMenuBuilderInterface;
|
use Chill\MainBundle\Routing\LocalMenuBuilderInterface;
|
||||||
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
|
|
||||||
use Knp\Menu\MenuItem;
|
use Knp\Menu\MenuItem;
|
||||||
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
|
|
||||||
use Chill\DocStoreBundle\Security\Authorization\PersonDocumentVoter;
|
use Chill\DocStoreBundle\Security\Authorization\PersonDocumentVoter;
|
||||||
use Symfony\Component\Security\Core\Role\Role;
|
use Symfony\Component\Security\Core\Security;
|
||||||
use Symfony\Component\Translation\TranslatorInterface;
|
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||||
|
|
||||||
/**
|
final class MenuBuilder implements LocalMenuBuilderInterface
|
||||||
*
|
|
||||||
*
|
|
||||||
* @author Julien Fastré <julien.fastre@champs-libres.coop>
|
|
||||||
*/
|
|
||||||
class MenuBuilder implements LocalMenuBuilderInterface
|
|
||||||
{
|
{
|
||||||
/**
|
private Security $security;
|
||||||
*
|
protected TranslatorInterface $translator;
|
||||||
* @var TokenStorageInterface
|
|
||||||
*/
|
|
||||||
protected $tokenStorage;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @var AuthorizationHelper
|
|
||||||
*/
|
|
||||||
protected $authorizationHelper;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @var TranslatorInterface
|
|
||||||
*/
|
|
||||||
protected $translator;
|
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
TokenStorageInterface $tokenStorage,
|
Security $security,
|
||||||
AuthorizationHelper $authorizationHelper,
|
|
||||||
TranslatorInterface $translator
|
TranslatorInterface $translator
|
||||||
){
|
) {
|
||||||
$this->tokenStorage = $tokenStorage;
|
$this->security = $security;
|
||||||
$this->authorizationHelper = $authorizationHelper;
|
|
||||||
$this->translator = $translator;
|
$this->translator = $translator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function buildMenu($menuId, MenuItem $menu, array $parameters)
|
public function buildMenu($menuId, MenuItem $menu, array $parameters)
|
||||||
{
|
{
|
||||||
switch($menuId) {
|
switch($menuId) {
|
||||||
@@ -65,11 +42,8 @@ class MenuBuilder implements LocalMenuBuilderInterface
|
|||||||
{
|
{
|
||||||
/* @var $person \Chill\PersonBundle\Entity\Person */
|
/* @var $person \Chill\PersonBundle\Entity\Person */
|
||||||
$person = $parameters['person'];
|
$person = $parameters['person'];
|
||||||
$user = $this->tokenStorage->getToken()->getUser();
|
|
||||||
|
if ($this->security->isGranted(PersonDocumentVoter::SEE, $person)) {
|
||||||
if ($this->authorizationHelper->userHasAccess($user,
|
|
||||||
$person->getCenter(), PersonDocumentVoter::SEE)) {
|
|
||||||
|
|
||||||
$menu->addChild($this->translator->trans('Documents'), [
|
$menu->addChild($this->translator->trans('Documents'), [
|
||||||
'route' => 'person_document_index',
|
'route' => 'person_document_index',
|
||||||
'routeParameters' => [
|
'routeParameters' => [
|
||||||
@@ -80,24 +54,22 @@ class MenuBuilder implements LocalMenuBuilderInterface
|
|||||||
'order'=> 350
|
'order'=> 350
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function buildMenuAccompanyingCourse(MenuItem $menu, array $parameters){
|
protected function buildMenuAccompanyingCourse(MenuItem $menu, array $parameters){
|
||||||
$course = $parameters['accompanyingCourse'];
|
$course = $parameters['accompanyingCourse'];
|
||||||
// $user = $this->tokenStorage->getToken()->getUser();
|
|
||||||
|
|
||||||
//TODO : add condition to check user rights?
|
if ($this->security->isGranted(AccompanyingCourseDocumentVoter::SEE, $course)) {
|
||||||
|
$menu->addChild($this->translator->trans('Documents'), [
|
||||||
$menu->addChild($this->translator->trans('Documents'), [
|
|
||||||
'route' => 'accompanying_course_document_index',
|
'route' => 'accompanying_course_document_index',
|
||||||
'routeParameters' => [
|
'routeParameters' => [
|
||||||
'course' => $course->getId()
|
'course' => $course->getId()
|
||||||
]
|
]
|
||||||
])
|
])
|
||||||
->setExtras([
|
->setExtras([
|
||||||
'order'=> 400
|
'order' => 400
|
||||||
]);
|
]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getMenuIds(): array
|
public static function getMenuIds(): array
|
||||||
|
@@ -3,13 +3,20 @@
|
|||||||
namespace Chill\DocStoreBundle\Security\Authorization;
|
namespace Chill\DocStoreBundle\Security\Authorization;
|
||||||
|
|
||||||
use Chill\DocStoreBundle\Entity\AccompanyingCourseDocument;
|
use Chill\DocStoreBundle\Entity\AccompanyingCourseDocument;
|
||||||
|
use Chill\DocStoreBundle\Entity\PersonDocument;
|
||||||
use Chill\MainBundle\Security\Authorization\AbstractChillVoter;
|
use Chill\MainBundle\Security\Authorization\AbstractChillVoter;
|
||||||
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
|
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
|
||||||
|
use Chill\MainBundle\Security\Authorization\VoterHelperFactoryInterface;
|
||||||
|
use Chill\MainBundle\Security\Authorization\VoterHelperInterface;
|
||||||
use Chill\MainBundle\Security\ProvideRoleHierarchyInterface;
|
use Chill\MainBundle\Security\ProvideRoleHierarchyInterface;
|
||||||
use Chill\MainBundle\Entity\User;
|
use Chill\MainBundle\Entity\User;
|
||||||
|
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||||
|
use Chill\PersonBundle\Entity\Person;
|
||||||
|
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter;
|
||||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||||
use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface;
|
use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface;
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
|
use Symfony\Component\Security\Core\Security;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@@ -22,30 +29,22 @@ class AccompanyingCourseDocumentVoter extends AbstractChillVoter implements Prov
|
|||||||
const UPDATE = 'CHILL_ACCOMPANYING_COURSE_DOCUMENT_UPDATE';
|
const UPDATE = 'CHILL_ACCOMPANYING_COURSE_DOCUMENT_UPDATE';
|
||||||
const DELETE = 'CHILL_ACCOMPANYING_COURSE_DOCUMENT_DELETE';
|
const DELETE = 'CHILL_ACCOMPANYING_COURSE_DOCUMENT_DELETE';
|
||||||
|
|
||||||
/**
|
protected LoggerInterface $logger;
|
||||||
* @var AuthorizationHelper
|
protected VoterHelperInterface $voterHelper;
|
||||||
*/
|
protected Security $security;
|
||||||
protected $authorizationHelper;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var AccessDecisionManagerInterface
|
|
||||||
*/
|
|
||||||
protected $accessDecisionManager;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var LoggerInterface
|
|
||||||
*/
|
|
||||||
protected $logger;
|
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
AccessDecisionManagerInterface $accessDecisionManager,
|
LoggerInterface $logger,
|
||||||
AuthorizationHelper $authorizationHelper,
|
Security $security,
|
||||||
LoggerInterface $logger
|
VoterHelperFactoryInterface $voterHelperFactory
|
||||||
)
|
) {
|
||||||
{
|
|
||||||
$this->accessDecisionManager = $accessDecisionManager;
|
|
||||||
$this->authorizationHelper = $authorizationHelper;
|
|
||||||
$this->logger = $logger;
|
$this->logger = $logger;
|
||||||
|
$this->security = $security;
|
||||||
|
$this->voterHelper = $voterHelperFactory
|
||||||
|
->generate(self::class)
|
||||||
|
->addCheckFor(AccompanyingCourseDocument::class, $this->getRoles())
|
||||||
|
->addCheckFor(AccompanyingPeriod::class, [self::SEE, self::CREATE])
|
||||||
|
->build();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getRoles()
|
public function getRoles()
|
||||||
@@ -61,26 +60,30 @@ class AccompanyingCourseDocumentVoter extends AbstractChillVoter implements Prov
|
|||||||
|
|
||||||
protected function supports($attribute, $subject)
|
protected function supports($attribute, $subject)
|
||||||
{
|
{
|
||||||
|
return $this->voterHelper->supports($attribute, $subject);
|
||||||
if (\in_array($attribute, $this->getRoles())) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function voteOnAttribute($attribute, $subject, TokenInterface $token)
|
protected function voteOnAttribute($attribute, $subject, TokenInterface $token)
|
||||||
{
|
{
|
||||||
return true;
|
$this->logger->debug(sprintf("Voting from %s class", self::class));
|
||||||
}
|
|
||||||
|
|
||||||
|
if (!$token->getUser() instanceof User) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($subject instanceof AccompanyingCourseDocument
|
||||||
|
&& !$this->security->isGranted(AccompanyingPeriodVoter::SEE, $subject->getCourse())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->voterHelper->voteOnAttribute($attribute, $subject, $token);
|
||||||
|
}
|
||||||
|
|
||||||
public function getRolesWithoutScope()
|
public function getRolesWithoutScope()
|
||||||
{
|
{
|
||||||
return array();
|
return array();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function getRolesWithHierarchy()
|
public function getRolesWithHierarchy()
|
||||||
{
|
{
|
||||||
return ['accompanyingCourseDocument' => $this->getRoles() ];
|
return ['accompanyingCourseDocument' => $this->getRoles() ];
|
||||||
|
@@ -19,8 +19,11 @@
|
|||||||
|
|
||||||
namespace Chill\DocStoreBundle\Security\Authorization;
|
namespace Chill\DocStoreBundle\Security\Authorization;
|
||||||
|
|
||||||
|
use App\Security\Authorization\VoterHelperFactory;
|
||||||
use Chill\MainBundle\Security\Authorization\AbstractChillVoter;
|
use Chill\MainBundle\Security\Authorization\AbstractChillVoter;
|
||||||
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
|
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
|
||||||
|
use Chill\MainBundle\Security\Authorization\VoterHelperFactoryInterface;
|
||||||
|
use Chill\MainBundle\Security\Authorization\VoterHelperInterface;
|
||||||
use Chill\MainBundle\Security\ProvideRoleHierarchyInterface;
|
use Chill\MainBundle\Security\ProvideRoleHierarchyInterface;
|
||||||
use Chill\DocStoreBundle\Entity\PersonDocument;
|
use Chill\DocStoreBundle\Entity\PersonDocument;
|
||||||
use Chill\MainBundle\Security\Resolver\CenterResolverDispatcher;
|
use Chill\MainBundle\Security\Resolver\CenterResolverDispatcher;
|
||||||
@@ -31,6 +34,7 @@ use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface
|
|||||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||||
use Symfony\Component\Security\Core\Role\Role;
|
use Symfony\Component\Security\Core\Role\Role;
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
|
use Symfony\Component\Security\Core\Security;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@@ -43,25 +47,22 @@ class PersonDocumentVoter extends AbstractChillVoter implements ProvideRoleHiera
|
|||||||
const UPDATE = 'CHILL_PERSON_DOCUMENT_UPDATE';
|
const UPDATE = 'CHILL_PERSON_DOCUMENT_UPDATE';
|
||||||
const DELETE = 'CHILL_PERSON_DOCUMENT_DELETE';
|
const DELETE = 'CHILL_PERSON_DOCUMENT_DELETE';
|
||||||
|
|
||||||
protected AuthorizationHelper $authorizationHelper;
|
|
||||||
|
|
||||||
protected AccessDecisionManagerInterface $accessDecisionManager;
|
|
||||||
|
|
||||||
protected LoggerInterface $logger;
|
protected LoggerInterface $logger;
|
||||||
|
protected Security $security;
|
||||||
protected CenterResolverDispatcher $centerResolverDispatcher;
|
protected VoterHelperInterface $voterHelper;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
AccessDecisionManagerInterface $accessDecisionManager,
|
LoggerInterface $logger,
|
||||||
AuthorizationHelper $authorizationHelper,
|
Security $security,
|
||||||
LoggerInterface $logger//,
|
VoterHelperFactoryInterface $voterHelperFactory
|
||||||
//CenterResolverDispatcher $centerResolverDispatcher
|
) {
|
||||||
)
|
|
||||||
{
|
|
||||||
$this->accessDecisionManager = $accessDecisionManager;
|
|
||||||
$this->authorizationHelper = $authorizationHelper;
|
|
||||||
$this->logger = $logger;
|
$this->logger = $logger;
|
||||||
//$this->centerResolverDispatcher = $centerResolverDispatcher;
|
$this->security = $security;
|
||||||
|
$this->voterHelper = $voterHelperFactory
|
||||||
|
->generate(self::class)
|
||||||
|
->addCheckFor(PersonDocument::class, $this->getRoles())
|
||||||
|
->addCheckFor(Person::class, [self::SEE, self::CREATE])
|
||||||
|
->build();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getRoles()
|
public function getRoles()
|
||||||
@@ -77,16 +78,7 @@ class PersonDocumentVoter extends AbstractChillVoter implements ProvideRoleHiera
|
|||||||
|
|
||||||
protected function supports($attribute, $subject)
|
protected function supports($attribute, $subject)
|
||||||
{
|
{
|
||||||
if (\in_array($attribute, $this->getRoles()) && $subject instanceof PersonDocument) {
|
return $this->voterHelper->supports($attribute, $subject);
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($subject instanceof Person
|
|
||||||
&& \in_array($attribute, [self::CREATE, self::SEE])) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -104,42 +96,12 @@ class PersonDocumentVoter extends AbstractChillVoter implements ProvideRoleHiera
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$center = $this->centerResolverDispatcher->resolveCenter($subject);
|
if ($subject instanceof PersonDocument
|
||||||
|
&& !$this->security->isGranted(PersonVoter::SEE, $subject->getPerson())) {
|
||||||
if ($subject instanceof PersonDocument) {
|
|
||||||
return $this->authorizationHelper->userHasAccess($token->getUser(), $subject, $attribute);
|
|
||||||
|
|
||||||
} elseif ($subject instanceof Person) {
|
|
||||||
return $this->authorizationHelper->userHasAccess($token->getUser(), $subject, $attribute);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
// subject is null. We check that at least one center is reachable
|
|
||||||
$centers = $this->authorizationHelper
|
|
||||||
->getReachableCenters($token->getUser(), new Role($attribute));
|
|
||||||
|
|
||||||
return count($centers) > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$this->accessDecisionManager->decide($token, [PersonVoter::SEE], $person)) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->authorizationHelper->userHasAccess(
|
return $this->voterHelper->voteOnAttribute($attribute, $subject, $token);
|
||||||
$token->getUser(),
|
|
||||||
$subject,
|
|
||||||
$attribute
|
|
||||||
);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function isGranted($attribute, $report, $user = null)
|
|
||||||
{
|
|
||||||
if (! $user instanceof User){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->helper->userHasAccess($user, $report, $attribute);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getRolesWithoutScope()
|
public function getRolesWithoutScope()
|
||||||
|
@@ -1,8 +1,4 @@
|
|||||||
services:
|
services:
|
||||||
Chill\DocStoreBundle\Menu\MenuBuilder:
|
Chill\DocStoreBundle\Menu\MenuBuilder:
|
||||||
arguments:
|
autowire: true
|
||||||
$tokenStorage: '@Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface'
|
autoconfigure: true
|
||||||
$authorizationHelper: '@Chill\MainBundle\Security\Authorization\AuthorizationHelper'
|
|
||||||
$translator: '@Symfony\Component\Translation\TranslatorInterface'
|
|
||||||
tags:
|
|
||||||
- { name: 'chill.menu_builder' }
|
|
||||||
|
@@ -17,7 +17,6 @@ final class Version20180605102533 extends AbstractMigration
|
|||||||
$this->addSql('CREATE SCHEMA chill_doc');
|
$this->addSql('CREATE SCHEMA chill_doc');
|
||||||
$this->addSql('CREATE SEQUENCE chill_doc.person_document_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
|
$this->addSql('CREATE SEQUENCE chill_doc.person_document_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
|
||||||
$this->addSql('CREATE TABLE chill_doc.document_category (bundle_id VARCHAR(255) NOT NULL, id_inside_bundle INT NOT NULL, document_class VARCHAR(255) NOT NULL, name JSON NOT NULL, PRIMARY KEY(bundle_id, id_inside_bundle))');
|
$this->addSql('CREATE TABLE chill_doc.document_category (bundle_id VARCHAR(255) NOT NULL, id_inside_bundle INT NOT NULL, document_class VARCHAR(255) NOT NULL, name JSON NOT NULL, PRIMARY KEY(bundle_id, id_inside_bundle))');
|
||||||
$this->addSql('COMMENT ON COLUMN chill_doc.document_category.name IS \'(DC2Type:json_array)\'');
|
|
||||||
$this->addSql('CREATE TABLE chill_doc.person_document (id INT NOT NULL, category_bundle_id VARCHAR(255) DEFAULT NULL, category_id_inside_bundle INT DEFAULT NULL, scope_id INT DEFAULT NULL, user_id INT DEFAULT NULL, person_id INT DEFAULT NULL, title TEXT NOT NULL, description TEXT NOT NULL, content TEXT NOT NULL, date TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, PRIMARY KEY(id))');
|
$this->addSql('CREATE TABLE chill_doc.person_document (id INT NOT NULL, category_bundle_id VARCHAR(255) DEFAULT NULL, category_id_inside_bundle INT DEFAULT NULL, scope_id INT DEFAULT NULL, user_id INT DEFAULT NULL, person_id INT DEFAULT NULL, title TEXT NOT NULL, description TEXT NOT NULL, content TEXT NOT NULL, date TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, PRIMARY KEY(id))');
|
||||||
$this->addSql('CREATE INDEX IDX_41DA53C369A0BE36EF62EFC ON chill_doc.person_document (category_bundle_id, category_id_inside_bundle)');
|
$this->addSql('CREATE INDEX IDX_41DA53C369A0BE36EF62EFC ON chill_doc.person_document (category_bundle_id, category_id_inside_bundle)');
|
||||||
$this->addSql('CREATE INDEX IDX_41DA53C682B5931 ON chill_doc.person_document (scope_id)');
|
$this->addSql('CREATE INDEX IDX_41DA53C682B5931 ON chill_doc.person_document (scope_id)');
|
||||||
@@ -34,6 +33,6 @@ final class Version20180605102533 extends AbstractMigration
|
|||||||
$this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', 'Migration can only be executed safely on \'postgresql\'.');
|
$this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', 'Migration can only be executed safely on \'postgresql\'.');
|
||||||
|
|
||||||
$this->addSql('DROP SCHEMA chill_doc CASCADE');
|
$this->addSql('DROP SCHEMA chill_doc CASCADE');
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -16,9 +16,6 @@ final class Version20180606133338 extends AbstractMigration
|
|||||||
|
|
||||||
$this->addSql('CREATE SEQUENCE chill_doc.stored_object_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
|
$this->addSql('CREATE SEQUENCE chill_doc.stored_object_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
|
||||||
$this->addSql('CREATE TABLE chill_doc.stored_object (id INT NOT NULL, filename TEXT NOT NULL, key JSON NOT NULL, iv JSON NOT NULL, creation_date TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, type TEXT NOT NULL, datas JSON NOT NULL, PRIMARY KEY(id))');
|
$this->addSql('CREATE TABLE chill_doc.stored_object (id INT NOT NULL, filename TEXT NOT NULL, key JSON NOT NULL, iv JSON NOT NULL, creation_date TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, type TEXT NOT NULL, datas JSON NOT NULL, PRIMARY KEY(id))');
|
||||||
$this->addSql('COMMENT ON COLUMN chill_doc.stored_object.key IS \'(DC2Type:json_array)\'');
|
|
||||||
$this->addSql('COMMENT ON COLUMN chill_doc.stored_object.iv IS \'(DC2Type:json_array)\'');
|
|
||||||
$this->addSql('COMMENT ON COLUMN chill_doc.stored_object.datas IS \'(DC2Type:json_array)\'');
|
|
||||||
$this->addSql('ALTER TABLE chill_doc.person_document ADD object_id INT DEFAULT NULL');
|
$this->addSql('ALTER TABLE chill_doc.person_document ADD object_id INT DEFAULT NULL');
|
||||||
$this->addSql('ALTER TABLE chill_doc.person_document DROP content');
|
$this->addSql('ALTER TABLE chill_doc.person_document DROP content');
|
||||||
$this->addSql('ALTER TABLE chill_doc.person_document ADD CONSTRAINT FK_41DA53C232D562B FOREIGN KEY (object_id) REFERENCES chill_doc.stored_object (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
|
$this->addSql('ALTER TABLE chill_doc.person_document ADD CONSTRAINT FK_41DA53C232D562B FOREIGN KEY (object_id) REFERENCES chill_doc.stored_object (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
|
||||||
|
@@ -39,12 +39,12 @@ use Symfony\Component\Form\Extension\Core\Type\CollectionType;
|
|||||||
*/
|
*/
|
||||||
class ParticipationController extends AbstractController
|
class ParticipationController extends AbstractController
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var \Psr\Log\LoggerInterface
|
* @var \Psr\Log\LoggerInterface
|
||||||
*/
|
*/
|
||||||
private $logger;
|
private $logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ParticipationController constructor.
|
* ParticipationController constructor.
|
||||||
*
|
*
|
||||||
@@ -54,10 +54,10 @@ class ParticipationController extends AbstractController
|
|||||||
{
|
{
|
||||||
$this->logger = $logger;
|
$this->logger = $logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show a form to add a participation
|
* Show a form to add a participation
|
||||||
*
|
*
|
||||||
* This function parse the person_id / persons_ids query argument
|
* This function parse the person_id / persons_ids query argument
|
||||||
* and decide if it should process a single or multiple participation. Depending
|
* and decide if it should process a single or multiple participation. Depending
|
||||||
* on this, the appropriate layout and form.
|
* on this, the appropriate layout and form.
|
||||||
@@ -67,46 +67,46 @@ class ParticipationController extends AbstractController
|
|||||||
*/
|
*/
|
||||||
public function newAction(Request $request)
|
public function newAction(Request $request)
|
||||||
{
|
{
|
||||||
|
|
||||||
// test the request is correct
|
// test the request is correct
|
||||||
try {
|
try {
|
||||||
$this->testRequest($request);
|
$this->testRequest($request);
|
||||||
} catch (\RuntimeException $ex) {
|
} catch (\RuntimeException $ex) {
|
||||||
$this->logger->warning($ex->getMessage());
|
$this->logger->warning($ex->getMessage());
|
||||||
|
|
||||||
return (new Response())
|
return (new Response())
|
||||||
->setStatusCode(Response::HTTP_BAD_REQUEST)
|
->setStatusCode(Response::HTTP_BAD_REQUEST)
|
||||||
->setContent($ex->getMessage());
|
->setContent($ex->getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
// forward to other action
|
// forward to other action
|
||||||
$single = $request->query->has('person_id');
|
$single = $request->query->has('person_id');
|
||||||
$multiple = $request->query->has('persons_ids');
|
$multiple = $request->query->has('persons_ids');
|
||||||
|
|
||||||
if ($single === true) {
|
if ($single === true) {
|
||||||
return $this->newSingle($request);
|
return $this->newSingle($request);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($multiple === true) {
|
if ($multiple === true) {
|
||||||
|
|
||||||
return $this->newMultiple($request);
|
return $this->newMultiple($request);
|
||||||
}
|
}
|
||||||
|
|
||||||
// at this point, we miss the required fields. Throw an error
|
// at this point, we miss the required fields. Throw an error
|
||||||
return (new Response())
|
return (new Response())
|
||||||
->setStatusCode(Response::HTTP_BAD_REQUEST)
|
->setStatusCode(Response::HTTP_BAD_REQUEST)
|
||||||
->setContent("You must provide either 'person_id' or "
|
->setContent("You must provide either 'person_id' or "
|
||||||
. "'persons_ids' argument in query");
|
. "'persons_ids' argument in query");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Test that the query parameters are valid :
|
* Test that the query parameters are valid :
|
||||||
*
|
*
|
||||||
* - an `event_id` is existing ;
|
* - an `event_id` is existing ;
|
||||||
* - `person_id` and `persons_ids` are **not** both present ;
|
* - `person_id` and `persons_ids` are **not** both present ;
|
||||||
* - `persons_id` is correct (contains only numbers and a ','.
|
* - `persons_id` is correct (contains only numbers and a ','.
|
||||||
*
|
*
|
||||||
* @param Request $request
|
* @param Request $request
|
||||||
* @throws \RuntimeException if an error is detected
|
* @throws \RuntimeException if an error is detected
|
||||||
*/
|
*/
|
||||||
@@ -114,64 +114,64 @@ class ParticipationController extends AbstractController
|
|||||||
{
|
{
|
||||||
$single = $request->query->has('person_id');
|
$single = $request->query->has('person_id');
|
||||||
$multiple = $request->query->has('persons_ids');
|
$multiple = $request->query->has('persons_ids');
|
||||||
|
|
||||||
if ($single === true AND $multiple === true) {
|
if ($single === true AND $multiple === true) {
|
||||||
// we are not allowed to have both person_id and persons_ids
|
// we are not allowed to have both person_id and persons_ids
|
||||||
throw new \RuntimeException("You are not allow to provide both 'person_id' and "
|
throw new \RuntimeException("You are not allow to provide both 'person_id' and "
|
||||||
. "'persons_ids' simulaneously");
|
. "'persons_ids' simulaneously");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($multiple === true) {
|
if ($multiple === true) {
|
||||||
$persons_ids = $request->query->get('persons_ids');
|
$persons_ids = $request->query->get('persons_ids');
|
||||||
|
|
||||||
if (!preg_match('/^([0-9]{1,},{0,1}){1,}[0-9]{0,}$/', $persons_ids)) {
|
if (!preg_match('/^([0-9]{1,},{0,1}){1,}[0-9]{0,}$/', $persons_ids)) {
|
||||||
throw new \RuntimeException("The persons_ids value should "
|
throw new \RuntimeException("The persons_ids value should "
|
||||||
. "contains int separated by ','");
|
. "contains int separated by ','");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// check for event_id - this could be removed later
|
// check for event_id - this could be removed later
|
||||||
if ($request->query->has('event_id') === FALSE) {
|
if ($request->query->has('event_id') === FALSE) {
|
||||||
throw new \RuntimeException("You must provide an event_id");
|
throw new \RuntimeException("You must provide an event_id");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show a form with single participation.
|
* Show a form with single participation.
|
||||||
*
|
*
|
||||||
* @param Request $request
|
* @param Request $request
|
||||||
* @return Response
|
* @return Response
|
||||||
*/
|
*/
|
||||||
protected function newSingle(Request $request)
|
protected function newSingle(Request $request)
|
||||||
{
|
{
|
||||||
|
|
||||||
$returnPath = $request->query->get('return_path') ?
|
$returnPath = $request->query->get('return_path') ?
|
||||||
$request->query->get('return_path') : null;
|
$request->query->get('return_path') : null;
|
||||||
|
|
||||||
$participation = $this->handleRequest($request, new Participation(), false);
|
$participation = $this->handleRequest($request, new Participation(), false);
|
||||||
|
|
||||||
$this->denyAccessUnlessGranted(ParticipationVoter::CREATE,
|
$this->denyAccessUnlessGranted(ParticipationVoter::CREATE,
|
||||||
$participation, 'The user is not allowed to create this participation');
|
$participation, 'The user is not allowed to create this participation');
|
||||||
|
|
||||||
$form = $this->createCreateForm($participation, $returnPath);
|
$form = $this->createCreateForm($participation, $returnPath);
|
||||||
|
|
||||||
return $this->render('ChillEventBundle:Participation:new.html.twig', array(
|
return $this->render('ChillEventBundle:Participation:new.html.twig', array(
|
||||||
'form' => $form->createView(),
|
'form' => $form->createView(),
|
||||||
'participation' => $participation,
|
'participation' => $participation,
|
||||||
'ignored_participations' => array() // this is required, see self::newMultiple
|
'ignored_participations' => array() // this is required, see self::newMultiple
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show a form with multiple participation.
|
* Show a form with multiple participation.
|
||||||
*
|
*
|
||||||
* If a person is already participating on the event (if a participation with
|
* If a person is already participating on the event (if a participation with
|
||||||
* the same person is associated with the event), the participation is ignored.
|
* the same person is associated with the event), the participation is ignored.
|
||||||
*
|
*
|
||||||
* If all but one participation is ignored, the page show the same response
|
* If all but one participation is ignored, the page show the same response
|
||||||
* than the newSingle function.
|
* than the newSingle function.
|
||||||
*
|
*
|
||||||
* If all participations must be ignored, an error is shown and the method redirects
|
* If all participations must be ignored, an error is shown and the method redirects
|
||||||
* to the event 'show' view with an appropriate flash message.
|
* to the event 'show' view with an appropriate flash message.
|
||||||
*
|
*
|
||||||
@@ -181,24 +181,24 @@ class ParticipationController extends AbstractController
|
|||||||
protected function newMultiple(Request $request)
|
protected function newMultiple(Request $request)
|
||||||
{
|
{
|
||||||
$participations = $this->handleRequest($request, new Participation(), true);
|
$participations = $this->handleRequest($request, new Participation(), true);
|
||||||
|
$ignoredParticipations = $newParticipations = [];
|
||||||
|
|
||||||
foreach ($participations as $i => $participation) {
|
foreach ($participations as $i => $participation) {
|
||||||
// check for authorization
|
// check for authorization
|
||||||
$this->denyAccessUnlessGranted(ParticipationVoter::CREATE,
|
$this->denyAccessUnlessGranted(ParticipationVoter::CREATE,
|
||||||
$participation, 'The user is not allowed to create this participation');
|
$participation, 'The user is not allowed to create this participation');
|
||||||
|
|
||||||
// create a collection of person's id participating to the event
|
// create a collection of person's id participating to the event
|
||||||
/* @var $peopleParticipating \Doctrine\Common\Collections\ArrayCollection */
|
/* @var $peopleParticipating \Doctrine\Common\Collections\ArrayCollection */
|
||||||
$peopleParticipating = isset($peopleParticipating) ? $peopleParticipating :
|
$peopleParticipating = isset($peopleParticipating) ? $peopleParticipating :
|
||||||
$participation->getEvent()->getParticipations()->map(
|
$participation->getEvent()->getParticipations()->map(
|
||||||
function(Participation $p) { return $p->getPerson()->getId(); }
|
function(Participation $p) { return $p->getPerson()->getId(); }
|
||||||
);
|
);
|
||||||
// check that the user is not already in the event
|
// check that the user is not already in the event
|
||||||
if ($peopleParticipating->contains($participation->getPerson()->getId())) {
|
if ($peopleParticipating->contains($participation->getPerson()->getId())) {
|
||||||
$ignoredParticipations[] = $participation
|
$ignoredParticipations[] = $participation
|
||||||
->getEvent()->getParticipations()->filter(
|
->getEvent()->getParticipations()->filter(
|
||||||
function (Participation $p) use ($participation) {
|
function (Participation $p) use ($participation) {
|
||||||
return $p->getPerson()->getId() === $participation->getPerson()->getId();
|
return $p->getPerson()->getId() === $participation->getPerson()->getId();
|
||||||
}
|
}
|
||||||
)->first();
|
)->first();
|
||||||
@@ -206,15 +206,15 @@ class ParticipationController extends AbstractController
|
|||||||
$newParticipations[] = $participation;
|
$newParticipations[] = $participation;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// this is where the function redirect depending on valid participation
|
// this is where the function redirect depending on valid participation
|
||||||
|
|
||||||
if (!isset($newParticipations)) {
|
if ([] === $newParticipations) {
|
||||||
// if we do not have nay participants, redirect to event view
|
// if we do not have nay participants, redirect to event view
|
||||||
$this->addFlash('error', $this->get('translator')->trans(
|
$this->addFlash('error', $this->get('translator')->trans(
|
||||||
'None of the requested people may participate '
|
'None of the requested people may participate '
|
||||||
. 'the event: they are maybe already participating.'));
|
. 'the event: they are maybe already participating.'));
|
||||||
|
|
||||||
return $this->redirectToRoute('chill_event__event_show', array(
|
return $this->redirectToRoute('chill_event__event_show', array(
|
||||||
'event_id' => $request->query->getInt('event_id', 0)
|
'event_id' => $request->query->getInt('event_id', 0)
|
||||||
));
|
));
|
||||||
@@ -222,24 +222,29 @@ class ParticipationController extends AbstractController
|
|||||||
// if we have multiple participations, show a form with multiple participations
|
// if we have multiple participations, show a form with multiple participations
|
||||||
$form = $this->createCreateFormMultiple($newParticipations);
|
$form = $this->createCreateFormMultiple($newParticipations);
|
||||||
|
|
||||||
return $this->render('ChillEventBundle:Participation:new-multiple.html.twig', array(
|
return $this->render(
|
||||||
|
'ChillEventBundle:Participation:new-multiple.html.twig',
|
||||||
|
[
|
||||||
'form' => $form->createView(),
|
'form' => $form->createView(),
|
||||||
'participations' => $newParticipations,
|
'participations' => $newParticipations,
|
||||||
'ignored_participations' => isset($ignoredParticipations) ? $ignoredParticipations : array()
|
'ignored_participations' => $ignoredParticipations
|
||||||
));
|
]
|
||||||
} else {
|
);
|
||||||
// if we have only one participation, show the same form than for single participation
|
}
|
||||||
$form = $this->createCreateForm($participation);
|
|
||||||
|
// if we have only one participation, show the same form than for single participation
|
||||||
return $this->render('ChillEventBundle:Participation:new.html.twig', array(
|
$form = $this->createCreateForm($participation);
|
||||||
|
|
||||||
|
return $this->render(
|
||||||
|
'ChillEventBundle:Participation:new.html.twig',
|
||||||
|
[
|
||||||
'form' => $form->createView(),
|
'form' => $form->createView(),
|
||||||
'participation' => $participation,
|
'participation' => $participation,
|
||||||
'ignored_participations' => isset($ignoredParticipations) ? $ignoredParticipations : array()
|
'ignored_participations' => $ignoredParticipations,
|
||||||
));
|
]
|
||||||
|
);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Request $request
|
* @param Request $request
|
||||||
* @return \Symfony\Component\HttpFoundation\RedirectResponse|Response
|
* @return \Symfony\Component\HttpFoundation\RedirectResponse|Response
|
||||||
@@ -251,32 +256,32 @@ class ParticipationController extends AbstractController
|
|||||||
$this->testRequest($request);
|
$this->testRequest($request);
|
||||||
} catch (\RuntimeException $ex) {
|
} catch (\RuntimeException $ex) {
|
||||||
$this->logger->warning($ex->getMessage());
|
$this->logger->warning($ex->getMessage());
|
||||||
|
|
||||||
return (new Response())
|
return (new Response())
|
||||||
->setStatusCode(Response::HTTP_BAD_REQUEST)
|
->setStatusCode(Response::HTTP_BAD_REQUEST)
|
||||||
->setContent($ex->getMessage());
|
->setContent($ex->getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
// forward to other action
|
// forward to other action
|
||||||
$single = $request->query->has('person_id');
|
$single = $request->query->has('person_id');
|
||||||
$multiple = $request->query->has('persons_ids');
|
$multiple = $request->query->has('persons_ids');
|
||||||
|
|
||||||
if ($single === true) {
|
if ($single === true) {
|
||||||
return $this->createSingle($request);
|
return $this->createSingle($request);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($multiple === true) {
|
if ($multiple === true) {
|
||||||
|
|
||||||
return $this->createMultiple($request);
|
return $this->createMultiple($request);
|
||||||
}
|
}
|
||||||
|
|
||||||
// at this point, we miss the required fields. Throw an error
|
// at this point, we miss the required fields. Throw an error
|
||||||
return (new Response())
|
return (new Response())
|
||||||
->setStatusCode(Response::HTTP_BAD_REQUEST)
|
->setStatusCode(Response::HTTP_BAD_REQUEST)
|
||||||
->setContent("You must provide either 'person_id' or "
|
->setContent("You must provide either 'person_id' or "
|
||||||
. "'persons_ids' argument in query");
|
. "'persons_ids' argument in query");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Request $request
|
* @param Request $request
|
||||||
* @return \Symfony\Component\HttpFoundation\RedirectResponse|Response
|
* @return \Symfony\Component\HttpFoundation\RedirectResponse|Response
|
||||||
@@ -284,41 +289,41 @@ class ParticipationController extends AbstractController
|
|||||||
public function createSingle(Request $request)
|
public function createSingle(Request $request)
|
||||||
{
|
{
|
||||||
$participation = $this->handleRequest($request, new Participation(), false);
|
$participation = $this->handleRequest($request, new Participation(), false);
|
||||||
|
|
||||||
$this->denyAccessUnlessGranted(ParticipationVoter::CREATE,
|
$this->denyAccessUnlessGranted(ParticipationVoter::CREATE,
|
||||||
$participation, 'The user is not allowed to create this participation');
|
$participation, 'The user is not allowed to create this participation');
|
||||||
|
|
||||||
$form = $this->createCreateForm($participation);
|
$form = $this->createCreateForm($participation);
|
||||||
$form->handleRequest($request);
|
$form->handleRequest($request);
|
||||||
|
|
||||||
if ($form->isSubmitted() && $form->isValid()) {
|
if ($form->isSubmitted() && $form->isValid()) {
|
||||||
$em = $this->getDoctrine()->getManager();
|
$em = $this->getDoctrine()->getManager();
|
||||||
|
|
||||||
$em->persist($participation);
|
$em->persist($participation);
|
||||||
$em->flush();
|
$em->flush();
|
||||||
|
|
||||||
$this->addFlash('success', $this->get('translator')->trans(
|
$this->addFlash('success', $this->get('translator')->trans(
|
||||||
'The participation was created'
|
'The participation was created'
|
||||||
));
|
));
|
||||||
|
|
||||||
if ($request->query->get('return_path'))
|
if ($request->query->get('return_path'))
|
||||||
{
|
{
|
||||||
return $this->redirect($request->query->get('return_path'));
|
return $this->redirect($request->query->get('return_path'));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
return $this->redirectToRoute('chill_event__event_show', array(
|
return $this->redirectToRoute('chill_event__event_show', array(
|
||||||
'event_id' => $participation->getEvent()->getId()
|
'event_id' => $participation->getEvent()->getId()
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->render('ChillEventBundle:Participation:new.html.twig', array(
|
return $this->render('ChillEventBundle:Participation:new.html.twig', array(
|
||||||
'form' => $form->createView(),
|
'form' => $form->createView(),
|
||||||
'participation' => $participation
|
'participation' => $participation
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Request $request
|
* @param Request $request
|
||||||
* @return \Symfony\Component\HttpFoundation\RedirectResponse|Response
|
* @return \Symfony\Component\HttpFoundation\RedirectResponse|Response
|
||||||
@@ -326,56 +331,56 @@ class ParticipationController extends AbstractController
|
|||||||
public function createMultiple(Request $request)
|
public function createMultiple(Request $request)
|
||||||
{
|
{
|
||||||
$participations = $this->handleRequest($request, new Participation(), true);
|
$participations = $this->handleRequest($request, new Participation(), true);
|
||||||
|
|
||||||
foreach($participations as $participation) {
|
foreach($participations as $participation) {
|
||||||
$this->denyAccessUnlessGranted(ParticipationVoter::CREATE,
|
$this->denyAccessUnlessGranted(ParticipationVoter::CREATE,
|
||||||
$participation, 'The user is not allowed to create this participation');
|
$participation, 'The user is not allowed to create this participation');
|
||||||
}
|
}
|
||||||
|
|
||||||
$form = $this->createCreateFormMultiple($participations);
|
$form = $this->createCreateFormMultiple($participations);
|
||||||
$form->handleRequest($request);
|
$form->handleRequest($request);
|
||||||
|
|
||||||
if ($form->isSubmitted() && $form->isValid()) {
|
if ($form->isSubmitted() && $form->isValid()) {
|
||||||
$em = $this->getDoctrine()->getManager();
|
$em = $this->getDoctrine()->getManager();
|
||||||
$data = $form->getData();
|
$data = $form->getData();
|
||||||
|
|
||||||
foreach($data['participations'] as $participation) {
|
foreach($data['participations'] as $participation) {
|
||||||
$em->persist($participation);
|
$em->persist($participation);
|
||||||
}
|
}
|
||||||
|
|
||||||
$em->flush();
|
$em->flush();
|
||||||
|
|
||||||
$this->addFlash('success', $this->get('translator')->trans(
|
$this->addFlash('success', $this->get('translator')->trans(
|
||||||
'The participations were created'
|
'The participations were created'
|
||||||
));
|
));
|
||||||
|
|
||||||
return $this->redirectToRoute('chill_event__event_show', array(
|
return $this->redirectToRoute('chill_event__event_show', array(
|
||||||
'event_id' => $participations[0]->getEvent()->getId()
|
'event_id' => $participations[0]->getEvent()->getId()
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->render('ChillEventBundle:Participation:new.html.twig', array(
|
return $this->render('ChillEventBundle:Participation:new.html.twig', array(
|
||||||
'form' => $form->createView(),
|
'form' => $form->createView(),
|
||||||
'participation' => $participation
|
'participation' => $participation
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Handle the request to adapt $participation.
|
* Handle the request to adapt $participation.
|
||||||
*
|
*
|
||||||
* If the request is multiple, the $participation object is cloned.
|
* If the request is multiple, the $participation object is cloned.
|
||||||
* Limitations: the $participation should not be persisted.
|
* Limitations: the $participation should not be persisted.
|
||||||
*
|
*
|
||||||
* @param Request $request
|
* @param Request $request
|
||||||
* @param Participation $participation
|
* @param Participation $participation
|
||||||
* @param boolean $multiple (default false)
|
* @param boolean $multiple (default false)
|
||||||
* @return Participation|Participations[] return one single participation if $multiple == false
|
* @return Participation|Participations[] return one single participation if $multiple == false
|
||||||
* @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException if the event/person is not found
|
* @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException if the event/person is not found
|
||||||
* @throws \Symfony\Component\Security\Core\Exception\AccessDeniedException if the user does not have access to event/person
|
* @throws \Symfony\Component\Security\Core\Exception\AccessDeniedException if the user does not have access to event/person
|
||||||
*/
|
*/
|
||||||
protected function handleRequest(
|
protected function handleRequest(
|
||||||
Request $request,
|
Request $request,
|
||||||
Participation $participation,
|
Participation $participation,
|
||||||
$multiple = false)
|
$multiple = false)
|
||||||
{
|
{
|
||||||
@@ -384,37 +389,37 @@ class ParticipationController extends AbstractController
|
|||||||
throw new \LogicException("The participation object should not be managed by "
|
throw new \LogicException("The participation object should not be managed by "
|
||||||
. "the object manager using the method ".__METHOD__);
|
. "the object manager using the method ".__METHOD__);
|
||||||
}
|
}
|
||||||
|
|
||||||
$event_id = $request->query->getInt('event_id', 0); // sf4 check:
|
$event_id = $request->query->getInt('event_id', 0); // sf4 check:
|
||||||
// prevent error: `Argument 2 passed to ::getInt() must be of the type int, null given`
|
// prevent error: `Argument 2 passed to ::getInt() must be of the type int, null given`
|
||||||
|
|
||||||
if ($event_id !== NULL) {
|
if ($event_id !== NULL) {
|
||||||
$event = $em->getRepository('ChillEventBundle:Event')
|
$event = $em->getRepository('ChillEventBundle:Event')
|
||||||
->find($event_id);
|
->find($event_id);
|
||||||
|
|
||||||
if ($event === NULL) {
|
if ($event === NULL) {
|
||||||
throw $this->createNotFoundException('The event with id '.$event_id.' is not found');
|
throw $this->createNotFoundException('The event with id '.$event_id.' is not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->denyAccessUnlessGranted('CHILL_EVENT_SEE', $event,
|
$this->denyAccessUnlessGranted('CHILL_EVENT_SEE', $event,
|
||||||
'The user is not allowed to see the event');
|
'The user is not allowed to see the event');
|
||||||
|
|
||||||
$participation->setEvent($event);
|
$participation->setEvent($event);
|
||||||
}
|
}
|
||||||
|
|
||||||
// this script should be able to handle multiple, so we translate
|
// this script should be able to handle multiple, so we translate
|
||||||
// single person_id in an array
|
// single person_id in an array
|
||||||
$persons_ids = $request->query->has('person_id') ?
|
$persons_ids = $request->query->has('person_id') ?
|
||||||
[$request->query->getInt('person_id', 0)] // sf4 check:
|
[$request->query->getInt('person_id', 0)] // sf4 check:
|
||||||
// prevent error: `Argument 2 passed to ::getInt() must be of the type int, null given`
|
// prevent error: `Argument 2 passed to ::getInt() must be of the type int, null given`
|
||||||
: explode(',', $request->query->get('persons_ids'));
|
: explode(',', $request->query->get('persons_ids'));
|
||||||
$participations = array();
|
$participations = array();
|
||||||
|
|
||||||
foreach($persons_ids as $person_id) {
|
foreach($persons_ids as $person_id) {
|
||||||
|
|
||||||
// clone if we have to reuse the $participation
|
// clone if we have to reuse the $participation
|
||||||
$participation = count($persons_ids) > 1 ? clone $participation : $participation;
|
$participation = count($persons_ids) > 1 ? clone $participation : $participation;
|
||||||
|
|
||||||
if ($person_id !== NULL) {
|
if ($person_id !== NULL) {
|
||||||
$person = $em->getRepository('ChillPersonBundle:Person')
|
$person = $em->getRepository('ChillPersonBundle:Person')
|
||||||
->find($person_id);
|
->find($person_id);
|
||||||
@@ -428,13 +433,13 @@ class ParticipationController extends AbstractController
|
|||||||
|
|
||||||
$participation->setPerson($person);
|
$participation->setPerson($person);
|
||||||
}
|
}
|
||||||
|
|
||||||
$participations[] = $participation;
|
$participations[] = $participation;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $multiple ? $participations : $participations[0];
|
return $multiple ? $participations : $participations[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Participation $participation
|
* @param Participation $participation
|
||||||
* @param null $return_path
|
* @param null $return_path
|
||||||
@@ -442,7 +447,7 @@ class ParticipationController extends AbstractController
|
|||||||
*/
|
*/
|
||||||
public function createCreateForm(Participation $participation, $return_path = null)
|
public function createCreateForm(Participation $participation, $return_path = null)
|
||||||
{
|
{
|
||||||
|
|
||||||
$form = $this->createForm(ParticipationType::class, $participation, array(
|
$form = $this->createForm(ParticipationType::class, $participation, array(
|
||||||
'event_type' => $participation->getEvent()->getType(),
|
'event_type' => $participation->getEvent()->getType(),
|
||||||
'action' => $this->generateUrl('chill_event_participation_create', array(
|
'action' => $this->generateUrl('chill_event_participation_create', array(
|
||||||
@@ -451,14 +456,14 @@ class ParticipationController extends AbstractController
|
|||||||
'person_id' => $participation->getPerson()->getId()
|
'person_id' => $participation->getPerson()->getId()
|
||||||
))
|
))
|
||||||
));
|
));
|
||||||
|
|
||||||
$form->add('submit', SubmitType::class, array(
|
$form->add('submit', SubmitType::class, array(
|
||||||
'label' => 'Create'
|
'label' => 'Create'
|
||||||
));
|
));
|
||||||
|
|
||||||
return $form;
|
return $form;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array $participations
|
* @param array $participations
|
||||||
* @return \Symfony\Component\Form\FormInterface
|
* @return \Symfony\Component\Form\FormInterface
|
||||||
@@ -470,7 +475,7 @@ class ParticipationController extends AbstractController
|
|||||||
'action' => $this->generateUrl('chill_event_participation_create', array(
|
'action' => $this->generateUrl('chill_event_participation_create', array(
|
||||||
'event_id' => current($participations)->getEvent()->getId(),
|
'event_id' => current($participations)->getEvent()->getId(),
|
||||||
'persons_ids' => implode(',', array_map(
|
'persons_ids' => implode(',', array_map(
|
||||||
function(Participation $p) { return $p->getPerson()->getId(); },
|
function(Participation $p) { return $p->getPerson()->getId(); },
|
||||||
$participations))
|
$participations))
|
||||||
)
|
)
|
||||||
)));
|
)));
|
||||||
@@ -481,90 +486,90 @@ class ParticipationController extends AbstractController
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
$form->add('submit', SubmitType::class, array(
|
$form->add('submit', SubmitType::class, array(
|
||||||
'label' => 'Create'
|
'label' => 'Create'
|
||||||
));
|
));
|
||||||
|
|
||||||
return $form;
|
return $form;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* show an edit form for the participation with the given id.
|
* show an edit form for the participation with the given id.
|
||||||
*
|
*
|
||||||
* @param int $participation_id
|
* @param int $participation_id
|
||||||
* @return \Symfony\Component\HttpFoundation\Response
|
* @return \Symfony\Component\HttpFoundation\Response
|
||||||
* @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException if the participation is not found
|
* @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException if the participation is not found
|
||||||
* @throws \Symfony\Component\HttpFoundation\File\Exception\AccessDeniedException if the user is not allowed to edit the participation
|
* @throws \Symfony\Component\HttpFoundation\File\Exception\AccessDeniedException if the user is not allowed to edit the participation
|
||||||
*/
|
*/
|
||||||
public function editAction($participation_id)
|
public function editAction($participation_id)
|
||||||
{
|
{
|
||||||
/* @var $participation Participation */
|
/* @var $participation Participation */
|
||||||
$participation = $this->getDoctrine()->getManager()
|
$participation = $this->getDoctrine()->getManager()
|
||||||
->getRepository('ChillEventBundle:Participation')
|
->getRepository('ChillEventBundle:Participation')
|
||||||
->find($participation_id);
|
->find($participation_id);
|
||||||
|
|
||||||
if ($participation === NULL) {
|
if ($participation === NULL) {
|
||||||
throw $this->createNotFoundException('The participation is not found');
|
throw $this->createNotFoundException('The participation is not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->denyAccessUnlessGranted(ParticipationVoter::UPDATE, $participation,
|
$this->denyAccessUnlessGranted(ParticipationVoter::UPDATE, $participation,
|
||||||
'You are not allowed to edit this participation');
|
'You are not allowed to edit this participation');
|
||||||
|
|
||||||
$form = $this->createEditForm($participation);
|
$form = $this->createEditForm($participation);
|
||||||
|
|
||||||
return $this->render('ChillEventBundle:Participation:edit.html.twig', array(
|
return $this->render('ChillEventBundle:Participation:edit.html.twig', array(
|
||||||
'form' => $form->createView(),
|
'form' => $form->createView(),
|
||||||
'participation' => $participation
|
'participation' => $participation
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $participation_id
|
* @param $participation_id
|
||||||
* @param Request $request
|
* @param Request $request
|
||||||
* @return \Symfony\Component\HttpFoundation\RedirectResponse|Response
|
* @return \Symfony\Component\HttpFoundation\RedirectResponse|Response
|
||||||
*/
|
*/
|
||||||
public function updateAction($participation_id, Request $request)
|
public function updateAction($participation_id, Request $request)
|
||||||
{
|
{
|
||||||
/* @var $participation Participation */
|
/* @var $participation Participation */
|
||||||
$participation = $this->getDoctrine()->getManager()
|
$participation = $this->getDoctrine()->getManager()
|
||||||
->getRepository('ChillEventBundle:Participation')
|
->getRepository('ChillEventBundle:Participation')
|
||||||
->find($participation_id);
|
->find($participation_id);
|
||||||
|
|
||||||
if ($participation === NULL) {
|
if ($participation === NULL) {
|
||||||
throw $this->createNotFoundException('The participation is not found');
|
throw $this->createNotFoundException('The participation is not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->denyAccessUnlessGranted(ParticipationVoter::UPDATE, $participation,
|
$this->denyAccessUnlessGranted(ParticipationVoter::UPDATE, $participation,
|
||||||
'You are not allowed to edit this participation');
|
'You are not allowed to edit this participation');
|
||||||
|
|
||||||
$form = $this->createEditForm($participation);
|
$form = $this->createEditForm($participation);
|
||||||
|
|
||||||
$form->handleRequest($request);
|
$form->handleRequest($request);
|
||||||
|
|
||||||
if ($form->isSubmitted() && $form->isValid()) {
|
if ($form->isSubmitted() && $form->isValid()) {
|
||||||
$em = $this->getDoctrine()->getManager();
|
$em = $this->getDoctrine()->getManager();
|
||||||
|
|
||||||
$em->flush();
|
$em->flush();
|
||||||
|
|
||||||
$this->addFlash('success', $this->get('translator')->trans(
|
$this->addFlash('success', $this->get('translator')->trans(
|
||||||
'The participation was updated'
|
'The participation was updated'
|
||||||
));
|
));
|
||||||
|
|
||||||
return $this->redirectToRoute('chill_event__event_show', array(
|
return $this->redirectToRoute('chill_event__event_show', array(
|
||||||
'event_id' => $participation->getEvent()->getId()
|
'event_id' => $participation->getEvent()->getId()
|
||||||
));
|
));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->render('ChillEventBundle:Participation:edit.html.twig', array(
|
return $this->render('ChillEventBundle:Participation:edit.html.twig', array(
|
||||||
'form' => $form->createView(),
|
'form' => $form->createView(),
|
||||||
'participation' => $participation
|
'participation' => $participation
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param Participation $participation
|
* @param Participation $participation
|
||||||
* @return \Symfony\Component\Form\FormInterface
|
* @return \Symfony\Component\Form\FormInterface
|
||||||
*/
|
*/
|
||||||
@@ -576,14 +581,14 @@ class ParticipationController extends AbstractController
|
|||||||
'participation_id' => $participation->getId()
|
'participation_id' => $participation->getId()
|
||||||
))
|
))
|
||||||
));
|
));
|
||||||
|
|
||||||
$form->add('submit', SubmitType::class, array(
|
$form->add('submit', SubmitType::class, array(
|
||||||
'label' => 'Edit'
|
'label' => 'Edit'
|
||||||
));
|
));
|
||||||
|
|
||||||
return $form;
|
return $form;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* show a form to edit multiple participation for the same event.
|
* show a form to edit multiple participation for the same event.
|
||||||
*
|
*
|
||||||
@@ -594,84 +599,84 @@ class ParticipationController extends AbstractController
|
|||||||
{
|
{
|
||||||
$event = $this->getDoctrine()->getRepository('ChillEventBundle:Event')
|
$event = $this->getDoctrine()->getRepository('ChillEventBundle:Event')
|
||||||
->find($event_id);
|
->find($event_id);
|
||||||
|
|
||||||
if ($event === null) {
|
if ($event === null) {
|
||||||
throw $this->createNotFoundException("The event with id $event_id is not found");
|
throw $this->createNotFoundException("The event with id $event_id is not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
// check for ACL, on Event level and on Participation Level
|
// check for ACL, on Event level and on Participation Level
|
||||||
$this->denyAccessUnlessGranted('CHILL_EVENT_SEE', $event, "You are not allowed "
|
$this->denyAccessUnlessGranted('CHILL_EVENT_SEE', $event, "You are not allowed "
|
||||||
. "to see this event");
|
. "to see this event");
|
||||||
foreach ($event->getParticipations() as $participation) {
|
foreach ($event->getParticipations() as $participation) {
|
||||||
$this->denyAccessUnlessGranted(ParticipationVoter::UPDATE, $participation,
|
$this->denyAccessUnlessGranted(ParticipationVoter::UPDATE, $participation,
|
||||||
"You are not allowed to update participation with id ".$participation->getId());
|
"You are not allowed to update participation with id ".$participation->getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
switch ($event->getParticipations()->count()) {
|
switch ($event->getParticipations()->count()) {
|
||||||
|
|
||||||
case 0:
|
case 0:
|
||||||
// if there aren't any participation, redirect to the 'show' view with an add flash
|
// if there aren't any participation, redirect to the 'show' view with an add flash
|
||||||
$this->addFlash('warning', $this->get('translator')
|
$this->addFlash('warning', $this->get('translator')
|
||||||
->trans( "There are no participation to edit for this event"));
|
->trans( "There are no participation to edit for this event"));
|
||||||
|
|
||||||
return $this->redirectToRoute('chill_event__event_show',
|
return $this->redirectToRoute('chill_event__event_show',
|
||||||
array('event_id' => $event->getId()));
|
array('event_id' => $event->getId()));
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
// redirect to the form for a single participation
|
// redirect to the form for a single participation
|
||||||
return $this->redirectToRoute('chill_event_participation_edit', array(
|
return $this->redirectToRoute('chill_event_participation_edit', array(
|
||||||
'participation_id' => $event->getParticipations()->current()->getId()
|
'participation_id' => $event->getParticipations()->current()->getId()
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
$form = $this->createEditFormMultiple($event->getParticipations(), $event);
|
$form = $this->createEditFormMultiple($event->getParticipations(), $event);
|
||||||
|
|
||||||
return $this->render('ChillEventBundle:Participation:edit-multiple.html.twig', array(
|
return $this->render('ChillEventBundle:Participation:edit-multiple.html.twig', array(
|
||||||
'event' => $event,
|
'event' => $event,
|
||||||
'participations' => $event->getParticipations(),
|
'participations' => $event->getParticipations(),
|
||||||
'form' => $form->createView()
|
'form' => $form->createView()
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function updateMultipleAction($event_id, Request $request)
|
public function updateMultipleAction($event_id, Request $request)
|
||||||
{
|
{
|
||||||
/* @var $event \Chill\EventBundle\Entity\Event */
|
/* @var $event \Chill\EventBundle\Entity\Event */
|
||||||
$event = $this->getDoctrine()->getRepository('ChillEventBundle:Event')
|
$event = $this->getDoctrine()->getRepository('ChillEventBundle:Event')
|
||||||
->find($event_id);
|
->find($event_id);
|
||||||
|
|
||||||
if ($event === null) {
|
if ($event === null) {
|
||||||
throw $this->createNotFoundException("The event with id $event_id is not found");
|
throw $this->createNotFoundException("The event with id $event_id is not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->denyAccessUnlessGranted('CHILL_EVENT_SEE', $event, "You are not allowed "
|
$this->denyAccessUnlessGranted('CHILL_EVENT_SEE', $event, "You are not allowed "
|
||||||
. "to see this event");
|
. "to see this event");
|
||||||
foreach ($event->getParticipations() as $participation) {
|
foreach ($event->getParticipations() as $participation) {
|
||||||
$this->denyAccessUnlessGranted(ParticipationVoter::UPDATE, $participation,
|
$this->denyAccessUnlessGranted(ParticipationVoter::UPDATE, $participation,
|
||||||
"You are not allowed to update participation with id ".$participation->getId());
|
"You are not allowed to update participation with id ".$participation->getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
$form = $this->createEditFormMultiple($event->getParticipations(), $event);
|
$form = $this->createEditFormMultiple($event->getParticipations(), $event);
|
||||||
|
|
||||||
$form->handleRequest($request);
|
$form->handleRequest($request);
|
||||||
|
|
||||||
if ($form->isSubmitted() && $form->isValid()) {
|
if ($form->isSubmitted() && $form->isValid()) {
|
||||||
$this->getDoctrine()->getManager()->flush();
|
$this->getDoctrine()->getManager()->flush();
|
||||||
|
|
||||||
$this->addFlash('success', $this->get('translator')->trans("The participations "
|
$this->addFlash('success', $this->get('translator')->trans("The participations "
|
||||||
. "have been successfully updated."));
|
. "have been successfully updated."));
|
||||||
|
|
||||||
return $this->redirectToRoute('chill_event__event_show',
|
return $this->redirectToRoute('chill_event__event_show',
|
||||||
array('event_id' => $event->getId()));
|
array('event_id' => $event->getId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->render('ChillEventBundle:Participation:edit-multiple.html.twig', array(
|
return $this->render('ChillEventBundle:Participation:edit-multiple.html.twig', array(
|
||||||
'event' => $event,
|
'event' => $event,
|
||||||
'participations' => $event->getParticipations(),
|
'participations' => $event->getParticipations(),
|
||||||
'form' => $form->createView()
|
'form' => $form->createView()
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param ArrayIterator $participations
|
* @param ArrayIterator $participations
|
||||||
* @param Event $event
|
* @param Event $event
|
||||||
@@ -679,14 +684,14 @@ class ParticipationController extends AbstractController
|
|||||||
*/
|
*/
|
||||||
protected function createEditFormMultiple(ArrayIterator $participations, Event $event)
|
protected function createEditFormMultiple(ArrayIterator $participations, Event $event)
|
||||||
{
|
{
|
||||||
$form = $this->createForm(\Symfony\Component\Form\Extension\Core\Type\FormType::class,
|
$form = $this->createForm(\Symfony\Component\Form\Extension\Core\Type\FormType::class,
|
||||||
array('participations' => $participations), array(
|
array('participations' => $participations), array(
|
||||||
'method' => 'POST',
|
'method' => 'POST',
|
||||||
'action' => $this->generateUrl('chill_event_participation_update_multiple', array(
|
'action' => $this->generateUrl('chill_event_participation_update_multiple', array(
|
||||||
'event_id' => $event->getId()
|
'event_id' => $event->getId()
|
||||||
))
|
))
|
||||||
));
|
));
|
||||||
|
|
||||||
$form->add('participations', CollectionType::class, array(
|
$form->add('participations', CollectionType::class, array(
|
||||||
'entry_type' => ParticipationType::class,
|
'entry_type' => ParticipationType::class,
|
||||||
'entry_options' => array(
|
'entry_options' => array(
|
||||||
@@ -694,14 +699,14 @@ class ParticipationController extends AbstractController
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
$form->add('submit', SubmitType::class, array(
|
$form->add('submit', SubmitType::class, array(
|
||||||
'label' => 'Update'
|
'label' => 'Update'
|
||||||
));
|
));
|
||||||
|
|
||||||
return $form;
|
return $form;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param integer $participation_id
|
* @param integer $participation_id
|
||||||
* @param Request $request
|
* @param Request $request
|
||||||
@@ -713,28 +718,28 @@ class ParticipationController extends AbstractController
|
|||||||
$participation = $em->getRepository('ChillEventBundle:Participation')->findOneBy([
|
$participation = $em->getRepository('ChillEventBundle:Participation')->findOneBy([
|
||||||
'id' => $participation_id
|
'id' => $participation_id
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if (! $participation) {
|
if (! $participation) {
|
||||||
throw $this->createNotFoundException('Unable to find participation.');
|
throw $this->createNotFoundException('Unable to find participation.');
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @var Event $event */
|
/** @var Event $event */
|
||||||
$event = $participation->getEvent();
|
$event = $participation->getEvent();
|
||||||
|
|
||||||
$form = $this->createDeleteForm($participation_id);
|
$form = $this->createDeleteForm($participation_id);
|
||||||
|
|
||||||
if ($request->getMethod() === Request::METHOD_DELETE) {
|
if ($request->getMethod() === Request::METHOD_DELETE) {
|
||||||
$form->handleRequest($request);
|
$form->handleRequest($request);
|
||||||
|
|
||||||
if ($form->isValid()) {
|
if ($form->isValid()) {
|
||||||
|
|
||||||
$em->remove($participation);
|
$em->remove($participation);
|
||||||
$em->flush();
|
$em->flush();
|
||||||
|
|
||||||
$this->addFlash('success', $this->get('translator')
|
$this->addFlash('success', $this->get('translator')
|
||||||
->trans("The participation has been sucessfully removed")
|
->trans("The participation has been sucessfully removed")
|
||||||
);
|
);
|
||||||
|
|
||||||
return $this->redirectToRoute('chill_event__event_show', [
|
return $this->redirectToRoute('chill_event__event_show', [
|
||||||
'event_id' => $event->getId()
|
'event_id' => $event->getId()
|
||||||
]);
|
]);
|
||||||
@@ -744,9 +749,9 @@ class ParticipationController extends AbstractController
|
|||||||
'event_id' => $event->getId(),
|
'event_id' => $event->getId(),
|
||||||
'delete_form' => $form->createView()
|
'delete_form' => $form->createView()
|
||||||
]);
|
]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $participation_id
|
* @param $participation_id
|
||||||
* @return \Symfony\Component\Form\FormInterface
|
* @return \Symfony\Component\Form\FormInterface
|
||||||
@@ -762,5 +767,5 @@ class ParticipationController extends AbstractController
|
|||||||
->getForm()
|
->getForm()
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -50,19 +50,19 @@ class LoadRolesACL extends AbstractFixture implements OrderedFixtureInterface
|
|||||||
break;
|
break;
|
||||||
case 'administrative':
|
case 'administrative':
|
||||||
case 'direction':
|
case 'direction':
|
||||||
if (in_array($scope->getName()['en'], array('administrative', 'social'))) {
|
if (in_array($scope->getName()['en'], array('administrative', 'social'), true)) {
|
||||||
break 2; // we do not want any power on social or administrative
|
break 2; // we do not want any power on social or administrative
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Adding CHILL_EVENT_UPDATE & CHILL_EVENT_CREATE "
|
printf("Adding CHILL_EVENT_UPDATE & CHILL_EVENT_CREATE "
|
||||||
. "& CHILL_EVENT_PARTICIPATION_UPDATE & CHILL_EVENT_PARTICIPATION_CREATE "
|
. "& CHILL_EVENT_PARTICIPATION_UPDATE & CHILL_EVENT_PARTICIPATION_CREATE "
|
||||||
. "& CHILL_EVENT_SEE & CHILL_EVENT_SEE_DETAILS "
|
. "& CHILL_EVENT_SEE & CHILL_EVENT_SEE_DETAILS "
|
||||||
. "to %s "
|
. "to %s "
|
||||||
. "permission group, scope '%s' \n",
|
. "permission group, scope '%s' \n",
|
||||||
$permissionsGroup->getName(), $scope->getName()['en']);
|
$permissionsGroup->getName(), $scope->getName()['en']);
|
||||||
|
|
||||||
$roleScopeUpdate = (new RoleScope())
|
$roleScopeUpdate = (new RoleScope())
|
||||||
->setRole('CHILL_EVENT_UPDATE')
|
->setRole('CHILL_EVENT_UPDATE')
|
||||||
->setScope($scope);
|
->setScope($scope);
|
||||||
@@ -71,7 +71,7 @@ class LoadRolesACL extends AbstractFixture implements OrderedFixtureInterface
|
|||||||
->setScope($scope);
|
->setScope($scope);
|
||||||
$permissionsGroup->addRoleScope($roleScopeUpdate);
|
$permissionsGroup->addRoleScope($roleScopeUpdate);
|
||||||
$permissionsGroup->addRoleScope($roleScopeUpdate2);
|
$permissionsGroup->addRoleScope($roleScopeUpdate2);
|
||||||
|
|
||||||
$roleScopeCreate = (new RoleScope())
|
$roleScopeCreate = (new RoleScope())
|
||||||
->setRole('CHILL_EVENT_CREATE')
|
->setRole('CHILL_EVENT_CREATE')
|
||||||
->setScope($scope);
|
->setScope($scope);
|
||||||
@@ -80,7 +80,7 @@ class LoadRolesACL extends AbstractFixture implements OrderedFixtureInterface
|
|||||||
->setScope($scope);
|
->setScope($scope);
|
||||||
$permissionsGroup->addRoleScope($roleScopeCreate);
|
$permissionsGroup->addRoleScope($roleScopeCreate);
|
||||||
$permissionsGroup->addRoleScope($roleScopeCreate2);
|
$permissionsGroup->addRoleScope($roleScopeCreate2);
|
||||||
|
|
||||||
$roleScopeSee = (new RoleScope())
|
$roleScopeSee = (new RoleScope())
|
||||||
->setRole('CHILL_EVENT_SEE')
|
->setRole('CHILL_EVENT_SEE')
|
||||||
->setScope($scope);
|
->setScope($scope);
|
||||||
@@ -89,7 +89,7 @@ class LoadRolesACL extends AbstractFixture implements OrderedFixtureInterface
|
|||||||
->setScope($scope);
|
->setScope($scope);
|
||||||
$permissionsGroup->addRoleScope($roleScopeSee);
|
$permissionsGroup->addRoleScope($roleScopeSee);
|
||||||
$permissionsGroup->addRoleScope($roleScopeSee2);
|
$permissionsGroup->addRoleScope($roleScopeSee2);
|
||||||
|
|
||||||
$manager->persist($roleScopeUpdate);
|
$manager->persist($roleScopeUpdate);
|
||||||
$manager->persist($roleScopeUpdate2);
|
$manager->persist($roleScopeUpdate2);
|
||||||
$manager->persist($roleScopeCreate);
|
$manager->persist($roleScopeCreate);
|
||||||
@@ -97,9 +97,9 @@ class LoadRolesACL extends AbstractFixture implements OrderedFixtureInterface
|
|||||||
$manager->persist($roleScopeSee);
|
$manager->persist($roleScopeSee);
|
||||||
$manager->persist($roleScopeSee2);
|
$manager->persist($roleScopeSee2);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$manager->flush();
|
$manager->flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -46,7 +46,7 @@ class EventType
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array
|
* @var array
|
||||||
* @ORM\Column(type="json_array")
|
* @ORM\Column(type="json")
|
||||||
*/
|
*/
|
||||||
private $name;
|
private $name;
|
||||||
|
|
||||||
@@ -55,7 +55,7 @@ class EventType
|
|||||||
* @ORM\Column(type="boolean")
|
* @ORM\Column(type="boolean")
|
||||||
*/
|
*/
|
||||||
private $active;
|
private $active;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var Collection
|
* @var Collection
|
||||||
* @ORM\OneToMany(
|
* @ORM\OneToMany(
|
||||||
|
@@ -44,7 +44,7 @@ class Role
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array
|
* @var array
|
||||||
* @ORM\Column(type="json_array")
|
* @ORM\Column(type="json")
|
||||||
*/
|
*/
|
||||||
private $name;
|
private $name;
|
||||||
|
|
||||||
@@ -53,7 +53,7 @@ class Role
|
|||||||
* @ORM\Column(type="boolean")
|
* @ORM\Column(type="boolean")
|
||||||
*/
|
*/
|
||||||
private $active;
|
private $active;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var EventType
|
* @var EventType
|
||||||
* @ORM\ManyToOne(
|
* @ORM\ManyToOne(
|
||||||
|
@@ -41,19 +41,19 @@ class Status
|
|||||||
* @ORM\GeneratedValue(strategy="AUTO")
|
* @ORM\GeneratedValue(strategy="AUTO")
|
||||||
*/
|
*/
|
||||||
private $id;
|
private $id;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array
|
* @var array
|
||||||
* @ORM\Column(type="json_array")
|
* @ORM\Column(type="json")
|
||||||
*/
|
*/
|
||||||
private $name;
|
private $name;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var boolean
|
* @var boolean
|
||||||
* @ORM\Column(type="boolean")
|
* @ORM\Column(type="boolean")
|
||||||
*/
|
*/
|
||||||
private $active;
|
private $active;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var EventType
|
* @var EventType
|
||||||
* @ORM\ManyToOne(
|
* @ORM\ManyToOne(
|
||||||
|
@@ -504,6 +504,8 @@ class ApiController extends AbstractCRUDController
|
|||||||
$this->getContextForSerializationPostAlter($action, $request, $_format, $entity, [$postedData])
|
$this->getContextForSerializationPostAlter($action, $request, $_format, $entity, [$postedData])
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
throw new \Exception('Unable to handle such request method.');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -342,13 +342,19 @@ class CRUDController extends AbstractController
|
|||||||
*/
|
*/
|
||||||
protected function buildQueryEntities(string $action, Request $request)
|
protected function buildQueryEntities(string $action, Request $request)
|
||||||
{
|
{
|
||||||
return $this->getDoctrine()->getManager()
|
$query = $this->getDoctrine()->getManager()
|
||||||
->createQueryBuilder()
|
->createQueryBuilder()
|
||||||
->select('e')
|
->select('e')
|
||||||
->from($this->getEntityClass(), 'e')
|
->from($this->getEntityClass(), 'e')
|
||||||
;
|
;
|
||||||
|
|
||||||
|
$this->customizeQuery($action, $request, $query);
|
||||||
|
|
||||||
|
return $query;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function customizeQuery(string $action, Request $request, $query): void {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Query the entity.
|
* Query the entity.
|
||||||
*
|
*
|
||||||
|
@@ -8,6 +8,7 @@ use Chill\MainBundle\Security\Authorization\ChillVoterInterface;
|
|||||||
use Chill\MainBundle\Security\ProvideRoleInterface;
|
use Chill\MainBundle\Security\ProvideRoleInterface;
|
||||||
use Chill\MainBundle\Security\Resolver\CenterResolverInterface;
|
use Chill\MainBundle\Security\Resolver\CenterResolverInterface;
|
||||||
use Chill\MainBundle\Security\Resolver\ScopeResolverInterface;
|
use Chill\MainBundle\Security\Resolver\ScopeResolverInterface;
|
||||||
|
use Chill\MainBundle\Templating\Entity\ChillEntityRenderInterface;
|
||||||
use Symfony\Component\HttpKernel\Bundle\Bundle;
|
use Symfony\Component\HttpKernel\Bundle\Bundle;
|
||||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||||
use Chill\MainBundle\DependencyInjection\CompilerPass\SearchableServicesCompilerPass;
|
use Chill\MainBundle\DependencyInjection\CompilerPass\SearchableServicesCompilerPass;
|
||||||
@@ -38,6 +39,8 @@ class ChillMainBundle extends Bundle
|
|||||||
->addTag('chill_main.center_resolver');
|
->addTag('chill_main.center_resolver');
|
||||||
$container->registerForAutoconfiguration(ScopeResolverInterface::class)
|
$container->registerForAutoconfiguration(ScopeResolverInterface::class)
|
||||||
->addTag('chill_main.scope_resolver');
|
->addTag('chill_main.scope_resolver');
|
||||||
|
$container->registerForAutoconfiguration(ChillEntityRenderInterface::class)
|
||||||
|
->addTag('chill.render_entity');
|
||||||
|
|
||||||
$container->addCompilerPass(new SearchableServicesCompilerPass());
|
$container->addCompilerPass(new SearchableServicesCompilerPass());
|
||||||
$container->addCompilerPass(new ConfigConsistencyCompilerPass());
|
$container->addCompilerPass(new ConfigConsistencyCompilerPass());
|
||||||
|
@@ -10,18 +10,18 @@ use Symfony\Component\Console\Output\OutputInterface;
|
|||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Julien Fastré <julien.fastre@champs-libres.coop
|
* @author Julien Fastré <julien.fastre@champs-libres.coop
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class LoadCountriesCommand extends Command
|
class LoadCountriesCommand extends Command
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var EntityManager
|
* @var EntityManager
|
||||||
*/
|
*/
|
||||||
private $entityManager;
|
private $entityManager;
|
||||||
|
|
||||||
private $availableLanguages;
|
private $availableLanguages;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* LoadCountriesCommand constructor.
|
* LoadCountriesCommand constructor.
|
||||||
*
|
*
|
||||||
@@ -34,7 +34,7 @@ class LoadCountriesCommand extends Command
|
|||||||
$this->availableLanguages=$availableLanguages;
|
$this->availableLanguages=$availableLanguages;
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-PHPdoc)
|
* (non-PHPdoc)
|
||||||
* @see \Symfony\Component\Console\Command\Command::configure()
|
* @see \Symfony\Component\Console\Command\Command::configure()
|
||||||
@@ -45,7 +45,7 @@ class LoadCountriesCommand extends Command
|
|||||||
->setDescription('Load or update countries in db. This command does not delete existing countries, '.
|
->setDescription('Load or update countries in db. This command does not delete existing countries, '.
|
||||||
'but will update names according to available languages');
|
'but will update names according to available languages');
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-PHPdoc)
|
* (non-PHPdoc)
|
||||||
* @see \Symfony\Component\Console\Command\Command::execute()
|
* @see \Symfony\Component\Console\Command\Command::execute()
|
||||||
@@ -54,43 +54,44 @@ class LoadCountriesCommand extends Command
|
|||||||
{
|
{
|
||||||
$countries = static::prepareCountryList($this->availableLanguages);
|
$countries = static::prepareCountryList($this->availableLanguages);
|
||||||
$em = $this->entityManager;
|
$em = $this->entityManager;
|
||||||
|
|
||||||
foreach($countries as $country) {
|
foreach($countries as $country) {
|
||||||
$countryStored = $em->getRepository('ChillMainBundle:Country')
|
$countryStored = $em->getRepository('ChillMainBundle:Country')
|
||||||
->findOneBy(array('countryCode' => $country->getCountryCode()));
|
->findOneBy(array('countryCode' => $country->getCountryCode()));
|
||||||
|
|
||||||
if (NULL === $countryStored) {
|
if (NULL === $countryStored) {
|
||||||
$em->persist($country);
|
$em->persist($country);
|
||||||
} else {
|
} else {
|
||||||
$countryStored->setName($country->getName());
|
$countryStored->setName($country->getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$em->flush();
|
$em->flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function prepareCountryList($languages)
|
public static function prepareCountryList($languages)
|
||||||
{
|
{
|
||||||
$regionBundle = Intl::getRegionBundle();
|
$regionBundle = Intl::getRegionBundle();
|
||||||
|
$countries = [];
|
||||||
|
|
||||||
foreach ($languages as $language) {
|
foreach ($languages as $language) {
|
||||||
$countries[$language] = $regionBundle->getCountryNames($language);
|
$countries[$language] = $regionBundle->getCountryNames($language);
|
||||||
}
|
}
|
||||||
|
|
||||||
$countryEntities = array();
|
$countryEntities = array();
|
||||||
|
|
||||||
foreach ($countries[$languages[0]] as $countryCode => $name) {
|
foreach ($countries[$languages[0]] as $countryCode => $name) {
|
||||||
$names = array();
|
$names = array();
|
||||||
|
|
||||||
foreach ($languages as $language) {
|
foreach ($languages as $language) {
|
||||||
$names[$language] = $countries[$language][$countryCode];
|
$names[$language] = $countries[$language][$countryCode];
|
||||||
}
|
}
|
||||||
|
|
||||||
$country = new \Chill\MainBundle\Entity\Country();
|
$country = new \Chill\MainBundle\Entity\Country();
|
||||||
$country->setName($names)->setCountryCode($countryCode);
|
$country->setName($names)->setCountryCode($countryCode);
|
||||||
$countryEntities[] = $country;
|
$countryEntities[] = $country;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $countryEntities;
|
return $countryEntities;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -3,6 +3,7 @@
|
|||||||
namespace Chill\MainBundle\Controller;
|
namespace Chill\MainBundle\Controller;
|
||||||
|
|
||||||
use Chill\MainBundle\CRUD\Controller\ApiController;
|
use Chill\MainBundle\CRUD\Controller\ApiController;
|
||||||
|
use Chill\MainBundle\Pagination\PaginatorInterface;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -20,8 +21,17 @@ class AddressReferenceAPIController extends ApiController
|
|||||||
|
|
||||||
$qb->where('e.postcode = :postal_code')
|
$qb->where('e.postcode = :postal_code')
|
||||||
->setParameter('postal_code', $request->query->get('postal_code'));
|
->setParameter('postal_code', $request->query->get('postal_code'));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function orderQuery(string $action, $query, Request $request, PaginatorInterface $paginator, $_format)
|
||||||
|
{
|
||||||
|
$query->addOrderBy('e.street', 'ASC');
|
||||||
|
$query->addOrderBy('e.streetNumber', 'ASC');
|
||||||
|
|
||||||
|
return $query;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -41,4 +41,9 @@ class AdminController extends AbstractController
|
|||||||
return $this->render('@ChillMain/Admin/layout_permissions.html.twig');
|
return $this->render('@ChillMain/Admin/layout_permissions.html.twig');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function indexLocationsAction()
|
||||||
|
{
|
||||||
|
return $this->render('@ChillMain/Admin/layout_location.html.twig');
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,36 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Chill\MainBundle\Controller;
|
||||||
|
|
||||||
|
use Chill\MainBundle\CRUD\Controller\ApiController;
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class LocationApiController
|
||||||
|
*
|
||||||
|
* @package Chill\MainBundle\Controller
|
||||||
|
* @author Champs Libres
|
||||||
|
*/
|
||||||
|
class LocationApiController extends ApiController
|
||||||
|
{
|
||||||
|
public function customizeQuery(string $action, Request $request, $query): void
|
||||||
|
{
|
||||||
|
$query->andWhere($query->expr()->orX(
|
||||||
|
$query->expr()->andX(
|
||||||
|
$query->expr()->eq('e.createdBy', ':user'),
|
||||||
|
$query->expr()->gte('e.createdAt', ':dateBefore')
|
||||||
|
),
|
||||||
|
$query->expr()->andX(
|
||||||
|
$query->expr()->eq('e.availableForUsers', "'TRUE'"),
|
||||||
|
$query->expr()->eq('e.active', "'TRUE'"),
|
||||||
|
$query->expr()->isNotNull('e.name'),
|
||||||
|
$query->expr()->neq('e.name', ':emptyString'),
|
||||||
|
)
|
||||||
|
))
|
||||||
|
->setParameters([
|
||||||
|
'user' => $this->getUser(),
|
||||||
|
'dateBefore' => (new \DateTime())->sub(new \DateInterval('P6M')),
|
||||||
|
'emptyString' => '',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
23
src/Bundle/ChillMainBundle/Controller/LocationController.php
Normal file
23
src/Bundle/ChillMainBundle/Controller/LocationController.php
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Chill\MainBundle\Controller;
|
||||||
|
|
||||||
|
use Chill\MainBundle\CRUD\Controller\CRUDController;
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
|
||||||
|
class LocationController extends CRUDController
|
||||||
|
{
|
||||||
|
protected function customizeQuery(string $action, Request $request, $query): void
|
||||||
|
{
|
||||||
|
$query->where('e.availableForUsers = true'); //TODO not working
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function createEntity(string $action, Request $request): object
|
||||||
|
{
|
||||||
|
$entity = parent::createEntity($action, $request);
|
||||||
|
|
||||||
|
$entity->setAvailableForUsers(true);
|
||||||
|
|
||||||
|
return $entity;
|
||||||
|
}
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user