You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

преди 8 години
преди 7 години
преди 5 години
преди 6 години
преди 8 години
преди 1 година
преди 2 години
преди 1 година
преди 8 години
преди 2 години
преди 2 години
преди 8 години
преди 2 години
преди 1 година
преди 8 години
преди 2 години
преди 1 година
преди 8 години
преди 5 години
преди 2 години
преди 1 година
преди 2 години
преди 1 година
преди 2 години
преди 2 години
преди 2 години
преди 2 години
преди 2 години
преди 6 години
преди 5 години
преди 2 години
преди 8 години
преди 2 години
преди 1 година
преди 1 година
преди 1 година
преди 2 години
преди 1 година
преди 2 години
преди 1 година
преди 2 години
преди 1 година
преди 2 години
преди 1 година
преди 1 година
преди 1 година
преди 1 година
преди 1 година
преди 1 година
преди 1 година
преди 1 година
преди 1 година
преди 1 година
преди 1 година
преди 1 година
преди 2 години
преди 2 години
преди 5 години
преди 2 години
преди 2 години
преди 2 години
преди 2 години
преди 1 година
преди 2 години
преди 1 година
преди 1 година
преди 2 години
преди 2 години
преди 2 години
преди 2 години
преди 2 години
преди 2 години
преди 2 години
преди 5 години
преди 2 години
преди 8 години
преди 2 години
преди 1 година
преди 2 години
преди 2 години
преди 1 година
преди 1 година
преди 1 година
преди 1 година
преди 1 година
преди 2 години
преди 1 година
преди 2 години
преди 5 години
преди 2 години
преди 5 години
преди 2 години
преди 1 година
преди 2 години
преди 1 година
преди 2 години
преди 2 години
преди 2 години
преди 2 години
преди 1 година
преди 2 години
преди 2 години
преди 2 години
преди 8 години
преди 2 години
преди 8 години
преди 2 години
преди 5 години
преди 2 години
преди 8 години
преди 2 години
преди 1 година
преди 2 години
преди 1 година
преди 2 години
преди 1 година
преди 2 години
преди 8 години
преди 2 години
преди 2 години
преди 5 години
преди 2 години
преди 1 година
преди 1 година
преди 2 години
преди 5 години
преди 2 години
преди 1 година
преди 2 години
преди 1 година
преди 2 години
преди 2 години
преди 2 години
преди 1 година
преди 2 години
преди 2 години
преди 1 година
преди 2 години
преди 2 години
преди 2 години
преди 1 година
преди 2 години
преди 2 години
преди 2 години
преди 2 години
преди 2 години
преди 1 година
преди 2 години
преди 1 година
преди 2 години
преди 1 година
преди 2 години
преди 7 години
преди 2 години
преди 8 години
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518
  1. <?php
  2. /**
  3. * Copyright distrib (2018)
  4. *
  5. * contact@opendistrib.net
  6. *
  7. * Ce logiciel est un programme informatique servant à aider les producteurs
  8. * à distribuer leur production en circuits courts.
  9. *
  10. * Ce logiciel est régi par la licence CeCILL soumise au droit français et
  11. * respectant les principes de diffusion des logiciels libres. Vous pouvez
  12. * utiliser, modifier et/ou redistribuer ce programme sous les conditions
  13. * de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA
  14. * sur le site "http://www.cecill.info".
  15. *
  16. * En contrepartie de l'accessibilité au code source et des droits de copie,
  17. * de modification et de redistribution accordés par cette licence, il n'est
  18. * offert aux utilisateurs qu'une garantie limitée. Pour les mêmes raisons,
  19. * seule une responsabilité restreinte pèse sur l'auteur du programme, le
  20. * titulaire des droits patrimoniaux et les concédants successifs.
  21. *
  22. * A cet égard l'attention de l'utilisateur est attirée sur les risques
  23. * associés au chargement, à l'utilisation, à la modification et/ou au
  24. * développement et à la reproduction du logiciel par l'utilisateur étant
  25. * donné sa spécificité de logiciel libre, qui peut le rendre complexe à
  26. * manipuler et qui le réserve donc à des développeurs et des professionnels
  27. * avertis possédant des connaissances informatiques approfondies. Les
  28. * utilisateurs sont donc invités à charger et tester l'adéquation du
  29. * logiciel à leurs besoins dans des conditions permettant d'assurer la
  30. * sécurité de leurs systèmes et ou de leurs données et, plus généralement,
  31. * à l'utiliser et l'exploiter dans les mêmes conditions de sécurité.
  32. *
  33. * Le fait que vous puissiez accéder à cet en-tête signifie que vous avez
  34. * pris connaissance de la licence CeCILL, et que vous en avez accepté les
  35. * termes.
  36. */
  37. namespace frontend\controllers;
  38. use common\helpers\GlobalParam;
  39. use frontend\forms\ProducerCodeForm;
  40. use GuzzleHttp\Client;
  41. use Yii;
  42. use frontend\forms\PasswordResetRequestForm;
  43. use frontend\forms\ResetPasswordForm;
  44. use frontend\forms\SignupForm;
  45. use common\forms\ContactForm;
  46. use yii\base\InvalidParamException;
  47. use yii\data\ActiveDataProvider;
  48. use yii\helpers\Html;
  49. use yii\web\BadRequestHttpException;
  50. use yii\filters\VerbFilter;
  51. use yii\filters\AccessControl;
  52. use common\forms\LoginForm;
  53. use yii\web\NotFoundHttpException;
  54. /**
  55. * Site controller
  56. */
  57. class SiteController extends FrontendController
  58. {
  59. /**
  60. * @inheritdoc
  61. */
  62. public function behaviors()
  63. {
  64. return [
  65. 'access' => [
  66. 'class' => AccessControl::class,
  67. 'only' => ['logout', 'signup'],
  68. 'rules' => [
  69. [
  70. 'actions' => ['signup'],
  71. 'allow' => true,
  72. 'roles' => ['?'],
  73. ],
  74. [
  75. 'actions' => ['logout'],
  76. 'allow' => true,
  77. 'roles' => ['@'],
  78. ],
  79. ],
  80. ],
  81. 'verbs' => [
  82. 'class' => VerbFilter::class,
  83. 'actions' => [
  84. 'logout' => ['get'],
  85. ],
  86. ],
  87. ];
  88. }
  89. /**
  90. * @inheritdoc
  91. */
  92. public function actions()
  93. {
  94. return [
  95. 'captcha' => [
  96. 'class' => 'yii\captcha\CaptchaAction',
  97. 'fixedVerifyCode' => YII_ENV_TEST ? 'testme' : null,
  98. ],
  99. ];
  100. }
  101. /**
  102. * Affiche la page d'erreur.
  103. *
  104. * @return mixed
  105. */
  106. public function actionError()
  107. {
  108. $exception = \Yii::$app->errorHandler->exception;
  109. if ($exception->getMessage() == 'Producteur introuvable'
  110. || \Yii::$app->getRequest()->getQueryParam('producer_not_found')) {
  111. return $this->render('error-404-producer', ['exception' => $exception]);
  112. }
  113. if ($exception !== null) {
  114. return $this->render('error', ['exception' => $exception]);
  115. }
  116. }
  117. /**
  118. * Affiche la page d'accueil.
  119. */
  120. public function actionIndex()
  121. {
  122. return $this->render('index');
  123. }
  124. public function actionService()
  125. {
  126. return $this->render('service', [
  127. 'producerDemoAccount' => $this->getProducerManager()->findOneProducerDemoAccount(),
  128. 'dataProviderPrices' => $this->getDataProviderPrices()
  129. ]);
  130. }
  131. public function getDataProviderPrices()
  132. {
  133. return new ActiveDataProvider([
  134. 'query' => $this->getProducerPriceRangeManager()->queryProducerPriceRanges()->query(),
  135. 'pagination' => [
  136. 'pageSize' => 100,
  137. ],
  138. ]);
  139. }
  140. /**
  141. * Liste les producteurs utilisant la plateforme.
  142. */
  143. public function actionProducers()
  144. {
  145. $dataProviderProducers = new ActiveDataProvider([
  146. 'query' => $this->getProducerManager()->queryProducersActive()->query(),
  147. 'pagination' => [
  148. 'pageSize' => 100,
  149. ],
  150. ]);
  151. return $this->render('producers', [
  152. 'dataProviderProducers' => $dataProviderProducers,
  153. 'producersArray' => $this->getProducerManager()->findProducersActive()
  154. ]);
  155. }
  156. public function actionAbout()
  157. {
  158. $aboutFewNumbers = Yii::$app->cache->getOrSet('about_few_numbers2', function () {
  159. $producerManager = $this->getProducerManager();
  160. $pointSaleManager = $this->getPointSaleManager();
  161. $userManager = $this->getUserManager();
  162. $orderManager = $this->getOrderManager();
  163. $countProducersActive = $producerManager->countProducersActiveWithTurnover();
  164. $countPointSalesActive = $pointSaleManager->countPointSalesActiveLastThreeMonths();
  165. $countUsersActive = $userManager->countUsersActiveLastThreeMonths();
  166. $averageOrdersPerDay = $orderManager->countGlobalUserOrdersAverageLastSevenDays();
  167. $averageTurnover = $orderManager->getAverageTurnoverLastThreeMonths();
  168. $resultMatomoApiVisitSummary = json_decode(file_get_contents(Yii::$app->params['matomoApiVisitSummaryUrl']));
  169. $numberVisitsMonth = $resultMatomoApiVisitSummary->nb_uniq_visitors;
  170. return $this->renderPartial('_about_few_numbers', [
  171. 'countProducersActive' => $countProducersActive,
  172. 'countPointSalesActive' => $countPointSalesActive,
  173. 'countUsersActive' => $countUsersActive,
  174. 'averageOrdersPerDay' => $averageOrdersPerDay,
  175. 'averageTurnover' => $averageTurnover,
  176. 'numberVisitsMonth' => $numberVisitsMonth
  177. ]);
  178. }, 60 * 60 * 24);
  179. return $this->render('about', [
  180. 'aboutFewNumbers' => $aboutFewNumbers
  181. ]);
  182. }
  183. public function actionSourceCode()
  184. {
  185. return $this->render('source_code');
  186. }
  187. /**
  188. * Liste les producteurs utilisant la plateforme.
  189. */
  190. public function actionAjaxProducers()
  191. {
  192. \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
  193. $producersArray = $this->getProducerManager()->findProducersActive();
  194. $producersArrayReturn = [];
  195. foreach($producersArray as $producer) {
  196. $producersArrayReturn[] = [
  197. 'id' => $producer->id,
  198. 'name' => Html::encode($producer->name),
  199. 'type' => Html::encode($producer->type),
  200. 'address' => Html::encode($producer->postcode.' '.$producer->city),
  201. 'latitude' => $producer->latitude,
  202. 'longitude' => $producer->longitude,
  203. 'link' => $this->getUrlManagerProducer()->createAbsoluteUrl(['site/index', 'slug_producer' => $producer->slug])
  204. ];
  205. }
  206. return $producersArrayReturn;
  207. }
  208. /**
  209. * Affiche la page de connexion et traite le formulaire de connexion.
  210. */
  211. public function actionLogin()
  212. {
  213. if (!\Yii::$app->user->isGuest) {
  214. return \Yii::$app->getResponse()->redirect(['site/index']);
  215. }
  216. $model = new LoginForm();
  217. if ($model->load(Yii::$app->request->post()) && $model->login()) {
  218. $returnUrl = \Yii::$app->request->get('return_url');
  219. if ($returnUrl) {
  220. return $this->redirect($returnUrl);
  221. }
  222. else {
  223. $userProducerArray = $this->getUserProducerManager()->findUserProducersByUser(GlobalParam::getCurrentUser());
  224. if ($userProducerArray
  225. && is_array($userProducerArray)
  226. && count($userProducerArray) == 1) {
  227. $urlRedirect = $this->getUrlManagerProducer()
  228. ->createAbsoluteUrl([
  229. 'site/index',
  230. 'slug_producer' => $userProducerArray[0]->producer->slug
  231. ]);
  232. return $this->redirect($urlRedirect);
  233. }
  234. else {
  235. return $this->goBack();
  236. }
  237. }
  238. } else {
  239. return $this->render('@frontend/views/site/login', [
  240. 'model' => $model,
  241. ]);
  242. }
  243. }
  244. /**
  245. * Déconnecte l'utilisateur.
  246. */
  247. public function actionLogout()
  248. {
  249. \Yii::$app->user->logout();
  250. return $this->goHome();
  251. }
  252. /**
  253. * Affiche la page de contact et traite le formulaire s'il est soumis.
  254. */
  255. public function actionContact()
  256. {
  257. $model = new ContactForm();
  258. if ($model->load(Yii::$app->request->post()) && $model->validate()) {
  259. if ($model->sendEmail(Yii::$app->params['adminEmail'])) {
  260. $this->setFlash('success', 'Votre message a bien été envoyé. Nous vous répondrons dès que possible.');
  261. }
  262. else {
  263. $this->setFlash('error', 'Il y a eu une erreur lors de l\'envoi de votre message.');
  264. }
  265. return $this->refresh();
  266. }
  267. else {
  268. return $this->render('contact', [
  269. 'model' => $model,
  270. ]);
  271. }
  272. }
  273. /**
  274. * Affiche la page d'inscription et traite son formulaire.
  275. */
  276. public function actionSignup()
  277. {
  278. $model = new SignupForm();
  279. $producerManager = $this->getProducerManager();
  280. if ($model->load(Yii::$app->request->post())) {
  281. $user = $model->signup();
  282. if ($user && Yii::$app->getUser()->login($user)) {
  283. if ($model->isProducer()) {
  284. $this->redirect(['site/signup-confirm']);
  285. }
  286. else {
  287. $producer = $producerManager->findOneProducerById($model->id_producer);
  288. if ($producer) {
  289. $this->redirect(['site/signup-confirm', 'idProducerRedirect' => $producer->id]);
  290. }
  291. else {
  292. $this->redirect(['site/index']);
  293. }
  294. }
  295. }
  296. }
  297. // Liste des producteurs disponibles
  298. $producersArray = $producerManager->populateProducerDropdown();
  299. $dataProducers = $producersArray['data'];
  300. $optionsProducers = $producersArray['options'];
  301. return $this->render('signup', [
  302. 'model' => $model,
  303. 'dataProducers' => $dataProducers,
  304. 'dataProviderPrices' => $this->getDataProviderPrices(),
  305. 'optionsProducers' => $optionsProducers,
  306. ]);
  307. }
  308. public function actionSignupConfirm($idProducerRedirect = null)
  309. {
  310. $producerManager = $this->getProducerManager();
  311. $user = $this->getUserCurrent();
  312. $producerRedirect = $idProducerRedirect ? $producerManager->findOneProducerById($idProducerRedirect) : null ;
  313. if(!$user) {
  314. throw new NotFoundHttpException('Page introuvable');
  315. }
  316. return $this->render('signup_confirm', [
  317. 'user' => $user,
  318. 'producerRedirect' => $producerRedirect
  319. ]);
  320. }
  321. /**
  322. * Affiche la page de demande de nouveau mot de passe.
  323. * Traitement du formulaire.
  324. */
  325. public function actionRequestPasswordReset()
  326. {
  327. $model = new PasswordResetRequestForm();
  328. if ($model->load(Yii::$app->request->post()) && $model->validate()) {
  329. if ($model->sendEmail()) {
  330. $this->setFlash('success', 'Un lien vous permettant de réinitialiser votre mot de passe
  331. vient d\'être envoyé sur votre boîte mail.');
  332. return $this->goHome();
  333. }
  334. else {
  335. $this->setFlash('error', 'Sorry, we are unable to reset password for email provided.');
  336. }
  337. }
  338. return $this->render('requestPasswordResetToken', [
  339. 'model' => $model,
  340. ]);
  341. }
  342. /**
  343. * Met à jour le mot de passe de l'utilisateur.
  344. */
  345. public function actionResetPassword($token)
  346. {
  347. try {
  348. $model = new ResetPasswordForm($token);
  349. } catch (InvalidParamException $e) {
  350. throw new BadRequestHttpException($e->getMessage());
  351. }
  352. if ($model->load($this->getRequest()->post())
  353. && $model->validate()
  354. && $model->resetPassword()) {
  355. $this->setFlash('success', 'Votre nouveau mot de passe vient d\'être sauvegardé.');
  356. return $this->goHome();
  357. }
  358. return $this->render('resetPassword', [
  359. 'model' => $model,
  360. ]);
  361. }
  362. /**
  363. * Affiche le formulaire de demande de code pour accéder à certains producteurs.
  364. */
  365. public function actionProducerCode(int $id)
  366. {
  367. $producerManager = $this->getProducerManager();
  368. $producer = $producerManager->findOneProducerById($id);
  369. if (!$producer) {
  370. throw new \yii\web\HttpException(404, 'Producteur introuvable');
  371. }
  372. $producerCodeForm = new ProducerCodeForm();
  373. $producerCodeForm->id_producer = $id;
  374. if ($producerCodeForm->load($this->getRequest()->post())
  375. && $producerCodeForm->validate()) {
  376. $this->getLogic()->setProducerContext($producer);
  377. $producerManager->addUser(GlobalParam::getCurrentUser(), $producer);
  378. $this->redirect($this->getUrlManagerProducer()->createAbsoluteUrl(['site/index', 'slug_producer' => $producer->slug]));
  379. }
  380. return $this->render('producer_code', [
  381. 'producer' => $producer,
  382. 'producerCodeForm' => $producerCodeForm,
  383. ]);
  384. }
  385. /**
  386. * Affiche la page de connexion / inscription pour accéder notamment au
  387. * formulaire de commande des producteurs.
  388. */
  389. public function actionProducer(int $id)
  390. {
  391. $loginForm = new LoginForm();
  392. $signupForm = new SignupForm();
  393. $producerManager = $this->getProducerManager();
  394. $producer = $producerManager->findOneProducerById($id);
  395. $this->getLogic()->setProducerContext($producer);
  396. $loginForm->id_producer = $id;
  397. $signupForm->id_producer = $id;
  398. $signupForm->option_user_producer = 'user';
  399. $returnUrl = $this->getRequest()->get('returnUrl', $this->getUrlManagerProducer()->createAbsoluteUrl(['site/index', 'slug_producer' => $producer->slug]));
  400. if (Yii::$app->user->isGuest) {
  401. if ($loginForm->load($this->getRequest()->post()) && $loginForm->login()) {
  402. if (!strlen($producer->code)) {
  403. $producerManager->addUser(GlobalParam::getCurrentUser(), $producer);
  404. }
  405. $this->redirect($returnUrl);
  406. }
  407. if ($signupForm->load($this->getRequest()->post())
  408. && ($user = $signupForm->signup())
  409. && Yii::$app->user->login($user)) {
  410. $this->redirect($returnUrl);
  411. }
  412. }
  413. else {
  414. $this->redirect($returnUrl);
  415. }
  416. return $this->render('producer', [
  417. 'loginForm' => $loginForm,
  418. 'signupForm' => $signupForm,
  419. 'producer' => $producer,
  420. ]);
  421. }
  422. /**
  423. * Indique à l'utilisateur que l'espace d'un producteur est hors ligne.
  424. */
  425. public function actionProducerOffline(int $id)
  426. {
  427. return $this->render('producer_offline', [
  428. 'producer' => $this->getProducerManager()->findOneProducerById($id),
  429. ]);
  430. }
  431. /**
  432. * Affiche les mentions légales.
  433. */
  434. public function actionMentions()
  435. {
  436. return $this->render('mentions');
  437. }
  438. /**
  439. * Affiche les conditions générale de service.
  440. */
  441. public function actionCgv()
  442. {
  443. return $this->render('cgv');
  444. }
  445. /**
  446. * Affiche les précisions concernant l'utilisation du crédit.
  447. */
  448. public function actionCredit()
  449. {
  450. return $this->render('credit');
  451. }
  452. }