CoreController.php 20KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699
  1. <?php
  2. namespace Muzich\CoreBundle\Controller;
  3. use Muzich\CoreBundle\lib\Controller;
  4. //use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
  5. use Muzich\CoreBundle\Entity\FollowUser;
  6. use Muzich\CoreBundle\Entity\FollowGroup;
  7. //use Doctrine\ORM\Query;
  8. use Muzich\CoreBundle\Form\Element\ElementAddForm;
  9. use Muzich\CoreBundle\ElementFactory\ElementManager;
  10. use Muzich\CoreBundle\Entity\Element;
  11. use Symfony\Component\HttpFoundation\RedirectResponse;
  12. use Muzich\CoreBundle\Form\Search\ElementSearchForm;
  13. use Symfony\Component\Routing\Exception\ResourceNotFoundException;
  14. use Muzich\CoreBundle\Entity\Tag;
  15. use Muzich\CoreBundle\Managers\TagManager;
  16. use Muzich\CoreBundle\Entity\UsersTagsFavorites;
  17. use Muzich\CoreBundle\Managers\ElementReportManager;
  18. use Muzich\CoreBundle\Propagator\EventUser;
  19. class CoreController extends Controller
  20. {
  21. /**
  22. * Action permettant de changer le language
  23. *
  24. * @param string $language
  25. * @return RedirectResponse
  26. */
  27. public function changeLanguageAction($language)
  28. {
  29. if($language != null)
  30. {
  31. $old = $this->get('session')->getLocale();
  32. $this->get('session')->setLocale($language);
  33. }
  34. $url_referer = $this->container->get('request')->headers->get('referer');
  35. $url_referer = str_replace(
  36. $siteurl = $this->container->getParameter('siteurl'),
  37. '',
  38. $url_referer
  39. );
  40. try {
  41. $params = $this->get('router')->match($url_referer);
  42. } catch (ResourceNotFoundException $exc) {
  43. return $this->redirect($this->generateUrl('home', array('_locale' => $language)));
  44. }
  45. $params['_locale'] = $language;
  46. $route = $params['_route'];
  47. unset($params['_route'], $params['_controller']);
  48. $new_url = $this->generateUrl($route, $params);
  49. return new RedirectResponse($new_url);
  50. }
  51. /**
  52. *
  53. * Cette action est écrite pour les utilisateur redirigé du a l'absence de
  54. * lague dans leur route.
  55. * Cette redirection n'est pas interne au code, elle est actuellement effectué
  56. * par le .htaccess lorsque il n'y as pas d'url (en plus de muzi.ch/
  57. */
  58. public function automaticLanguageAction()
  59. {
  60. $lang = $this->container->get('request')
  61. ->getPreferredLanguage($this->container->getParameter('supported_langs'));
  62. // Si on a une lang en sortie,
  63. if (is_null($lang))
  64. {
  65. $lang = 'fr';
  66. }
  67. if ($this->getUser() != 'anon.')
  68. {
  69. return $this->redirect($this->generateUrl('home', array('_locale' => $lang)));
  70. }
  71. else
  72. {
  73. return $this->redirect($this->generateUrl('index', array('_locale' => $lang)));
  74. }
  75. }
  76. /**
  77. * Cette action permet a un utilisateur de suivre ou de ne plus suivre
  78. * un utilisateur ou un groupe.
  79. *
  80. * @param string $type
  81. * @param int $id
  82. * @param string $salt
  83. */
  84. public function followAction($type, $id, $token)
  85. {
  86. if (($response = $this->mustBeConnected()))
  87. {
  88. return $response;
  89. }
  90. $user = $this->getUser();
  91. /**
  92. * Bug lors des tests: L'user n'est pas 'lié' a celui en base par doctrine.
  93. * Docrine le voit si on faire une requete directe.
  94. */
  95. if ($this->container->getParameter('env') == 'test')
  96. {
  97. $user = $this->getDoctrine()->getRepository('MuzichCoreBundle:User')->findOneById(
  98. $this->container->get('security.context')->getToken()->getUser()->getId(),
  99. array()
  100. )->getSingleResult();
  101. }
  102. // Vérifications préléminaires
  103. if ($user->getPersonalHash() != $token
  104. || !in_array($type, array('user', 'group'))
  105. || !is_numeric($id)
  106. || $user->getId() == $id
  107. )
  108. {
  109. throw $this->createNotFoundException();
  110. }
  111. // On tente de récupérer l'enregistrement FollowUser / FollowGroup
  112. $em = $this->getDoctrine()->getEntityManager();
  113. $Follow = $em
  114. ->getRepository('MuzichCoreBundle:Follow' . ucfirst($type))
  115. ->findOneBy(
  116. array(
  117. 'follower' => $user->getId(),
  118. ($type == 'user') ? 'followed' : 'group' => $id
  119. )
  120. )
  121. ;
  122. // Si il existe déjà c'est qu'il ne veut plus suivre
  123. if ($Follow)
  124. {
  125. if ($type == 'user')
  126. {
  127. // L'utilisateur suis déjà, on doit détruire l'entité
  128. $event = new EventUser($this->container);
  129. $event->removeFromFollow($Follow->getFollowed());
  130. $em->persist($Follow->getFollowed());
  131. }
  132. $em->remove($Follow);
  133. $em->flush();
  134. $following = false;
  135. }
  136. // Sinon, c'est qu'il veut le suivre
  137. else
  138. {
  139. // On récupére l'entité a suivre
  140. $followed = $em->getRepository('MuzichCoreBundle:'.ucfirst($type))->find($id);
  141. if (!$followed) {
  142. throw $this->createNotFoundException('No '.$type.' found for id '.$id);
  143. }
  144. // On instancie te renseigne l'objet Follow****
  145. if ($type == 'user') { $Follow = new FollowUser(); }
  146. else { $Follow = new FollowGroup(); }
  147. $Follow->setFollower($user);
  148. if ($type == 'user')
  149. {
  150. $Follow->setFollowed($followed);
  151. $event = new EventUser($this->container);
  152. $event->addToFollow($followed, $this->getUser());
  153. $em->persist($followed);
  154. }
  155. else { $Follow->setGroup($followed); }
  156. $em->persist($Follow);
  157. $em->flush();
  158. $following = true;
  159. }
  160. if ($this->getRequest()->isXmlHttpRequest())
  161. {
  162. return $this->jsonResponse(array(
  163. 'status' => 'success',
  164. 'following' => $following
  165. ));
  166. }
  167. else
  168. {
  169. return $this->redirect($this->container->get('request')->headers->get('referer'));
  170. }
  171. }
  172. /**
  173. * Procédure d'ajout d'un element
  174. */
  175. public function elementAddAction($group_slug)
  176. {
  177. if (($response = $this->mustBeConnected()))
  178. {
  179. return $response;
  180. }
  181. if ($this->getRequest()->getMethod() != 'POST')
  182. {
  183. throw $this->createNotFoundException('Cette ressource n\'est pas accessible');
  184. }
  185. $user = $this->getUser(true, array('join' => array('groups_owned_groups_tags')));
  186. $em = $this->getDoctrine()->getEntityManager();
  187. /*
  188. * Contrôle préléminaire si groupe précisé
  189. */
  190. $group = null;
  191. if ($group_slug)
  192. {
  193. $group = $this->findGroupWithSlug($group_slug);
  194. if (!$group->userCanAddElement($this->getUserId()))
  195. {
  196. $group = null;
  197. throw $this->createNotFoundException('Vous ne pouvez pas ajouter d\'éléments a ce groupe');
  198. }
  199. }
  200. $element = new Element();
  201. $element->setType('none');
  202. $form = $this->getAddForm($element);
  203. $form->bindRequest($this->getRequest());
  204. if ($form->isValid())
  205. {
  206. /**
  207. * Bug lors des tests: L'user n'est pas 'lié' a celui en base par doctrine.
  208. * Docrine le voit si on faire une requete directe.
  209. */
  210. if ($this->container->getParameter('env') == 'test')
  211. {
  212. $user = $this->getDoctrine()->getRepository('MuzichCoreBundle:User')->findOneById(
  213. $this->container->get('security.context')->getToken()->getUser()->getId(),
  214. array()
  215. )->getSingleResult();
  216. }
  217. // On utilise le gestionnaire d'élément
  218. $factory = new ElementManager($element, $em, $this->container);
  219. $factory->proceedFill($user);
  220. // Si on a précisé un groupe dans lequel mettre l'element
  221. if ($group)
  222. {
  223. $element->setGroup($group);
  224. $redirect_url = $this->generateUrl('show_group', array('slug' => $group_slug));
  225. }
  226. else
  227. {
  228. $redirect_url = $this->generateUrl('home');
  229. }
  230. $em->persist($element);
  231. $em->flush();
  232. if ($this->getRequest()->isXmlHttpRequest())
  233. {
  234. // Récupération du li
  235. if (!$group)
  236. {
  237. $html = $this->render('MuzichCoreBundle:SearchElement:li.element.html.twig', array(
  238. 'element' => $element,
  239. 'class_color' => 'odd'
  240. ))->getContent();
  241. }
  242. else
  243. {
  244. $html = $this->render('MuzichCoreBundle:SearchElement:li.element.html.twig', array(
  245. 'element' => $element,
  246. 'class_color' => 'odd',
  247. 'no_group_name' => true
  248. ))->getContent();
  249. }
  250. return $this->jsonResponse(array(
  251. 'status' => 'success',
  252. 'html' => $html,
  253. 'groups' => (!$group)?$this->isAddedElementCanBeInGroup($element):array()
  254. ));
  255. }
  256. else
  257. {
  258. return $this->redirect($redirect_url);
  259. }
  260. }
  261. else
  262. {
  263. if ($this->getRequest()->isXmlHttpRequest())
  264. {
  265. // Récupération des erreurs
  266. $validator = $this->container->get('validator');
  267. $errorList = $validator->validate($form);
  268. $errors = array();
  269. foreach ($errorList as $error)
  270. {
  271. $errors[] = $this->trans($error->getMessage(), array(), 'validators');
  272. }
  273. foreach ($form->getErrors() as $error)
  274. {
  275. if (!in_array($err = $this->trans($error->getMessageTemplate(), array(), 'validators'), $errors))
  276. {
  277. $errors[] = $err;
  278. }
  279. }
  280. return $this->jsonResponse(array(
  281. 'status' => 'error',
  282. 'errors' => $errors
  283. ));
  284. }
  285. else
  286. {
  287. if (!$group_slug)
  288. {
  289. $search_object = $this->getElementSearcher();
  290. $search_form = $this->getSearchForm($search_object);
  291. $add_form = $form;
  292. return $this->render('MuzichHomeBundle:Home:index.html.twig', array(
  293. 'search_tags_id' => $search_object->getTags(),
  294. 'user' => $this->getUser(),
  295. 'add_form' => $add_form->createView(),
  296. 'add_form_name' => 'add',
  297. 'search_form' => $search_form->createView(),
  298. 'search_form_name' => 'search',
  299. 'network_public' => $search_object->isNetworkPublic(),
  300. 'elements' => $search_object->getElements($this->getDoctrine(), $this->getUserId()),
  301. 'more_count' => $this->container->getParameter('search_default_count')*2,
  302. 'ids_display' => $search_object->getIdsDisplay()
  303. ));
  304. }
  305. else
  306. {
  307. $group = $this->findGroupWithSlug($group_slug);
  308. $search_object = $this->createSearchObject(array(
  309. 'group_id' => $group->getId()
  310. ));
  311. ($group->getOwner()->getId() == $this->getUserId()) ? $his = true : $his = false;
  312. if ($his || $group->getOpen())
  313. {
  314. $add_form = $form;
  315. }
  316. return $this->render('MuzichHomeBundle:Show:showGroup.html.twig', array(
  317. 'group' => $group,
  318. 'his_group' => ($group->getOwner()->getId() == $this->getUserId()) ? true : false,
  319. 'elements' => $search_object->getElements($this->getDoctrine(), $this->getUserId()),
  320. 'following' => $this->getUser()->isFollowingGroupByQuery($this->getDoctrine(), $group->getId()),
  321. 'user' => $this->getUser(),
  322. 'add_form' => (isset($add_form)) ? $add_form->createView() : null,
  323. 'add_form_name' => (isset($add_form)) ? 'add' : null,
  324. 'more_count' => null,
  325. 'more_route' => 'show_group_more',
  326. 'ids_display' => $search_object->getIdsDisplay()
  327. ));
  328. }
  329. }
  330. }
  331. }
  332. /**
  333. * Cette méthode vérifie si l'élément qui vient d'être envoyé pourrais être
  334. * associé a un groupe de l'utilisateur.
  335. *
  336. * @param Element $element
  337. * @return array
  338. */
  339. protected function isAddedElementCanBeInGroup(Element $element)
  340. {
  341. $element_tags = $element->getTags();
  342. $groups = array();
  343. foreach ($this->getUser()->getGroupsOwned() as $group)
  344. {
  345. foreach ($element_tags as $element_tag)
  346. {
  347. if ($group->hasThisTag($element_tag->getId()))
  348. {
  349. $groups[] = array(
  350. 'name' => $group->getName(),
  351. 'id' => $group->getId(),
  352. 'url' => $this->generateUrl('ajax_set_element_group', array(
  353. 'token' => $this->getUser()->getPersonalHash(),
  354. 'element_id' => $element->getId(),
  355. 'group_id' => $group->getId()
  356. ))
  357. );
  358. }
  359. }
  360. }
  361. return $groups;
  362. }
  363. /**
  364. * Action non ajax nettoyant la liste de tags du chercheur d'éléments
  365. *
  366. * @return RedirectResponse
  367. */
  368. public function filterClearAction()
  369. {
  370. $es = $this->getElementSearcher();
  371. $es->update(array('tags' => array()));
  372. $this->setElementSearcherParams($es->getParams());
  373. return $this->redirect($this->container->get('request')->headers->get('referer'));
  374. }
  375. /**
  376. * Action non ajax de selection de ses tags favoris pour le chercheur d'élément
  377. *
  378. * @return RedirectResponse
  379. */
  380. public function filterMytagsAction()
  381. {
  382. $this->getElementSearcher(null, true);
  383. return $this->redirect($this->container->get('request')->headers->get('referer'));
  384. }
  385. /**
  386. * Action de récupération ajax de l'id des tags favoris de son profil
  387. *
  388. * @return Response
  389. */
  390. public function getFavoriteTagsAction()
  391. {
  392. if (($response = $this->mustBeConnected()))
  393. {
  394. return $response;
  395. }
  396. // On construit l'element searcher avec les tags favoris
  397. $es = $this->getElementSearcher(null, true);
  398. // Et on retourne les tags
  399. return $this->jsonResponse(array(
  400. 'response' => 'success',
  401. 'tags' => $es->getTags()
  402. ));
  403. }
  404. /**
  405. * Ajout d'un tag en base.
  406. */
  407. public function addTagAction()
  408. {
  409. if (($response = $this->mustBeConnected(true)))
  410. {
  411. return $response;
  412. }
  413. if (strlen((($tag_name = $this->getRequest()->request->get('tag_name'))))
  414. < $this->container->getParameter('tag_add_min_length'))
  415. {
  416. return $this->jsonResponse(array(
  417. 'status' => 'error',
  418. 'errors' => array($this->trans(
  419. 'tags.add.errors.min',
  420. array(
  421. '%limit%' => $this->container->getParameter('tag_add_min_length')
  422. ),
  423. 'userui'
  424. )
  425. )));
  426. }
  427. if (strlen($tag_name) > $this->container->getParameter('tag_add_max_length'))
  428. {
  429. return $this->jsonResponse(array(
  430. 'status' => 'error',
  431. 'errors' => array($this->trans(
  432. 'tags.add.errors.max',
  433. array(
  434. '%limit%' => $this->container->getParameter('tag_add_max_length')
  435. ),
  436. 'userui'
  437. )
  438. )));
  439. }
  440. $tagManager = new TagManager();
  441. $tag = $tagManager->addTag(
  442. $this->getDoctrine(),
  443. $tag_name,
  444. $this->getUser(),
  445. $this->getRequest()->request->get('argument')
  446. );
  447. return $this->jsonResponse(array(
  448. 'status' => 'success',
  449. 'tag_id' => $tag->getId(),
  450. 'tag_name' => $tag->getName()
  451. ));
  452. }
  453. /**
  454. * Action ajax qui ajoute le tags précisé en paramétre aux tags favoris de
  455. * l'utilisateur.
  456. *
  457. * @param int $tag_id
  458. * @param string $token
  459. * @return Response
  460. */
  461. public function addTagToFavoritesAction($tag_id, $token)
  462. {
  463. if (($response = $this->mustBeConnected(true)))
  464. {
  465. return $response;
  466. }
  467. if (!($tag = $this->getDoctrine()->getRepository('MuzichCoreBundle:Tag')
  468. ->findOneById($tag_id)) || $this->getUser()->getPersonalHash() != $token)
  469. {
  470. return $this->jsonResponse(array(
  471. 'status' => 'error',
  472. 'errors' => array('NotFound')
  473. ));
  474. }
  475. $user = $this->getUser();
  476. /**
  477. * Bug lors des tests: L'user n'est pas 'lié' a celui en base par doctrine.
  478. * Docrine le voit si on faire une requete directe.
  479. */
  480. if ($this->container->getParameter('env') == 'test')
  481. {
  482. $user = $this->getDoctrine()->getRepository('MuzichCoreBundle:User')->findOneById(
  483. $this->container->get('security.context')->getToken()->getUser()->getId(),
  484. array()
  485. )->getSingleResult();
  486. }
  487. // On contrôle au préalable que le tag ne fait pas déjà partie des favoris de
  488. // l'utilisateur
  489. if (!$this->getDoctrine()->getRepository('MuzichCoreBundle:UsersTagsFavorites')
  490. ->findOneBy(array(
  491. 'user' => $this->getUserId(),
  492. 'tag' => $tag->getId()
  493. )))
  494. {
  495. // Si il ne l'est pas, on créer ce nouvel objet de relation
  496. $fav = new UsersTagsFavorites();
  497. $fav->setTag($tag);
  498. $fav->setUser($user);
  499. $fav->setPosition(0);
  500. $this->getDoctrine()->getEntityManager()->persist($fav);
  501. $this->getDoctrine()->getEntityManager()->flush();
  502. }
  503. return $this->jsonResponse(array(
  504. 'status' => 'success'
  505. ));
  506. }
  507. /**
  508. * Cette action (ajax) configure l'appartenance d'un élément a un groupe.
  509. * Le groupe et l'élément doivent appartenir a l'utilisateur en cours.
  510. *
  511. * @param int $element_id
  512. * @param int $group_id
  513. * @param string $token
  514. * @return Response
  515. */
  516. public function setElementGroupAction($element_id, $group_id, $token)
  517. {
  518. if (($response = $this->mustBeConnected(true)))
  519. {
  520. return $response;
  521. }
  522. if (!($element = $this->getDoctrine()->getRepository('MuzichCoreBundle:Element')
  523. ->findOneById($element_id))
  524. || !($group = $this->getDoctrine()->getRepository('MuzichCoreBundle:Group')
  525. ->findOneById($group_id))
  526. || $this->getUser()->getPersonalHash() != $token)
  527. {
  528. return $this->jsonResponse(array(
  529. 'status' => 'error',
  530. 'errors' => array('NotFound')
  531. ));
  532. }
  533. if ($element->getOwner()->getId() != $this->getUserId()
  534. || $group->getOwner()->getId() != $this->getUserId()
  535. )
  536. {
  537. return $this->jsonResponse(array(
  538. 'status' => 'error',
  539. 'errors' => array('NotAllowed')
  540. ));
  541. }
  542. // a partir d'ici on a tout ce qu'il faut
  543. $element->setGroup($group);
  544. $this->getDoctrine()->getEntityManager()->persist($element);
  545. $this->getDoctrine()->getEntityManager()->flush();
  546. // On récupère le nouveau dom de l'élément
  547. $html = $this->render('MuzichCoreBundle:SearchElement:element.html.twig', array(
  548. 'element' => $element
  549. ))->getContent();
  550. return $this->jsonResponse(array(
  551. 'status' => 'success',
  552. 'html' => $html,
  553. 'dom_id' => 'element_'.$element->getId()
  554. ));
  555. }
  556. /**
  557. * Action (ajax) permettant de signaler un élément comme contenu non approprié.
  558. *
  559. * @param int $element_id
  560. * @param string $token
  561. * @return Response
  562. */
  563. public function reportElementAction($element_id, $token)
  564. {
  565. if (($response = $this->mustBeConnected(true)))
  566. {
  567. return $response;
  568. }
  569. if (!($element = $this->getDoctrine()->getRepository('MuzichCoreBundle:Element')
  570. ->findOneById($element_id))
  571. || $this->getUser()->getPersonalHash() != $token)
  572. {
  573. return $this->jsonResponse(array(
  574. 'status' => 'error',
  575. 'errors' => array('NotFound')
  576. ));
  577. }
  578. // On utilise le manager de rapport
  579. $erm = new ElementReportManager($element);
  580. $erm->add($this->getUser());
  581. $this->getDoctrine()->getEntityManager()->persist($element);
  582. $this->getDoctrine()->getEntityManager()->flush();
  583. return $this->jsonResponse(array(
  584. 'status' => 'success'
  585. ));
  586. }
  587. /**
  588. * Il arrive que l'on configure le chercheur d'élément de façon a ce qu'il
  589. * affiche une liste d'élément précis (collection d'id). Cette action
  590. * supprime cette configuration de façon a ce que le chercheur fonctionne
  591. * normalement.
  592. *
  593. * @return type
  594. */
  595. public function filterRemoveIdsAction()
  596. {
  597. if (($response = $this->mustBeConnected(true)))
  598. {
  599. return $response;
  600. }
  601. $es = $this->getElementSearcher();
  602. $es->setIds(null);
  603. $es->setIdsDisplay(null);
  604. $this->setElementSearcherParams($es->getParams());
  605. $html = $this->render('MuzichCoreBundle:SearchElement:default.html.twig', array(
  606. 'user' => $this->getUser(),
  607. 'elements' => $es->getElements($this->getDoctrine(), $this->getUserId()),
  608. 'invertcolor' => false
  609. ))->getContent();
  610. return $this->jsonResponse(array(
  611. 'status' => 'success',
  612. 'html' => $html
  613. ));
  614. }
  615. }