ExtraFields: Add user tag extra field + add select2 js lib

pull/4032/head
Julio 3 years ago
parent f8927bbf8d
commit 9b5f203502
  1. 2
      assets/js/vendor.js
  2. 3
      assets/vue/views/user/sessions/List.vue
  3. 6
      public/main/inc/ajax/extra_field.ajax.php
  4. 53
      src/CoreBundle/Form/ExtraFieldType.php
  5. 37
      src/CoreBundle/Repository/TagRepository.php
  6. 24
      src/CoreBundle/Resources/views/Account/edit.html.twig
  7. 28
      tests/CoreBundle/Repository/TagRepositoryTest.php

@ -4,7 +4,7 @@
require('image-map-resizer/js/imageMapResizer.js');
require('cropper');
// require('jquery-ui-timepicker-addon/dist/jquery-ui-timepicker-addon');
//import('select2');
import('select2');
require('timeago');
//require('sweetalert2');
//import('bootstrap-select');

@ -19,7 +19,6 @@ import {computed, ref} from "vue";
import {useStore} from 'vuex';
import {useQuery, useResult} from '@vue/apollo-composable'
import {GET_SESSION_REL_USER_CURRENT} from "../../../graphql/queries/SessionRelUser.js";
import {DateTime} from "luxon";
import SessionTabs from '../../../components/session/Tabs';
import SessionListWrapper from '../../../components/session/SessionListWrapper';
import SessionListCategoryWrapper from '../../../components/session/SessionListCategoryWrapper';
@ -41,8 +40,6 @@ export default {
if (user.value) {
let userId = user.value.id;
let start = DateTime.local().toISO();
let end = DateTime.local().toISO();
const {result: resultSessions, loading: loadingSessions} = useQuery(GET_SESSION_REL_USER_CURRENT, {
user: "/api/users/" + userId,

@ -39,13 +39,15 @@ switch ($action) {
header('Content-Type: application/json');
$tag = isset($_REQUEST['q']) ? (string) $_REQUEST['q'] : '';
if (empty($tag)) {
$extraFieldRepo = Container::getExtraFieldRepository();
$field = $extraFieldRepo->find($fieldId);
if (empty($tag || null === $field)) {
echo json_encode(['items' => []]);
exit;
}
$tagRepo = Container::getTagRepository();
$field = $tagRepo->find($fieldId);
$tags = $tagRepo->findTagsByField($tag, $field);
$result = [];
foreach ($tags as $tag) {

@ -7,10 +7,10 @@ declare(strict_types=1);
namespace Chamilo\CoreBundle\Form;
use Chamilo\CoreBundle\Entity\ExtraField;
use Chamilo\CoreBundle\Entity\ExtraFieldItemInterface;
use Chamilo\CoreBundle\Entity\User;
use Chamilo\CoreBundle\Repository\ExtraFieldRepository;
use Chamilo\CoreBundle\Repository\ExtraFieldValuesRepository;
use Chamilo\CoreBundle\Repository\TagRepository;
use DateTime;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
@ -32,29 +32,32 @@ class ExtraFieldType extends AbstractType
private ExtraFieldValuesRepository $extraFieldValuesRepository;
private Security $security;
private ExtraFieldRepository $extraFieldRepository;
private TagRepository $tagRepository;
public function __construct(
ExtraFieldValuesRepository $extraFieldValuesRepository,
ExtraFieldRepository $extraFieldRepository,
TagRepository $tagRepository,
Security $security
) {
$this->extraFieldValuesRepository = $extraFieldValuesRepository;
$this->extraFieldRepository = $extraFieldRepository;
$this->security = $security;
$this->tagRepository = $tagRepository;
}
public function buildForm(FormBuilderInterface $builder, array $options): void
{
// @todo implement Course/Session extra fields
/** @var User|null|ExtraFieldItemInterface $item */
/** @var User|null $item */
$item = $this->security->getUser();
if (null === $item) {
return;
}
$extraFields = $this->extraFieldRepository->getExtraFields(ExtraField::USER_FIELD_TYPE);
$values = $this->extraFieldValuesRepository->getExtraFieldValuesFromItem($item, ExtraField::USER_FIELD_TYPE);
$extraFieldType = ExtraField::USER_FIELD_TYPE; // user/course/session ?
$extraFields = $this->extraFieldRepository->getExtraFields($extraFieldType);
$values = $this->extraFieldValuesRepository->getExtraFieldValuesFromItem($item, $extraFieldType);
$data = [];
foreach ($values as $value) {
@ -78,7 +81,6 @@ class ExtraFieldType extends AbstractType
switch ($extraField->getFieldType()) {
case \ExtraField::FIELD_TYPE_DOUBLE_SELECT:
case \ExtraField::FIELD_TYPE_DIVIDER:
case \ExtraField::FIELD_TYPE_TAG:
case \ExtraField::FIELD_TYPE_TIMEZONE:
case \ExtraField::FIELD_TYPE_FILE_IMAGE:
case \ExtraField::FIELD_TYPE_FILE:
@ -89,6 +91,36 @@ class ExtraFieldType extends AbstractType
case \ExtraField::FIELD_TYPE_SELECT_WITH_TEXT_FIELD:
case \ExtraField::FIELD_TYPE_TRIPLE_SELECT:
//@todo
break;
case \ExtraField::FIELD_TYPE_TAG:
$defaultOptions['expanded'] = false;
$defaultOptions['multiple'] = true;
// The class will be loaded in the template: src/CoreBundle/Resources/views/Account/edit.html.twig
// @todo implement generic form.
$class = 'select2_extra_rel_tag';
if (ExtraField::USER_FIELD_TYPE === $extraFieldType) {
$class = 'select2_user_rel_tag';
$tags = $this->tagRepository->getTagsByUser($extraField, $item);
$choices = [];
foreach ($tags as $tag) {
$stringTag = $tag->getTag();
if (empty($stringTag)) {
continue;
}
$choices[$stringTag] = $stringTag;
}
$defaultOptions['choices'] = $choices;
$defaultOptions['data'] = $choices;
}
$defaultOptions['attr'] = [
'class' => $class,
'style' => 'width:500px',
'data.field_id' => $extraField->getId(),
];
$builder->add($variable, ChoiceType::class, $defaultOptions);
break;
case \ExtraField::FIELD_TYPE_VIDEO_URL:
case \ExtraField::FIELD_TYPE_SOCIAL_PROFILE:
@ -191,6 +223,15 @@ class ExtraFieldType extends AbstractType
$data = $event->getData();
foreach ($extraFields as $extraField) {
$newValue = $data[$extraField->getVariable()] ?? null;
if (\ExtraField::FIELD_TYPE_TAG === $extraField->getFieldType()) {
foreach ($newValue as $tag) {
$this->tagRepository->addTagToUser($extraField, $item, $tag);
}
continue;
}
if (empty($newValue)) {
continue;
}

@ -9,6 +9,7 @@ namespace Chamilo\CoreBundle\Repository;
use Chamilo\CoreBundle\Entity\ExtraField;
use Chamilo\CoreBundle\Entity\Tag;
use Chamilo\CoreBundle\Entity\User;
use Chamilo\CoreBundle\Entity\UserRelTag;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Common\Collections\Collection;
use Doctrine\Persistence\ManagerRegistry;
@ -68,4 +69,40 @@ class TagRepository extends ServiceEntityRepository
return $qb->getQuery()->getResult();
}
public function addTagToUser(ExtraField $extraField, User $user, string $tag): User
{
$entityTag = $this->findOneBy(['tag' => $tag, 'field' => $extraField]);
$em = $this->getEntityManager();
if (null === $entityTag) {
$entityTag = (new Tag())
->setField($extraField)
->setTag($tag)
;
$em->persist($entityTag);
}
$userRelTag = (new UserRelTag())
->setUser($user)
->setTag($entityTag)
;
$exists = $user->getUserRelTags()->exists(
/** @var UserRelTag $element */
function ($key, $element) use ($userRelTag) {
return $userRelTag->getTag() === $element->getTag();
}
);
if (!$exists) {
$entityTag->setCount($entityTag->getCount() + 1);
$em->persist($entityTag);
$user->getUserRelTags()->add($userRelTag);
}
$em->persist($user);
$em->flush();
return $user;
}
}

@ -1,7 +1,29 @@
{% extends "@ChamiloCore/Layout/layout_one_col.html.twig" %}
{% block content %}
{% autoescape false %}
{% autoescape false %}<script>
document.addEventListener("DOMContentLoaded", function() {
$('.select2_user_rel_tag').each(function(i, obj) {
let fieldId = '&field_id=' + $(this).attr('data.field_id');
$(this).select2({
ajax: {
url: '{{ url('legacy_main', { 'name' : 'inc/ajax/extra_field.ajax.php', 'a': 'search_tags', 'type': 'user'}) }}' + fieldId,
processResults: function (data) {
return {
results: data.items
}
}
},
cache: false,
tags: true,
tokenSeparators: [','],
});
});
$('.select2_user_rel_tag').refresh
});
</script>
<h3>{{ user.userIdentifier }}</h3>
{# <a href="{{ url('app_forgot_password_request') }}" class="btn btn-primary">#}
{# Reset password#}

@ -9,6 +9,7 @@ namespace Chamilo\Tests\CoreBundle\Repository;
use Chamilo\CoreBundle\Entity\ExtraField;
use Chamilo\CoreBundle\Entity\ExtraFieldRelTag;
use Chamilo\CoreBundle\Entity\Tag;
use Chamilo\CoreBundle\Entity\User;
use Chamilo\CoreBundle\Entity\UserRelTag;
use Chamilo\CoreBundle\Repository\ExtraFieldRelTagRepository;
use Chamilo\CoreBundle\Repository\TagRepository;
@ -135,4 +136,31 @@ class TagRepositoryTest extends AbstractApiTest
$this->assertCount(1, $tags);
$this->assertInstanceOf(Tag::class, $tags[0]);
}
public function testAddTagToUser(): void
{
$em = $this->getEntityManager();
$repo = self::getContainer()->get(TagRepository::class);
$extraField = (new ExtraField())
->setDisplayText('test')
->setVariable('test')
->setExtraFieldType(ExtraField::USER_FIELD_TYPE)
->setFieldType(\ExtraField::FIELD_TYPE_TAG)
;
$em->persist($extraField);
$em->flush();
$user = $this->createUser('test');
$user = $repo->addTagToUser($extraField, $user, 'php');
$this->assertInstanceOf(User::class, $user);
$this->assertSame(1, $user->getUserRelTags()->count());
$em->flush();
$em->clear();
$user = $this->getUser('test');
$repo->addTagToUser($extraField, $user, 'php');
$this->assertSame(1, $user->getUserRelTags()->count());
}
}

Loading…
Cancel
Save