Controller.php 17KB

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