CoreController.php 20KB

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