From 318bf3ce3bf7aff99fde210bde6d211c75b1f2bb Mon Sep 17 00:00:00 2001 From: Julio Montoya Date: Mon, 5 Jul 2021 13:24:20 +0200 Subject: [PATCH] User friends: Fix CRUD, UserRelUserListener.php added --- assets/vue/router/personalfile.js | 10 +- assets/vue/store/modules/crud.js | 22 ++- assets/vue/utils/fetch.js | 2 - assets/vue/views/personalfile/Create.vue | 62 ------ assets/vue/views/userreluser/Add.vue | 72 +------ assets/vue/views/userreluser/List.vue | 176 ++++++++++++------ .../Entity/Listener/UserListener.php | 1 - .../Entity/Listener/UserRelUserListener.php | 53 ++++++ src/CoreBundle/Entity/UserRelUser.php | 5 +- 9 files changed, 197 insertions(+), 206 deletions(-) delete mode 100644 assets/vue/views/personalfile/Create.vue create mode 100644 src/CoreBundle/Entity/Listener/UserRelUserListener.php diff --git a/assets/vue/router/personalfile.js b/assets/vue/router/personalfile.js index 18b7b97f7a..c13a240ba5 100644 --- a/assets/vue/router/personalfile.js +++ b/assets/vue/router/personalfile.js @@ -15,11 +15,11 @@ export default { path: '', component: () => import('../views/personalfile/List.vue') }, - { - name: 'PersonalFileCreate', - path: 'new', - component: () => import('../views/personalfile/Create.vue') - }, + // { + // name: 'PersonalFileCreate', + // path: 'new', + // component: () => import('../views/personalfile/Create.vue') + // }, { name: 'PersonalFileUploadFile', path: 'upload', diff --git a/assets/vue/store/modules/crud.js b/assets/vue/store/modules/crud.js index b1c602aa6a..b6fb3fca58 100644 --- a/assets/vue/store/modules/crud.js +++ b/assets/vue/store/modules/crud.js @@ -139,6 +139,23 @@ export default function makeCrudModule({ commit(ACTIONS.TOGGLE_LOADING); } }, + findAll: ({ commit, state }, params) => { + if (!service) throw new Error('No service specified!'); + + console.log('crud.js findAll'); + //commit(ACTIONS.TOGGLE_LOADING); + + return service + .findAll({params}) + .then(response => response.json()) + .then(retrieved => { + console.log('result of retrieved'); + //commit(ACTIONS.TOGGLE_LOADING); + + return retrieved['hydra:member']; + }) + .catch(e => handleError(commit, e)); + }, fetchAll: ({ commit, state }, params) => { if (!service) throw new Error('No service specified!'); @@ -235,16 +252,13 @@ export default function makeCrudModule({ findResourceNode: ({ commit }, params) => { const id = params['id']; delete params['id']; - console.log('findResourceNode'); - console.log(id); - console.log(params); + console.log('findResourceNode', id); if (!service) throw new Error('No service specified!'); commit(ACTIONS.TOGGLE_LOADING); return service .find(id, params) - //.then(response => service.checkResponse(response)) .then(response => { if (200 === response.status) { return response.json(); diff --git a/assets/vue/utils/fetch.js b/assets/vue/utils/fetch.js index cfd0d4395f..ef92c2c68f 100644 --- a/assets/vue/utils/fetch.js +++ b/assets/vue/utils/fetch.js @@ -43,8 +43,6 @@ export default function(id, options = {}) { const entryPoint = ENTRYPOINT + (ENTRYPOINT.endsWith('/') ? '' : '/'); - console.log('entryPoint', entryPoint); - if ('PUT' === options.method) { const payload = options.body && JSON.parse(options.body); if (isObject(payload) && payload['@id']) { diff --git a/assets/vue/views/personalfile/Create.vue b/assets/vue/views/personalfile/Create.vue deleted file mode 100644 index 813b1bbb83..0000000000 --- a/assets/vue/views/personalfile/Create.vue +++ /dev/null @@ -1,62 +0,0 @@ - - - diff --git a/assets/vue/views/userreluser/Add.vue b/assets/vue/views/userreluser/Add.vue index 1d39db2962..128c524fcd 100644 --- a/assets/vue/views/userreluser/Add.vue +++ b/assets/vue/views/userreluser/Add.vue @@ -4,8 +4,8 @@ + :to="{ name: 'UserRelUserList' }" + > @@ -17,14 +17,12 @@ import { mapActions, mapGetters } from 'vuex'; import { mapFields } from 'vuex-map-fields'; -import ListMixin from '../../mixins/ListMixin'; import Toolbar from '../../components/Toolbar.vue'; import VueMultiselect from 'vue-multiselect' @@ -59,7 +56,6 @@ export default { Toolbar, VueMultiselect }, - mixins: [ListMixin], setup() { const users = ref([]); const isLoadingSelect = ref(false); @@ -104,12 +100,6 @@ export default { }, data() { return { - selected: [], - isBusy: false, - options: { - sortBy: 'sendDate', - sortDesc: 'asc', - }, selectedItems: [], // prime vue itemDialog: false, @@ -119,72 +109,14 @@ export default { submitted: false, }; }, - mounted() { - this.onUpdateOptions(this.options); - }, computed: { - // From crud.js list function - ...mapGetters('resourcenode', { - resourceNode: 'getResourceNode' - }), ...mapGetters({ 'isAuthenticated': 'security/isAuthenticated', 'isAdmin': 'security/isAdmin', 'currentUser': 'security/getUser', }), - - ...mapGetters('message', { - items: 'list', - }), - - //...getters - - // From ListMixin - ...mapFields('message', { - deletedItem: 'deleted', - error: 'error', - isLoading: 'isLoading', - resetList: 'resetList', - totalItems: 'totalItems', - view: 'view' - }), }, methods: { - deleteItemButton() { - console.log('deleteItem'); - this.deleteItem(this.item); - //this.items = this.items.filter(val => val.iid !== this.item.iid); - this.deleteItemDialog = false; - this.item = {}; - this.onUpdateOptions(this.options); - }, - onRowSelected(items) { - this.selected = items - }, - selectAllRows() { - this.$refs.selectableTable.selectAllRows() - }, - clearSelected() { - this.$refs.selectableTable.clearSelected() - }, - async deleteSelected() { - this.deleteMultipleAction(this.selected); - this.onRequest({ - pagination: this.pagination, - }); - }, - //...actions, - // From ListMixin - ...mapActions('userreluser', { - getPage: 'fetchAll', - create: 'create', - update: 'update', - deleteItem: 'del', - deleteMultipleAction: 'delMultiple' - }), - ...mapActions('resourcenode', { - findResourceNode: 'findResourceNode', - }), } }; diff --git a/assets/vue/views/userreluser/List.vue b/assets/vue/views/userreluser/List.vue index d831059eff..fb66e267d0 100644 --- a/assets/vue/views/userreluser/List.vue +++ b/assets/vue/views/userreluser/List.vue @@ -33,21 +33,55 @@ +
+
+ Requests +
+ + + + + + {{ request.user.username }} + + + + + +
+ + + + + + {{ request.friend.username }} + + Waiting + +
Friends
+ + - + {{ slotProps.data.friend.username }} @@ -74,28 +108,15 @@ - @@ -130,7 +151,7 @@
@@ -172,29 +193,89 @@ export default { setup() { const store = useStore(); const user = store.getters["security/getUser"]; - const filters = ref([]); const isLoadingSelect = ref(false); + const deleteItemDialog = ref(false); + const item = ref([]); + const friendRequests = ref([]); + const waitingRequests = ref([]); + //const friendFilter = ref([]); + + const friendRequestFilter = { + friend: user.id, + relationType: 10 + }; + + const waitingFilter = { + user: user.id, + relationType: 10 + }; - filters.value = { - friend: user.id + const friendFilter = { + user: user.id, + relationType: 3, }; + /*store.dispatch('userreluser/findAll', friendRequestFilter).then(response => { + friendRequests.value = response; + }); + store.dispatch('userreluser/findAll', waitingFilter).then(response => { + waitingRequests.value = response; + }); + + // Handles the table + store.dispatch('userreluser/fetchAll', friendFilter);*/ + function addFriend(friend) { - axios.put(friend['@id'], { + // Create new friend connection + axios.post(ENTRYPOINT + 'user_rel_users', { + user: user['@id'], + friend: friend.user['@id'], relationType: 3, }).then(response => { console.log(response); isLoadingSelect.value = false; - store.dispatch('userreluser/resetList'); - store.dispatch('userreluser/fetchAll', filters.value); + // Update other relation from invitation to friend. + axios.put(friend['@id'], { + relationType: 3, + }).then(response => { + console.log(response); + reloadHandler(); + }).catch(function (error) { + console.log(error); + }); }).catch(function (error) { - isLoadingSelect.value = false; console.log(error); }); } + function reloadHandler() { + store.dispatch('userreluser/resetList'); + store.dispatch('userreluser/fetchAll', friendFilter); + store.dispatch('userreluser/findAll', friendRequestFilter).then(response => { + friendRequests.value = response; + }); + store.dispatch('userreluser/findAll', waitingFilter).then(response => { + waitingRequests.value = response; + }); + } + + function deleteItemButton(item) { + store.dispatch('userreluser/del', item); + deleteItemDialog.value = false; + reloadHandler(); + } + + reloadHandler(); + return { addFriend, + reloadHandler, + deleteItemButton, + item, + friendRequests, + waitingRequests, + friendFilter, + deleteItemDialog } }, data() { @@ -206,23 +287,13 @@ export default { ], pageOptions: [10, 20, 50, this.$i18n.t('All')], selected: [], - isBusy: false, selectedItems: [], // prime vue itemDialog: false, - deleteItemDialog: false, deleteMultipleDialog: false, - item: {}, submitted: false, }; }, - mounted() { - console.log('mounted'); - this.filters = { - friend: this.currentUser.id - }; - this.onUpdateOptions(this.options); - }, computed: { // From crud.js list function ...mapGetters('resourcenode', { @@ -257,7 +328,10 @@ export default { this.options.page = event.page + 1; this.options.sortBy = event.sortField; this.options.sortDesc = event.sortOrder === -1; - + this.filters = { + user: this.currentUser.id, + relationType: 3 + }; this.onUpdateOptions(this.options); }, sortingChanged(event) { @@ -270,11 +344,6 @@ export default { // ctx.sortBy ==> Field key for sorting by (or null for no sorting) // ctx.sortDesc ==> true if sorting descending, false otherwise }, - openNew() { - this.item = {}; - this.submitted = false; - this.itemDialog = true; - }, hideDialog() { this.itemDialog = false; this.submitted = false; @@ -314,12 +383,7 @@ export default { confirmDeleteMultiple() { this.deleteMultipleDialog = true; }, - reloadHandler() { - this.onUpdateOptions(this.options); - }, deleteMultipleItems() { - console.log('deleteMultipleItems'); - console.log(this.selectedItems); this.deleteMultipleAction(this.selectedItems); this.onRequest({ pagination: this.pagination, @@ -328,14 +392,6 @@ export default { this.selectedItems = null; //this.onUpdateOptions(this.options); }, - deleteItemButton() { - console.log('deleteItem'); - this.deleteItem(this.item); - //this.items = this.items.filter(val => val.iid !== this.item.iid); - this.deleteItemDialog = false; - this.item = {}; - this.onUpdateOptions(this.options); - }, onRowSelected(items) { this.selected = items }, diff --git a/src/CoreBundle/Entity/Listener/UserListener.php b/src/CoreBundle/Entity/Listener/UserListener.php index dc7e5f276d..85098d2c85 100644 --- a/src/CoreBundle/Entity/Listener/UserListener.php +++ b/src/CoreBundle/Entity/Listener/UserListener.php @@ -30,7 +30,6 @@ class UserListener public function prePersist(User $user, LifecycleEventArgs $args): void { //error_log('User listener prePersist'); - if ($user) { $this->userRepository->updateCanonicalFields($user); $this->userRepository->updatePassword($user); diff --git a/src/CoreBundle/Entity/Listener/UserRelUserListener.php b/src/CoreBundle/Entity/Listener/UserRelUserListener.php new file mode 100644 index 0000000000..8dfaef690e --- /dev/null +++ b/src/CoreBundle/Entity/Listener/UserRelUserListener.php @@ -0,0 +1,53 @@ +security = $security; + } + + public function prePersist(UserRelUser $userRelUser, LifecycleEventArgs $args): void + { + $currentUser = $this->security->getUser(); + // User cannot be connected to himself + if ($userRelUser->getFriend()->getUsername() === $currentUser->getUserIdentifier()) { + throw new \Exception('Invalid relation UserRelUser'); + } + } + + public function postRemove(UserRelUser $userRelUser, LifecycleEventArgs $args) + { + // Deletes the other connection + $em = $args->getEntityManager(); + $repo = $em->getRepository(UserRelUser::class); + $connection = $repo->findOneBy( + [ + 'user' => $userRelUser->getFriend(), + 'friend' => $userRelUser->getUser(), + 'relationType' => $userRelUser->getRelationType(), + ] + ); + + if (null !== $connection) { + $em->remove($connection); + $em->flush(); + } + } +} diff --git a/src/CoreBundle/Entity/UserRelUser.php b/src/CoreBundle/Entity/UserRelUser.php index afa475f1a5..0b6dc84d9d 100644 --- a/src/CoreBundle/Entity/UserRelUser.php +++ b/src/CoreBundle/Entity/UserRelUser.php @@ -33,6 +33,7 @@ use Symfony\Component\Validator\Constraints as Assert; * } * ) * @ORM\Entity + * @ORM\EntityListeners({"Chamilo\CoreBundle\Entity\Listener\UserRelUserListener"}) */ #[ApiResource( collectionOperations: [ @@ -51,7 +52,7 @@ use Symfony\Component\Validator\Constraints as Assert; //'security' => "is_granted('ROLE_ADMIN') or object.user == user", ], 'delete' => [ - //'security' => "is_granted('ROLE_ADMIN') or object.user == user", + //'security' => "object.user == user", ], ], attributes: [ @@ -96,7 +97,7 @@ class UserRelUser * @ORM\Id * @ORM\GeneratedValue */ - protected int $id; + protected ?int $id = null; /** * @ORM\ManyToOne(targetEntity="Chamilo\CoreBundle\Entity\User", inversedBy="friends")