Controller.php 17KB

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