Controller.php 18KB

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