<?php
namespace App\Manager;
use App\Entity\Customer;
use App\Entity\Address;
use App\Entity\CustomerLoginToken;
use App\Entity\PriceGroup;
class CustomerManager {
private $session;
private $mailer;
private $em;
private $key = "SDflkfoRE5459Z_çà#è79=/";
public function __construct(\Symfony\Component\HttpFoundation\Session\SessionInterface $session, \Doctrine\ORM\EntityManagerInterface $em, \App\Service\Mailer $mailer)
{
$this->session = $session;
$this->em = $em;
$this->mailer = $mailer;
$this->cart = null;
}
public function getCustomer()
{
$id = $this->session->get('customer_id');
if(!empty($id)){
$customer = $this->em->getRepository('App:Customer')->find($id);
if(!empty($customer)){
if($this->checkToken($customer)){
return $customer;
}
}
}
return false;
}
public function getCustomerCountry()
{
$customer = $this->getCustomer();
if($customer){
$defaultAddress = $customer->getDefaultAddress();
if($defaultAddress){
return $defaultAddress->getCountry();
}
}
return false;
}
public function getPriceContext(): PriceGroup
{
$code = $this->session->get('customer_price_context', PriceGroup::CODE_VIVOG);
return $this->em->getRepository(PriceGroup::class)->findOneByCode($code);
}
public function setPriceContext(PriceGroup $priceGroup)
{
$customer = $this->getCustomer();
if(empty($customer) || !$this->hasPriceContext($priceGroup)){
throw new \App\Exception\PriceGroupException();
}
$this->session->set('customer_price_context',$priceGroup->getCode());
}
public function isExpert()
{
$currentPriceGroup = $this->session->get('customer_price_context', false);
return $currentPriceGroup === PriceGroup::CODE_EXPERT;
}
public function hasExpertContext()
{
$customer = $this->getCustomer();
foreach($customer->getPriceGroups() as $priceGroup) {
if($priceGroup->getGroup()->getCode() == PriceGroup::CODE_EXPERT)
return true;
}
return false;
}
public function hasPriceContext(PriceGroup $priceGroup)
{
$customer = $this->getCustomer();
foreach($customer->getPriceGroups() as $cPriceGroup) {
if($cPriceGroup->getGroup() == $priceGroup)
return true;
}
return false;
}
public function initCustomerSession(&$customer)
{
$this->updateLastLogin($customer);
$this->session->set('customer_id',$customer->getId());
$this->session->set('customer_email',$customer->getEmail());
$this->session->set('customer_token',$this->getToken($customer));
}
protected function updateLastLogin(Customer $customer)
{
$customer->setLastLogin(new \DateTime);
$nbLogin = $customer->getNbLogin()+1;
$customer->setNbLogin($nbLogin);
$this->em->persist($customer);
$this->em->flush();
}
public function login($user,$pwd)
{
$customer = $this->em->getRepository('App:Customer')->findOneBy(array(
'email'=>$user
));
if(!empty($customer)){
if($this->checkPassword($pwd, $customer->getPassword())){
$priceGroups = $customer->getPriceGroups();
if(count($priceGroups) == 0) {
throw new \App\Exception\PriceGroupException();
}
$this->initCustomerSession($customer);
return $customer;
}
}
return false;
}
public function checkLogin($user,$pwd)
{
$customer = $this->em->getRepository('App:Customer')->findOneBy(array(
'email'=>$user
));
if(!empty($customer)){
return $this->checkPassword($pwd, $customer->getPassword());
}
return false;
}
public function generateLoginToken(Customer $customer)
{
$code = \App\Helpers\Encoder::getRandomDigit(4);
$token = new CustomerLoginToken();
$token->setCustomer($customer);
$token->setToken($this->getLoginToken($code));
}
protected function getLoginToken($code)
{
return md5($code.CustomerLoginToken::$KEY);
}
public function checkCustomerLoginToken(Customer $customer, $code)
{
$code = \App\Helpers\Encoder::getRandomDigit(4);
$token = new CustomerLoginToken();
$token->setCustomer($customer);
$token->setToken($this->getLoginToken($code));
}
public function register($data, $locale = "fr")
{
$customer = $this->em->getRepository('App:Customer')->findOneBy(array('email'=>$data['email']));
if(!empty($customer)){
$this->session->getFlashBag()->add('error', 'Un compte utilisateur utilise déjà cette adresse email : '.$data['email']);
return false;
}
$defaultGroup = $this->em->getRepository('App:CustomerGroup')->find(1);
$customer = new \App\Entity\Customer();
$customer->setGroup($defaultGroup);
$customer->setEmailAddress($data['email']);
$customer->setGender($data['address']->getGender());
$customer->setFirstname($data['address']->getFirstName());
$customer->setLastname($data['address']->getLastName());
$customer->setTelephone($data['address']->getPhone());
$customer->setPassword($this->encryptPassword($data['plainPassword']));
// $customer->setNewsletter($data['newsletter']);
//$customer->setPassword(hex2bin($this->encryptPassword($data['plainPassword'])));
$customer->setCompany($data['company']);
$customer->setSiret($data['siret']);
$customer->setTva($data['tva']);
$customer->setElevage($data['elevage']);
$customer->setMetier($data['metier']);
$language = $this->em->getRepository('App:Language')->findOneByCode($locale);
$customer->setLanguage($language);
$customer->setCreation(new \DateTime);
$customer->setStatus(Customer::STATUS_WAITING);
$this->em->persist($customer);
$this->em->flush();
if(isset($data['address'])){
$address = new Address();
$address->setGender($data['address']->getGender());
$address->setFirstname($data['address']->getFirstName());
$address->setLastname($data['address']->getLastName());
$address->setCompany($data['address']->getCompany());
$address->setAddress1($data['address']->getAddress1());
$address->setAddress2($data['address']->getAddress2());
$address->setPostcode($data['address']->getPostcode());
$address->setCity($data['address']->getCity());
$address->setCountry($data['address']->getCountry());
$address->setPhone($data['address']->getPhone());
$address->setCustomer($customer);
$this->em->persist($address);
$customer->setDefaultAddress($address);
$this->em->persist($customer);
$this->em->flush();
}
// $this->mailer->sendAccountConfirmation($customer, $locale);
$customerPrice = new \App\Entity\CustomerPriceGroup();
$customerPrice->setCustomer($customer);
if($data['expert']) {
$priceGroup = $this->em->getRepository(PriceGroup::class)->findOneByCode(PriceGroup::CODE_EXPERT);
$customerPrice->setSapId($data['expertId']);
}else{
$priceGroup = $this->em->getRepository(PriceGroup::class)->findOneByCode(PriceGroup::CODE_VIVOG);
}
$customerPrice->setGroup($priceGroup);
$this->em->persist($customerPrice);
$this->em->flush();
$this->em->refresh($customer);
// $this->setPriceContext($priceGroup);
$this->mailer->notifyRegistration($customer);
$this->initCustomerSession($customer);
return $customer;
}
public function delete(Customer $customer)
{
try{
$this->em->remove($customer);
$this->em->flush();
} catch (\Exception $ex) {
return false;
}
return true;
}
public function checkPassword(string $plain, string $encrypted)
{
if (!empty($plain) && !empty($encrypted)) {
$stack = explode(':', $encrypted);
if (sizeof($stack) != 2) return false;
return md5($stack[1] . $plain) == $stack[0];
}
return false;
}
public function encryptPassword($plain)
{
$salt = substr(md5($plain), 0, 2);
return md5($salt.$plain).':'.$salt;
}
public function renewPassword($email, $locale)
{
$customer = $this->em->getRepository('App:Customer')->findOneByEmail($email);
if(empty($customer)){
return "Aucun compte client ne correspond à l'email saisi.";
}else{
$pwd = $this->generatePassword();
$customer->setPassword($this->encryptPassword($pwd));
try{
$this->mailer->sendPassword($customer,$pwd,$locale);
$this->em->persist($customer);
$this->em->flush();
return true;
} catch (Exception $ex) {
return "Erreur lors de la génération du mot de passe";
return $ex->getMessage();
}
}
return false;
}
private function generatePassword($length=8)
{
//$chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
$chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
$count = mb_strlen($chars);
for ($i = 0, $result = ''; $i < $length; $i++) {
$index = rand(0, $count - 1);
$result .= mb_substr($chars, $index, 1);
}
return $result;
}
public function changePassword(Customer $customer, $currentPwd, $newPwd)
{
if($this->checkPassword($currentPwd, $customer->getPassword())){
$customer->setPassword($this->encryptPassword($newPwd));
$this->em->persist($customer);
$this->em->flush();
return true;
}
return "Mot de passe incorrect";
}
public function logout()
{
// $this->log('déconnexion');
$this->session->remove('customer_id');
$this->session->remove('customer_fullname');
$this->session->remove('customer_email');
$this->session->remove('customer_token');
}
public function isLogged() {
$customer = $this->getCustomer();
return $customer != false;
}
public function isElite() {
$customer = $this->getCustomer();
return $customer && $customer->hasEliteDiscount();
}
public function log($action='')
{
$customer = $this->getCustomer();
if($customer===false)
return;
$log = new \App\Entity\CustomerLog();
$log->setCustomer($customer);
$log->setDate(new \DateTime());
$log->setAction($action);
$this->em->persist($log);
$this->em->flush();
}
private function getToken(\App\Entity\Customer $customer)
{
return md5($customer->getId()."-".$customer->getEmail()."-".$this->key);
}
private function checkToken(\App\Entity\Customer $customer)
{
return $this->session->get('customer_token') === $this->getToken($customer);
}
/**
* Colonne 1 = Code client Synoptic
* Colonne 2 = Nom réduit
* Colonne 3 = Raison sociale
* Colonne 4 = Code tarif du client
* Colonne 5 = Code remise du client
*/
public function importDiscountFromCsv($csvFile) {
if(!file_exists($csvFile))
throw new \Exception('File not found');
if (($handle = fopen($csvFile, "r")) !== FALSE) {
$row = 0;
while (($data = fgetcsv($handle, null, ";")) !== FALSE) {
$customers = $this->em->getRepository('App:Customer')->findBySynopticId($data[0]);
foreach($customers as $customer){
$customer->setPriceCode($data[3]);
$customer->setDiscountCode($data[4]);
$this->em->persist($customer);
$this->em->flush();
}
}
fclose($handle);
}
}
public function canSeePrices() {
if(!$this->isLogged())
return false;
$customer = $this->getCustomer();
$status = $customer->getStatus();
return empty($status) || $status == Customer::STATUS_VALIDATED;
}
public function validate(Customer $customer, bool $test) {
$value = $test ? Customer::STATUS_VALIDATED : Customer::STATUS_BLOCKED;
$customer->setStatus($value);
$this->em->persist($customer);
$this->em->flush();
$this->em->refresh($customer);
$this->mailer->sendCustomerValidation($customer);
}
public function anonymize(Customer $customer) {
$customer->setFirstname('anonyme');
$customer->setLastname('anonyme');
$customer->setEmailAddress(uniqid().'@vivog.fr');
$customer->setCompany('anonyme');
$this->em->persist($customer);
$this->em->flush();
}
}