Controller.php 19KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706
  1. <?php
  2. namespace Muzich\CoreBundle\lib;
  3. use Symfony\Bundle\FrameworkBundle\Controller\Controller as BaseController;
  4. use Muzich\CoreBundle\Searcher\ElementSearcher;
  5. use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
  6. use Muzich\CoreBundle\Form\Search\ElementSearchForm;
  7. use Muzich\CoreBundle\Form\Element\ElementAddForm;
  8. use Symfony\Component\HttpFoundation\Response;
  9. use Muzich\CoreBundle\Searcher\GlobalSearcher;
  10. use Muzich\CoreBundle\Entity\Element;
  11. use Muzich\CoreBundle\Entity\Presubscription;
  12. use Muzich\CoreBundle\Entity\User;
  13. use Muzich\CoreBundle\Entity\Playlist;
  14. use Muzich\CoreBundle\Security\Context as SecurityContext;
  15. use Muzich\CoreBundle\Managers\PlaylistManager;
  16. use Muzich\CoreBundle\Form\Playlist\PlaylistForm;
  17. class Controller extends BaseController
  18. {
  19. protected static $user = null;
  20. protected static $user_personal_query = null;
  21. protected static $tags = array();
  22. /** @var SecurityContext */
  23. protected $security_context;
  24. /**
  25. * Authenticate a user with Symfony Security
  26. *
  27. */
  28. protected function authenticateUser($user)
  29. {
  30. $providerKey = $this->container->getParameter('fos_user.firewall_name');
  31. $token = new UsernamePasswordToken($user, null, $providerKey, $user->getRoles());
  32. $this->container->get('security.context')->setToken($token);
  33. }
  34. /**
  35. * Met a jour les parametres de ElementSearcher pour la "mémoire" de la
  36. * recherche
  37. *
  38. * @param array $params
  39. */
  40. protected function setElementSearcherParams($params, $session_id = '')
  41. {
  42. if ($session_id != '')
  43. {
  44. $session_id = '.'.$session_id;
  45. }
  46. if (!count($params['tags']))
  47. {
  48. if (count($this->getElementSearcher()->getTags()))
  49. {
  50. $this->get("session")->set('user.element_search.last_tags', $this->getElementSearcher()->getTags());
  51. }
  52. }
  53. $this->get("session")->set('user.element_search.params'.$session_id, $params);
  54. }
  55. protected function isVisitor()
  56. {
  57. $user = $this->getUser();
  58. if ($user === 'anon.')
  59. {
  60. return true;
  61. }
  62. elseif ($user instanceof User)
  63. {
  64. return false;
  65. }
  66. throw new \Exception('Unable to determine user type');
  67. }
  68. /**
  69. * Retourn l'objet ElementSearcher en cours.
  70. *
  71. * @param int $count Si renseigné impact le nombre d'éléments qui seront
  72. * récupérés
  73. * @param boolean $force_new Si a vrai la méthode procéède comme si on
  74. * demandé un nouveau objet de recherche (basé sur les tags favoris donc).
  75. *
  76. * @return ElementSearcher
  77. */
  78. protected function getElementSearcher($count = null, $force_new = false, $session_id = '')
  79. {
  80. $session = $this->get("session");
  81. if ($session_id != '')
  82. {
  83. $session_id = '.'.$session_id;
  84. }
  85. // Si l'objet n'existe pas encore, a t-on déjà des paramètres de recherche
  86. if (!$session->has('user.element_search.params'.$session_id) || $force_new)
  87. {
  88. // Il nous faut instancier notre premier objet recherche
  89. // Premièrement on récupère les tags favoris de l'utilisateur
  90. $this->ElementSearcher = new ElementSearcher();
  91. $this->ElementSearcher->init(array(
  92. 'tags' => $this->getUserFavoriteTags(),
  93. 'count' => ($count)?$count:$this->container->getParameter('search_default_count')
  94. ));
  95. // Et on met en session les paramètres
  96. $session->set('user.element_search.params', $this->ElementSearcher->getParams());
  97. }
  98. else
  99. {
  100. // Des paramètres existes, on fabrique l'objet recherche
  101. $this->ElementSearcher = new ElementSearcher();
  102. // et on l'initatialise avec ces paramétres connus
  103. $this->ElementSearcher->init($session->get('user.element_search.params'.$session_id));
  104. if ($count)
  105. {
  106. $this->ElementSearcher->update(array('count' => $count));
  107. }
  108. }
  109. // on le retourne
  110. return $this->ElementSearcher;
  111. }
  112. protected function getUserFavoriteTags()
  113. {
  114. if (!$this->isVisitor())
  115. {
  116. return $this->getDoctrine()->getRepository('MuzichCoreBundle:User')
  117. ->getTagsFavorites(
  118. $this->getUserId(),
  119. $this->container->getParameter('search_default_favorites_tags_count')
  120. )
  121. ;
  122. }
  123. return array();
  124. }
  125. protected function getNewElementSearcher()
  126. {
  127. return $this->getElementSearcher(null, true);
  128. }
  129. /**
  130. * Retourne l'objet User. Il est possible de préciser de quel manière récupérer
  131. * l'utilisateur:
  132. *
  133. * $user = $this->getUser(true, array('join' => array(
  134. * 'groups_owned'
  135. * )));
  136. *
  137. * ou de forcer sa (re)récupération en base (sinon c'est l'objet static qui est renvoyé)
  138. *
  139. * @param boolean $personal_query
  140. * @param array $params
  141. * @param boolean $force_refresh
  142. * @return \Muzich\CoreBundle\Entity\User
  143. */
  144. public function getUser($personal_query = false, $params = array(), $force_refresh = false)
  145. {
  146. if ($this->container->getParameter('env') == 'test')
  147. {
  148. return $this->container->get('security.context')->getToken()->getUser();
  149. }
  150. if (!$personal_query)
  151. {
  152. // Si on demande l'utilisateur sans forcer la réactualisation et que l'utilisateur
  153. // a déjà été demandé mais avec un requête personelle, on retourne cet utilisateur
  154. if (!$force_refresh && self::$user_personal_query)
  155. {
  156. return self::$user_personal_query;
  157. }
  158. // Si on demande une actualisation ou que l'utilisateur n'a pas encore été demandé
  159. // on va le récupérer
  160. else if ($force_refresh || !self::$user)
  161. {
  162. self::$user = $this->container->get('security.context')->getToken()->getUser();
  163. return self::$user;
  164. }
  165. return self::$user;
  166. }
  167. else
  168. {
  169. // Si l'on demande une réactualisation ou si l'user n'a pas encore été demandé
  170. // on va le récupérer en base.
  171. if ($force_refresh || !self::$user_personal_query)
  172. {
  173. $user = $this->container->get('security.context')->getToken()->getUser();
  174. if ($user !== 'anon.')
  175. {
  176. self::$user_personal_query = $this->getDoctrine()->getRepository('MuzichCoreBundle:User')->findOneById(
  177. $this->container->get('security.context')->getToken()->getUser()->getId(),
  178. array_key_exists('join', $params) ? $params['join'] : array()
  179. )->getSingleResult();
  180. return self::$user_personal_query;
  181. }
  182. else
  183. {
  184. return 'anon.';
  185. }
  186. }
  187. return self::$user_personal_query;
  188. }
  189. }
  190. protected function getUserOrNullIfVisitor()
  191. {
  192. if (($user = $this->getUser()) === 'anon.')
  193. {
  194. return null;
  195. }
  196. return $user;
  197. }
  198. /**
  199. * Retourne l'id de l'utilisateur en cours
  200. */
  201. protected function getUserId($return_null_if_visitor = false)
  202. {
  203. $user = $this->getUser();
  204. if ($user !== 'anon.')
  205. {
  206. return $user->getId();
  207. }
  208. if ($return_null_if_visitor)
  209. {
  210. return null;
  211. }
  212. throw new \Exception('User not connected');
  213. }
  214. protected function getUserRefreshed()
  215. {
  216. return $this->getUser(false, array(), true);
  217. }
  218. /**
  219. * Retourne un tabeau avec les tags connus.
  220. * TODO: Voir pour que cette info soit stocké (par exemple) dans un champs
  221. * texte en base. (json array)
  222. * TODO2: Voir si la question d'opt. "Formulaire d'ajout d'un élément" ne résoue pas
  223. * le problème du TODO ci-dessus.
  224. *
  225. * @return array
  226. */
  227. protected function getTagsArray($force_refresh = false)
  228. {
  229. throw new \Exception("Cette méthode ne doit plus être utilisé.");
  230. if (!count(self::$tags) || $force_refresh)
  231. {
  232. return self::$tags = $this->getDoctrine()->getRepository('MuzichCoreBundle:Tag')->getTagsArray();
  233. }
  234. return self::$tags;
  235. }
  236. /**
  237. * Retourne un tabeau avec les groupes accessible pour un ajout d'element.
  238. *
  239. * @return array
  240. */
  241. protected function getGroupsArray()
  242. {
  243. return $this->getDoctrine()->getRepository('MuzichCoreBundle:Group')
  244. ->getPublicAndOwnedArray($this->getUserId());
  245. }
  246. /**
  247. * Met en place un message de type flash.
  248. *
  249. * @param string $type
  250. * @param string $value
  251. */
  252. protected function setFlash($type, $value)
  253. {
  254. $this->container->get('session')->setFlash($type, $value);
  255. }
  256. /**
  257. * Instancie et retourne un objet ElementSearch
  258. *
  259. * @param array $params
  260. * @return ElementSearcher
  261. */
  262. protected function createSearchObject($params)
  263. {
  264. $search_object = new ElementSearcher();
  265. $search_object->init($params);
  266. return $search_object;
  267. }
  268. /**
  269. * Retourne un User en fonction du slug passé
  270. *
  271. * @param string $slug
  272. * @return User
  273. */
  274. protected function findUserWithSlug($slug)
  275. {
  276. try {
  277. return $this->getDoctrine()
  278. ->getRepository('MuzichCoreBundle:User')
  279. ->findOneBySlug($slug)
  280. ->getSingleResult()
  281. ;
  282. } catch (\Doctrine\ORM\NoResultException $e) {
  283. throw $this->createNotFoundException('Utilisateur introuvable.');
  284. }
  285. }
  286. /**
  287. * Retourne un Group en fonction du slug passé
  288. *
  289. * @param string $slug
  290. * @return Group
  291. */
  292. protected function findGroupWithSlug($slug)
  293. {
  294. try {
  295. return $this->getDoctrine()
  296. ->getRepository('MuzichCoreBundle:Group')
  297. ->findOneBySlug($slug)
  298. ->getSingleResult()
  299. ;
  300. } catch (\Doctrine\ORM\NoResultException $e) {
  301. throw $this->createNotFoundException('Groupe introuvable.');
  302. }
  303. }
  304. /**
  305. * Retourne un Group en fonction du id passé
  306. *
  307. * @param string $slug
  308. * @return Group
  309. */
  310. protected function findGroupWithId($id)
  311. {
  312. try {
  313. return $this->getDoctrine()
  314. ->getRepository('MuzichCoreBundle:Group')
  315. ->findOneById($id)
  316. ;
  317. } catch (\Doctrine\ORM\NoResultException $e) {
  318. throw $this->createNotFoundException('Groupe introuvable.');
  319. }
  320. }
  321. /**
  322. * Retourne le formulaire de recherche
  323. *
  324. * @param \Muzich\CoreBundle\Searcher\Searcher $search_object
  325. * @return \Symfony\Component\Form\Form
  326. */
  327. protected function getSearchForm($search_object)
  328. {
  329. return $this->createForm(
  330. new ElementSearchForm(),
  331. $search_object->getParams(true),
  332. array()
  333. );
  334. }
  335. /**
  336. * Retourne l'objet Form du formulaire de recherche global.
  337. *
  338. * @return \Symfony\Component\Form\Form
  339. */
  340. protected function getGlobalSearchForm($searcher = null)
  341. {
  342. if ($searcher === null)
  343. {
  344. $searcher = new GlobalSearcher();
  345. }
  346. return $this->createFormBuilder($searcher)
  347. ->add('string', 'text')
  348. ->getForm();
  349. }
  350. /**
  351. * Retourne le formulaire d'ajout d'élément
  352. *
  353. * @param \Muzich\CoreBundle\Searcher\Searcher $search_object
  354. * @return \Symfony\Component\Form\Form
  355. */
  356. protected function getAddForm($element = array(), $name = null)
  357. {
  358. //$form = new ElementAddForm();
  359. //$form->setName($name);
  360. //return $this->createForm(
  361. // $form,
  362. // $element,
  363. // array()
  364. //);
  365. $form = new ElementAddForm();
  366. $form->setName($name);
  367. return $this->createForm($form, $element);
  368. }
  369. /**
  370. * Retourne une réponse contenant et de type json
  371. *
  372. * @param array $content
  373. * @return Response
  374. */
  375. protected function jsonResponse($content)
  376. {
  377. $response = new Response(json_encode($content));
  378. $response->headers->set('Content-Type', 'application/json; charset=utf-8');
  379. return $response;
  380. }
  381. protected function jsonResponseError($error_type, $error_content = array())
  382. {
  383. return $this->jsonResponse(array(
  384. 'status' => 'error',
  385. 'error' => $error_type,
  386. 'data' => $error_content
  387. ));
  388. }
  389. protected function jsonNotFoundResponse()
  390. {
  391. $response = new Response(json_encode(array(
  392. 'status' => 'error',
  393. 'errors' => array('NotFound')
  394. )));
  395. $response->headers->set('Content-Type', 'application/json; charset=utf-8');
  396. return $response;
  397. }
  398. protected function jsonSuccessResponse($data = array())
  399. {
  400. $response = new Response(json_encode(array(
  401. 'status' => 'success',
  402. 'data' => $data
  403. )));
  404. $response->headers->set('Content-Type', 'application/json; charset=utf-8');
  405. return $response;
  406. }
  407. /**
  408. * Permet d'utiliser la méthode Assert que l'on utilise dans les templates
  409. * afin d'avoir une url correcte vers une ressource web (img, js, ...)
  410. *
  411. * @param string $path
  412. * @param string $packageName
  413. * @return string
  414. */
  415. protected function getAssetUrl($path, $packageName = null)
  416. {
  417. return $this->container->get('templating.helper.assets')->getUrl($path, $packageName);
  418. }
  419. /**
  420. * Retourne une traduction effectué par le translator
  421. *
  422. * @param string $string
  423. * @param array $params
  424. * @param string $package
  425. * @return string
  426. */
  427. protected function trans($string, $params = array(), $package = null)
  428. {
  429. return $this->get('translator')->trans($string, $params, $package);
  430. }
  431. /**
  432. * Permet de récupérer un objet réponse si l'utilisateur doit être connecté
  433. * pour accéder a cette ressource. On peux préciser $and_ajax pour que
  434. * la requete de type ajax soit une nécéssité.
  435. *
  436. * @return Response
  437. */
  438. protected function mustBeConnected($and_ajax = false)
  439. {
  440. if ($and_ajax && !$this->getRequest()->isXmlHttpRequest())
  441. {
  442. throw $this->createNotFoundException('Ressource ajax uniquement.');
  443. }
  444. if ($this->getUser() == 'anon.')
  445. {
  446. $this->setFlash('error', 'user.session_expired');
  447. if ($this->getRequest()->isXmlHttpRequest())
  448. {
  449. return $this->jsonResponse(array(
  450. 'status' => 'mustbeconnected'
  451. ));
  452. }
  453. else
  454. {
  455. return $this->redirect($this->generateUrl('home'));
  456. }
  457. }
  458. }
  459. /**
  460. *
  461. * @return \Doctrine\ORM\EntityManager
  462. */
  463. public function getEntityManager()
  464. {
  465. return $this->getDoctrine()->getEntityManager();
  466. }
  467. /**
  468. *
  469. * @param object $entity
  470. */
  471. public function persist($entity)
  472. {
  473. $this->getEntityManager()->persist($entity);
  474. }
  475. /**
  476. *
  477. * @param object $entity
  478. */
  479. public function remove($entity)
  480. {
  481. $this->getEntityManager()->remove($entity);
  482. }
  483. /**
  484. *
  485. */
  486. public function flush()
  487. {
  488. $this->getEntityManager()->flush();
  489. }
  490. /**
  491. * Cette méthode vérifie si l'élément qui vient d'être envoyé pourrais être
  492. * associé a un groupe de l'utilisateur.
  493. *
  494. * @param Element $element
  495. * @return array
  496. */
  497. protected function isAddedElementCanBeInGroup(Element $element)
  498. {
  499. $element_tags = $element->getTags();
  500. $groups = array();
  501. if ($element_tags)
  502. {
  503. foreach ($this->getUser()->getGroupsOwned() as $group)
  504. {
  505. foreach ($element_tags as $element_tag)
  506. {
  507. if ($group->hasThisTag($element_tag->getId()))
  508. {
  509. $groups[] = array(
  510. 'name' => $group->getName(),
  511. 'id' => $group->getId(),
  512. 'url' => $this->generateUrl('ajax_set_element_group', array(
  513. 'token' => $this->getUser()->getPersonalHash($element->getId()),
  514. 'element_id' => $element->getId(),
  515. 'group_id' => $group->getId()
  516. ))
  517. );
  518. }
  519. }
  520. }
  521. }
  522. return $groups;
  523. }
  524. protected function getPreSubscriptionForm()
  525. {
  526. return $this->createFormBuilder(new Presubscription())
  527. ->add('email', 'email')
  528. ->getForm()
  529. ;
  530. }
  531. protected function getDisplayAutoplayBooleanForContext($context)
  532. {
  533. if (in_array($context,
  534. $this->container->getParameter('autoplay_contexts')
  535. ))
  536. {
  537. return true;
  538. }
  539. return false;
  540. }
  541. protected function sendEmailconfirmationEmail($set_send_time = true)
  542. {
  543. $user = $this->getUserRefreshed();
  544. $tokenGenerator = $this->container->get('fos_user.util.token_generator');
  545. $user->setConfirmationToken($tokenGenerator->generateToken());
  546. if ($set_send_time)
  547. $user->setEmailConfirmationSentTimestamp(time());
  548. $token = hash('sha256', $user->getConfirmationToken().$user->getEmail());
  549. $url = $this->get('router')->generate('email_confirm', array('token' => $token), true);
  550. $rendered = $this->get('templating')->render('MuzichUserBundle:User:confirm_email_email.txt.twig', array(
  551. 'confirmation_url' => $url
  552. ));
  553. //$this->sendEmailMessage($rendered, $this->parameters['from_email']['resetting'], $user->getEmail());
  554. // Render the email, use the first line as the subject, and the rest as the body
  555. $renderedLines = explode("\n", trim($rendered));
  556. $subject = $renderedLines[0];
  557. $body = implode("\n", array_slice($renderedLines, 1));
  558. $message = \Swift_Message::newInstance()
  559. ->setSubject($subject)
  560. ->setFrom('contact@muzi.ch')
  561. ->setTo($user->getEmail())
  562. ->setBody($body);
  563. $message->getHeaders()->addTextHeader('List-Unsubscribe', 'unsubscribe@muzi.ch');
  564. $mailer = $this->get('mailer');
  565. $mailer->send($message);
  566. $this->persist($user);
  567. $this->flush();
  568. }
  569. protected function getParameter($key)
  570. {
  571. return $this->container->getParameter($key);
  572. }
  573. protected function userHaveNonConditionToMakeAction($action)
  574. {
  575. $secutity_context = $this->getSecurityContext();
  576. if (($condition = $secutity_context->actionIsAffectedBy(SecurityContext::AFFECT_CANT_MAKE, $action)) !== false)
  577. {
  578. return $condition;
  579. }
  580. return false;
  581. }
  582. /** @return SecurityContext */
  583. protected function getSecurityContext()
  584. {
  585. if ($this->security_context == null)
  586. $this->security_context = new SecurityContext($this->getUser());
  587. return $this->security_context;
  588. }
  589. /** @return PlaylistManager */
  590. protected function getPlaylistManager()
  591. {
  592. return new PlaylistManager($this->getEntityManager());
  593. }
  594. protected function getLastDisplayedElementId($elements)
  595. {
  596. if (count($elements))
  597. return $elements[count($elements)-1]->getId();
  598. return null;
  599. }
  600. protected function getElementWithId($element_id)
  601. {
  602. return $this->getEntityManager()->getRepository('MuzichCoreBundle:Element')
  603. ->findOneById($element_id);
  604. }
  605. protected function getPlaylistForm(Playlist $playlist = null)
  606. {
  607. if (!$playlist)
  608. $playlist = $this->getPlaylistManager()->getNewPlaylist($this->getUserOrNullIfVisitor());
  609. return $this->createForm(new PlaylistForm(), $playlist);
  610. }
  611. protected function tokenIsCorrect($intention = '')
  612. {
  613. if ($this->getRequest()->get('token') != $this->container->get('form.csrf_provider')->generateCsrfToken($intention))
  614. return false;
  615. return true;
  616. }
  617. protected function getUserManager()
  618. {
  619. return $this->container->get('muzich_user_manager');
  620. }
  621. }