Controller.php 18KB

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