src/Manager/CustomerManager.php line 68

Open in your IDE?
  1. <?php
  2. namespace App\Manager;
  3. use App\Entity\Customer;
  4. use App\Entity\Address;
  5. use App\Entity\CustomerLoginToken;
  6. use App\Entity\PriceGroup;
  7. class CustomerManager {
  8. private $session;
  9. private $mailer;
  10. private $em;
  11. private $key = "SDflkfoRE5459Z_çà#è79=/";
  12. public function __construct(\Symfony\Component\HttpFoundation\Session\SessionInterface $session, \Doctrine\ORM\EntityManagerInterface $em, \App\Service\Mailer $mailer)
  13. {
  14. $this->session = $session;
  15. $this->em = $em;
  16. $this->mailer = $mailer;
  17. $this->cart = null;
  18. }
  19. public function getCustomer()
  20. {
  21. $id = $this->session->get('customer_id');
  22. if(!empty($id)){
  23. $customer = $this->em->getRepository('App:Customer')->find($id);
  24. if(!empty($customer)){
  25. if($this->checkToken($customer)){
  26. return $customer;
  27. }
  28. }
  29. }
  30. return false;
  31. }
  32. public function getCustomerCountry()
  33. {
  34. $customer = $this->getCustomer();
  35. if($customer){
  36. $defaultAddress = $customer->getDefaultAddress();
  37. if($defaultAddress){
  38. return $defaultAddress->getCountry();
  39. }
  40. }
  41. return false;
  42. }
  43. public function getPriceContext(): PriceGroup
  44. {
  45. $code = $this->session->get('customer_price_context', PriceGroup::CODE_VIVOG);
  46. return $this->em->getRepository(PriceGroup::class)->findOneByCode($code);
  47. }
  48. public function setPriceContext(PriceGroup $priceGroup)
  49. {
  50. $customer = $this->getCustomer();
  51. if(empty($customer) || !$this->hasPriceContext($priceGroup)){
  52. throw new \App\Exception\PriceGroupException();
  53. }
  54. $this->session->set('customer_price_context',$priceGroup->getCode());
  55. }
  56. public function isExpert()
  57. {
  58. $currentPriceGroup = $this->session->get('customer_price_context', false);
  59. return $currentPriceGroup === PriceGroup::CODE_EXPERT;
  60. }
  61. public function hasExpertContext()
  62. {
  63. $customer = $this->getCustomer();
  64. foreach($customer->getPriceGroups() as $priceGroup) {
  65. if($priceGroup->getGroup()->getCode() == PriceGroup::CODE_EXPERT)
  66. return true;
  67. }
  68. return false;
  69. }
  70. public function hasPriceContext(PriceGroup $priceGroup)
  71. {
  72. $customer = $this->getCustomer();
  73. foreach($customer->getPriceGroups() as $cPriceGroup) {
  74. if($cPriceGroup->getGroup() == $priceGroup)
  75. return true;
  76. }
  77. return false;
  78. }
  79. public function initCustomerSession(&$customer)
  80. {
  81. $this->updateLastLogin($customer);
  82. $this->session->set('customer_id',$customer->getId());
  83. $this->session->set('customer_email',$customer->getEmail());
  84. $this->session->set('customer_token',$this->getToken($customer));
  85. }
  86. protected function updateLastLogin(Customer $customer)
  87. {
  88. $customer->setLastLogin(new \DateTime);
  89. $nbLogin = $customer->getNbLogin()+1;
  90. $customer->setNbLogin($nbLogin);
  91. $this->em->persist($customer);
  92. $this->em->flush();
  93. }
  94. public function login($user,$pwd)
  95. {
  96. $customer = $this->em->getRepository('App:Customer')->findOneBy(array(
  97. 'email'=>$user
  98. ));
  99. if(!empty($customer)){
  100. if($this->checkPassword($pwd, $customer->getPassword())){
  101. $priceGroups = $customer->getPriceGroups();
  102. if(count($priceGroups) == 0) {
  103. throw new \App\Exception\PriceGroupException();
  104. }
  105. $this->initCustomerSession($customer);
  106. return $customer;
  107. }
  108. }
  109. return false;
  110. }
  111. public function checkLogin($user,$pwd)
  112. {
  113. $customer = $this->em->getRepository('App:Customer')->findOneBy(array(
  114. 'email'=>$user
  115. ));
  116. if(!empty($customer)){
  117. return $this->checkPassword($pwd, $customer->getPassword());
  118. }
  119. return false;
  120. }
  121. public function generateLoginToken(Customer $customer)
  122. {
  123. $code = \App\Helpers\Encoder::getRandomDigit(4);
  124. $token = new CustomerLoginToken();
  125. $token->setCustomer($customer);
  126. $token->setToken($this->getLoginToken($code));
  127. }
  128. protected function getLoginToken($code)
  129. {
  130. return md5($code.CustomerLoginToken::$KEY);
  131. }
  132. public function checkCustomerLoginToken(Customer $customer, $code)
  133. {
  134. $code = \App\Helpers\Encoder::getRandomDigit(4);
  135. $token = new CustomerLoginToken();
  136. $token->setCustomer($customer);
  137. $token->setToken($this->getLoginToken($code));
  138. }
  139. public function register($data, $locale = "fr")
  140. {
  141. $customer = $this->em->getRepository('App:Customer')->findOneBy(array('email'=>$data['email']));
  142. if(!empty($customer)){
  143. $this->session->getFlashBag()->add('error', 'Un compte utilisateur utilise déjà cette adresse email : '.$data['email']);
  144. return false;
  145. }
  146. $defaultGroup = $this->em->getRepository('App:CustomerGroup')->find(1);
  147. $customer = new \App\Entity\Customer();
  148. $customer->setGroup($defaultGroup);
  149. $customer->setEmailAddress($data['email']);
  150. $customer->setGender($data['address']->getGender());
  151. $customer->setFirstname($data['address']->getFirstName());
  152. $customer->setLastname($data['address']->getLastName());
  153. $customer->setTelephone($data['address']->getPhone());
  154. $customer->setPassword($this->encryptPassword($data['plainPassword']));
  155. // $customer->setNewsletter($data['newsletter']);
  156. //$customer->setPassword(hex2bin($this->encryptPassword($data['plainPassword'])));
  157. $customer->setCompany($data['company']);
  158. $customer->setSiret($data['siret']);
  159. $customer->setTva($data['tva']);
  160. // $customer->setElevage($data['elevage']);
  161. $customer->setMetier($data['metier']);
  162. $language = $this->em->getRepository('App:Language')->findOneByCode($locale);
  163. $customer->setLanguage($language);
  164. $customer->setCreation(new \DateTime);
  165. $customer->setStatus(Customer::STATUS_WAITING);
  166. $customer->setExcluTva(0);
  167. $this->em->persist($customer);
  168. $this->em->flush();
  169. if(isset($data['address'])){
  170. $address = new Address();
  171. $address->setGender($data['address']->getGender());
  172. $address->setFirstname($data['address']->getFirstName());
  173. $address->setLastname($data['address']->getLastName());
  174. $address->setCompany($data['address']->getCompany());
  175. $address->setAddress1($data['address']->getAddress1());
  176. $address->setAddress2($data['address']->getAddress2());
  177. $address->setPostcode($data['address']->getPostcode());
  178. $address->setCity($data['address']->getCity());
  179. $address->setCountry($data['address']->getCountry());
  180. $address->setPhone($data['address']->getPhone());
  181. $address->setCustomer($customer);
  182. $this->em->persist($address);
  183. $customer->setDefaultAddress($address);
  184. $this->em->persist($customer);
  185. $this->em->flush();
  186. }
  187. // $this->mailer->sendAccountConfirmation($customer, $locale);
  188. $customerPrice = new \App\Entity\CustomerPriceGroup();
  189. $customerPrice->setCustomer($customer);
  190. if($data['expert']) {
  191. $priceGroup = $this->em->getRepository(PriceGroup::class)->findOneByCode(PriceGroup::CODE_EXPERT);
  192. $customerPrice->setSapId($data['expertId']);
  193. }else{
  194. $priceGroup = $this->em->getRepository(PriceGroup::class)->findOneByCode(PriceGroup::CODE_VIVOG);
  195. }
  196. $customerPrice->setGroup($priceGroup);
  197. $this->em->persist($customerPrice);
  198. $this->em->flush();
  199. $this->em->refresh($customer);
  200. // $this->setPriceContext($priceGroup);
  201. $this->mailer->notifyRegistration($customer);
  202. $this->initCustomerSession($customer);
  203. return $customer;
  204. }
  205. public function delete(Customer $customer)
  206. {
  207. try{
  208. $this->em->remove($customer);
  209. $this->em->flush();
  210. } catch (\Exception $ex) {
  211. return false;
  212. }
  213. return true;
  214. }
  215. public function checkPassword(string $plain, string $encrypted)
  216. {
  217. if (!empty($plain) && !empty($encrypted)) {
  218. $stack = explode(':', $encrypted);
  219. if (sizeof($stack) != 2) return false;
  220. return md5($stack[1] . $plain) == $stack[0];
  221. }
  222. return false;
  223. }
  224. public function encryptPassword($plain)
  225. {
  226. $salt = substr(md5($plain), 0, 2);
  227. return md5($salt.$plain).':'.$salt;
  228. }
  229. public function renewPassword($email, $locale)
  230. {
  231. $customer = $this->em->getRepository('App:Customer')->findOneByEmail($email);
  232. if(empty($customer)){
  233. return "Aucun compte client ne correspond à l'email saisi.";
  234. }else{
  235. $pwd = $this->generatePassword();
  236. $customer->setPassword($this->encryptPassword($pwd));
  237. try{
  238. $this->mailer->sendPassword($customer,$pwd,$locale);
  239. $this->em->persist($customer);
  240. $this->em->flush();
  241. return true;
  242. } catch (Exception $ex) {
  243. return "Erreur lors de la génération du mot de passe";
  244. return $ex->getMessage();
  245. }
  246. }
  247. return false;
  248. }
  249. private function generatePassword($length=8)
  250. {
  251. //$chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
  252. $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
  253. $count = mb_strlen($chars);
  254. for ($i = 0, $result = ''; $i < $length; $i++) {
  255. $index = rand(0, $count - 1);
  256. $result .= mb_substr($chars, $index, 1);
  257. }
  258. return $result;
  259. }
  260. public function changePassword(Customer $customer, $currentPwd, $newPwd)
  261. {
  262. if($this->checkPassword($currentPwd, $customer->getPassword())){
  263. $customer->setPassword($this->encryptPassword($newPwd));
  264. $this->em->persist($customer);
  265. $this->em->flush();
  266. return true;
  267. }
  268. return "Mot de passe incorrect";
  269. }
  270. public function logout()
  271. {
  272. // $this->log('déconnexion');
  273. $this->session->remove('customer_id');
  274. $this->session->remove('customer_fullname');
  275. $this->session->remove('customer_email');
  276. $this->session->remove('customer_token');
  277. $this->session->remove('customer_price_context');
  278. }
  279. public function isLogged() {
  280. $customer = $this->getCustomer();
  281. return $customer != false;
  282. }
  283. public function isElite() {
  284. $customer = $this->getCustomer();
  285. return $customer && $customer->hasEliteDiscount();
  286. }
  287. public function log($action='')
  288. {
  289. $customer = $this->getCustomer();
  290. if($customer===false)
  291. return;
  292. $log = new \App\Entity\CustomerLog();
  293. $log->setCustomer($customer);
  294. $log->setDate(new \DateTime());
  295. $log->setAction($action);
  296. $this->em->persist($log);
  297. $this->em->flush();
  298. }
  299. private function getToken(\App\Entity\Customer $customer)
  300. {
  301. return md5($customer->getId()."-".$customer->getEmail()."-".$this->key);
  302. }
  303. private function checkToken(\App\Entity\Customer $customer)
  304. {
  305. return $this->session->get('customer_token') === $this->getToken($customer);
  306. }
  307. /**
  308. * Colonne 1 = Code client Synoptic
  309. * Colonne 2 = Nom réduit
  310. * Colonne 3 = Raison sociale
  311. * Colonne 4 = Code tarif du client
  312. * Colonne 5 = Code remise du client
  313. */
  314. public function importDiscountFromCsv($csvFile) {
  315. if(!file_exists($csvFile))
  316. throw new \Exception('File not found');
  317. if (($handle = fopen($csvFile, "r")) !== FALSE) {
  318. $row = 0;
  319. while (($data = fgetcsv($handle, null, ";")) !== FALSE) {
  320. $customers = $this->em->getRepository('App:Customer')->findBySynopticId($data[0]);
  321. foreach($customers as $customer){
  322. $customer->setPriceCode($data[3]);
  323. $customer->setDiscountCode($data[4]);
  324. $this->em->persist($customer);
  325. $this->em->flush();
  326. }
  327. }
  328. fclose($handle);
  329. }
  330. }
  331. public function canSeePrices() {
  332. if(!$this->isLogged())
  333. return false;
  334. $customer = $this->getCustomer();
  335. $status = $customer->getStatus();
  336. return empty($status) || $status == Customer::STATUS_VALIDATED;
  337. }
  338. public function validate(Customer $customer, bool $test) {
  339. $value = $test ? Customer::STATUS_VALIDATED : Customer::STATUS_BLOCKED;
  340. $customer->setStatus($value);
  341. $this->em->persist($customer);
  342. $this->em->flush();
  343. $this->em->refresh($customer);
  344. $this->mailer->sendCustomerValidation($customer);
  345. }
  346. public function anonymize(Customer $customer) {
  347. $customer->setFirstname('anonyme');
  348. $customer->setLastname('anonyme');
  349. $customer->setEmailAddress(uniqid().'@vivog.fr');
  350. $customer->setCompany('anonyme');
  351. $this->em->persist($customer);
  352. $this->em->flush();
  353. }
  354. }