Symfony Symfony2: Как лучше реализовать разнопользовательскую систему?

d1gi

Новичок
Например требуется сделать так: при регистрации юзер может выбрать, кем он является, например

1) Фотограф
2) Видеоргаф

Адреса на страницы юзеров будут как в вк т.е. /id{user_id} и в зависимости от ролей будет разный дизайн страницы.

Прошу у вас рекомендации, как лучше это всё реализовать?

Сейчас кручу FOSUserBundle, там есть группы, но я пока непонял, как их можно назначить при регистрации? как можно сделать выбор групп через radio «по правильному» т.е. модернизировав сущность и форму?

как потом можно будет выбрать список всех юзеров заданной группы?

или в этой ситуации надо юзать не FOSUserBundle? :)
 

d1gi

Новичок
хотелось бы по больше конкретики ;) может быть какой-то конкретный бандл заюзать, может быть там нюансы есть в его заюзывании и т.д. ;)
 

d1gi

Новичок
Сделал следующую штуку:

PHP:
<?php
// ...Acme/Bundle/UserBundle/Entity/User.php
namespace Acme\Bundle\UserBundle\Entity;

use FOS\UserBundle\Entity\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Acme\Bundle\UserBundle\Entity\Group;

/**
 * @ORM\Entity
 * @ORM\Table(name="users")
 */
class User extends BaseUser
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;
    
    /**
     * @ORM\ManyToMany(targetEntity="Acme\Bundle\UserBundle\Entity\Group")
     * @ORM\JoinTable(name="users_groups_relations",
     *      joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="group_id", referencedColumnName="id")}
     * )
     */
    protected $groups;
}
Далее в контроллере выполняю:
PHP:
$this->getUser()->addGroup($this->get('fos_user.group_manager')->findGroupByName('photographers'));

print_r($this->getUser()->getGroups()->toArray());
Получаем, массив с заданной группой:
PHP:
Array
(
   [0] => Acme\Bundle\UserBundle\Entity\Group Object
      (
         [id:protected] => 3
         [name:protected] => photographers
         [roles:protected] => Array
            (
            )
      )
)
Но в таблице users_groups_relations отображения не происходит :( надо как-то явно указывать flush? или как это сделать можно?

Хотя если ручками в БД задать связь, то $this->getUser()->getGroups()->toArray(); правильно покажет включенную группу.

И еще вопрос, после того как будут заданы группы юзерам, как можно будет отобрать всех юзеров требуемой группы?
 

d1gi

Новичок
такс, как внести изменения в БД после выполнения addGroup() я нашел:

PHP:
$this->get('fos_user.user_manager')->updateUser($this->getUser());
теперь нужно разобраться как можно получиться список всех юзеров какой-то заданной группы, можете помоч куда смотреть?
 

fixxxer

К.О.
Партнер клуба
* @ORM\ManyToMany(targetEntity="Acme\Bundle\UserBundle\Entity\Group")
* @ORM\JoinTable(name="users_groups_relations",
* joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="group_id", referencedColumnName="id")}
* )
Вы меня простите за оффтоп, но это же звиздец. В какую больную голову вообще мог прийти такой синтаксис? А когда-то был внемяемый ОРМ...
 
  • Like
Реакции: AmdY

AmdY

Пью пиво
Команда форума
fixxxer
+1, в версии 1.х было всё нормально, а вторую версию родили от очень большого ума. А добавив ещё отсутствие автокомплита я вовсе не понимаю смысла.
 

d1gi

Новичок
такс... в классе User добавил в аннотацию inversedBy="users", получилось

PHP:
/*
 *@ORM\ManyToMany(targetEntity="Acme\Bundle\UserBundle\Entity\Group", inversedBy="users")
 */
в классе Group
PHP:
    /**
     * @ORM\ManyToMany(targetEntity="Acme\Bundle\UserBundle\Entity\User", mappedBy="groups")
     */
    protected $users;

    public function __construct() {
        $this->users = new ArrayCollection();
    }
    
    public function getUsers()
    {
        return $this->users;
    }
Затем в контроллере:
PHP:
$em = $this->getDoctrine()->getEntityManager();
$users = $em->getRepository('AcmeUserBundle:Group')->find(3)->getUsers();
print_r($users);
и тишина... выборки юзеров не происходит...

далее в консоле выполняю:
PHP:
php app/console doctrine:schema:update --dump-sql
а в ответ:
PHP:
  [Doctrine\DBAL\Schema\SchemaException]
  The table with name 'acme.users_groups_relations' already exists.

если по мануалу http://docs.doctrine-project.org/projects/doctrine-orm/en/2.1/reference/association-mapping.html#many-to-many-bidirectional то вроде бы всё правильно... гуглю уже второй день...
 

d1gi

Новичок
сделал тестовую репу https://github.com/Smart-Core/FOSUserBundle-Users-Groups-Relation

выполняю:
PHP:
php app/console doctrine:schema:update --dump-sql
в ответ:
PHP:
CREATE TABLE group_user (group_id INT NOT NULL, user_id INT NOT NULL, INDEX IDX_A4C ........
почему он не юзает таблицу fos_user_user_group, которая указана в User? а пытается создать свою?
 

d1gi

Новичок
Выборка юзеров заданной группы видимо лучше всего сделать через DQL запрос, например:

PHP:
        $users = $em->createQuery("SELECT u FROM AcmeUserBundle:User u JOIN u.groups g WHERE g.id = 1")
            ->setMaxResults(5)
            ->setFirstResult(0)
            ->getResult();
Теперь такой вопрос ;) нужно, чтобы человек при регистрации указал свою группу, допустим форму расширил:

PHP:
        $builder->add('my_group', 'choice', array(
            'choices' => array(
                'videograph' => 'Видеограф',
                'photographers' => 'Фотограф'),
        ));
Можете подсказать куда дальше копать, чтобы в процессе регистрации в таблице users_groups_relations появилась связь?

Разумеется в форме можно указывать и id группы, это вторично, главное чтобы пользоваться юзерам можно было :)

UPD: песочницу выложил в репу https://github.com/Smart-Core/FOSUserBundle-Users-Groups-Relation
 
Сверху