src/Eccube/Repository/CustomerRepository.php line 84

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of EC-CUBE
  4.  *
  5.  * Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved.
  6.  *
  7.  * http://www.ec-cube.co.jp/
  8.  *
  9.  * For the full copyright and license information, please view the LICENSE
  10.  * file that was distributed with this source code.
  11.  */
  12. namespace Eccube\Repository;
  13. use Doctrine\ORM\EntityManagerInterface;
  14. use Doctrine\ORM\QueryBuilder;
  15. use Doctrine\Persistence\ManagerRegistry as RegistryInterface;
  16. use Eccube\Common\EccubeConfig;
  17. use Eccube\Doctrine\Query\Queries;
  18. use Eccube\Entity\Customer;
  19. use Eccube\Entity\Master\CustomerStatus;
  20. use Eccube\Entity\Master\OrderStatus;
  21. use Eccube\Entity\Master\Pref;
  22. use Eccube\Entity\Master\Sex;
  23. use Eccube\Util\StringUtil;
  24. use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface;
  25. /**
  26.  * CustomerRepository
  27.  *
  28.  * This class was generated by the Doctrine ORM. Add your own custom
  29.  * repository methods below.
  30.  */
  31. class CustomerRepository extends AbstractRepository
  32. {
  33.     /**
  34.      * @var Queries
  35.      */
  36.     protected $queries;
  37.     /**
  38.      * @var EntityManagerInterface
  39.      */
  40.     protected $entityManager;
  41.     /**
  42.      * @var OrderRepository
  43.      */
  44.     protected $orderRepository;
  45.     /**
  46.      * @var EccubeConfig
  47.      */
  48.     protected $eccubeConfig;
  49.     /**
  50.      * @var EncoderFactoryInterface
  51.      */
  52.     protected $encoderFactory;
  53.     public const COLUMNS = [
  54.         'customer_id' => 'c.id''name' => 'c.name01',
  55.     ];
  56.     /**
  57.      * CustomerRepository constructor.
  58.      *
  59.      * @param RegistryInterface $registry
  60.      * @param Queries $queries
  61.      * @param EntityManagerInterface $entityManager
  62.      * @param OrderRepository $orderRepository
  63.      * @param EncoderFactoryInterface $encoderFactory
  64.      * @param EccubeConfig $eccubeConfig
  65.      */
  66.     public function __construct(
  67.         RegistryInterface $registry,
  68.         Queries $queries,
  69.         EntityManagerInterface $entityManager,
  70.         OrderRepository $orderRepository,
  71.         EncoderFactoryInterface $encoderFactory,
  72.         EccubeConfig $eccubeConfig
  73.     ) {
  74.         parent::__construct($registryCustomer::class);
  75.         $this->queries $queries;
  76.         $this->entityManager $entityManager;
  77.         $this->orderRepository $orderRepository;
  78.         $this->encoderFactory $encoderFactory;
  79.         $this->eccubeConfig $eccubeConfig;
  80.     }
  81.     public function newCustomer()
  82.     {
  83.         $CustomerStatus $this->getEntityManager()
  84.             ->find(CustomerStatus::class, CustomerStatus::PROVISIONAL);
  85.         $Customer = new \Eccube\Entity\Customer();
  86.         $Customer
  87.             ->setStatus($CustomerStatus);
  88.         return $Customer;
  89.     }
  90.     /**
  91.      * @param array{
  92.      *         multi?:string,
  93.      *         pref?:Pref,
  94.      *         sex?:Sex[],
  95.      *         birth_month?:string|int,
  96.      *         birth_start?:\DateTime,
  97.      *         birth_end?:\DateTime,
  98.      *         phone_number?:string,
  99.      *         buy_total_start?:string|int,
  100.      *         buy_total_end?:string|int,
  101.      *         buy_times_start?:string|int,
  102.      *         buy_times_end?:string|int,
  103.      *         create_datetime_start?:\DateTime,
  104.      *         create_datetime_end?:\DateTime,
  105.      *         create_date_start?:\DateTime,
  106.      *         create_date_end?:\DateTime,
  107.      *         update_datetime_start?:\DateTime,
  108.      *         update_datetime_end?:\DateTime,
  109.      *         update_date_start?:\DateTime,
  110.      *         update_date_end?:\DateTime,
  111.      *         last_buy_datetime_start?:\DateTime,
  112.      *         last_buy_datetime_end?:\DateTime,
  113.      *         last_buy_start?:\DateTime,
  114.      *         last_buy_end?:\DateTime,
  115.      *         customer_status?:CustomerStatus[],
  116.      *         buy_product_name?:string,
  117.      *         sortkey?:string,
  118.      *         sorttype?:string
  119.      *     } $searchData
  120.      * @return QueryBuilder
  121.      */
  122.     public function getQueryBuilderBySearchData($searchData)
  123.     {
  124.         $qb $this->createQueryBuilder('c')
  125.             ->select('c');
  126.         if (isset($searchData['multi']) && StringUtil::isNotBlank($searchData['multi'])) {
  127.             // スペース除去
  128.             $clean_key_multi preg_replace('/\s+|[ ]+/u'''$searchData['multi']);
  129.             $id preg_match('/^\d{0,10}$/'$clean_key_multi) ? $clean_key_multi null;
  130.             if ($id && $id '2147483647' && $this->isPostgreSQL()) {
  131.                 $id null;
  132.             }
  133.             $qb
  134.                 ->andWhere("c.id = :customer_id OR CONCAT(c.name01, c.name02) LIKE :name OR CONCAT(COALESCE(c.kana01, ''), COALESCE(c.kana02, '')) LIKE :kana OR c.email LIKE :email")
  135.                 ->setParameter('customer_id'$id)
  136.                 ->setParameter('name''%'.$clean_key_multi.'%')
  137.                 ->setParameter('kana''%'.$clean_key_multi.'%')
  138.                 ->setParameter('email''%'.$clean_key_multi.'%');
  139.         }
  140.         // Pref
  141.         if (!empty($searchData['pref']) && $searchData['pref']) {
  142.             $qb
  143.                 ->andWhere('c.Pref = :pref')
  144.                 ->setParameter('pref'$searchData['pref']->getId());
  145.         }
  146.         // sex
  147.         if (!empty($searchData['sex']) && count($searchData['sex']) > 0) {
  148.             $sexs = [];
  149.             foreach ($searchData['sex'] as $sex) {
  150.                 $sexs[] = $sex->getId();
  151.             }
  152.             $qb
  153.                 ->andWhere($qb->expr()->in('c.Sex'':sexs'))
  154.                 ->setParameter('sexs'$sexs);
  155.         }
  156.         if (!empty($searchData['birth_month']) && $searchData['birth_month']) {
  157.             $qb
  158.                 ->andWhere('EXTRACT(MONTH FROM c.birth) = :birth_month')
  159.                 ->setParameter('birth_month'$searchData['birth_month']);
  160.         }
  161.         // birth
  162.         if (!empty($searchData['birth_start']) && $searchData['birth_start']) {
  163.             $qb
  164.                 ->andWhere('c.birth >= :birth_start')
  165.                 ->setParameter('birth_start'$searchData['birth_start']);
  166.         }
  167.         if (!empty($searchData['birth_end']) && $searchData['birth_end']) {
  168.             $date = clone $searchData['birth_end'];
  169.             $date->modify('+1 days');
  170.             $qb
  171.                 ->andWhere('c.birth < :birth_end')
  172.                 ->setParameter('birth_end'$date);
  173.         }
  174.         // tel
  175.         if (isset($searchData['phone_number']) && StringUtil::isNotBlank($searchData['phone_number'])) {
  176.             $tel preg_replace('/[^0-9]/'''$searchData['phone_number']);
  177.             $qb
  178.                 ->andWhere('c.phone_number LIKE :phone_number')
  179.                 ->setParameter('phone_number''%'.$tel.'%');
  180.         }
  181.         // buy_total
  182.         if (isset($searchData['buy_total_start']) && StringUtil::isNotBlank($searchData['buy_total_start'])) {
  183.             $qb
  184.                 ->andWhere('c.buy_total >= :buy_total_start')
  185.                 ->setParameter('buy_total_start'$searchData['buy_total_start']);
  186.         }
  187.         if (isset($searchData['buy_total_end']) && StringUtil::isNotBlank($searchData['buy_total_end'])) {
  188.             $qb
  189.                 ->andWhere('c.buy_total <= :buy_total_end')
  190.                 ->setParameter('buy_total_end'$searchData['buy_total_end']);
  191.         }
  192.         // buy_times
  193.         if (isset($searchData['buy_times_start']) && StringUtil::isNotBlank($searchData['buy_times_start'])) {
  194.             $qb
  195.                 ->andWhere('c.buy_times >= :buy_times_start')
  196.                 ->setParameter('buy_times_start'$searchData['buy_times_start']);
  197.         }
  198.         if (isset($searchData['buy_times_end']) && StringUtil::isNotBlank($searchData['buy_times_end'])) {
  199.             $qb
  200.                 ->andWhere('c.buy_times <= :buy_times_end')
  201.                 ->setParameter('buy_times_end'$searchData['buy_times_end']);
  202.         }
  203.         // create_date
  204.         if (!empty($searchData['create_datetime_start']) && $searchData['create_datetime_start']) {
  205.             $date $searchData['create_datetime_start'];
  206.             $qb
  207.                 ->andWhere('c.create_date >= :create_date_start')
  208.                 ->setParameter('create_date_start'$date);
  209.         } elseif (!empty($searchData['create_date_start']) && $searchData['create_date_start']) {
  210.             $qb
  211.                 ->andWhere('c.create_date >= :create_date_start')
  212.                 ->setParameter('create_date_start'$searchData['create_date_start']);
  213.         }
  214.         if (!empty($searchData['create_datetime_end']) && $searchData['create_datetime_end']) {
  215.             $date $searchData['create_datetime_end'];
  216.             $qb
  217.                 ->andWhere('c.create_date < :create_date_end')
  218.                 ->setParameter('create_date_end'$date);
  219.         } elseif (!empty($searchData['create_date_end']) && $searchData['create_date_end']) {
  220.             $date = clone $searchData['create_date_end'];
  221.             $date->modify('+1 days');
  222.             $qb
  223.                 ->andWhere('c.create_date < :create_date_end')
  224.                 ->setParameter('create_date_end'$date);
  225.         }
  226.         // update_date
  227.         if (!empty($searchData['update_datetime_start']) && $searchData['update_datetime_start']) {
  228.             $date $searchData['update_datetime_start'];
  229.             $qb
  230.                 ->andWhere('c.update_date >= :update_date_start')
  231.                 ->setParameter('update_date_start'$date);
  232.         } elseif (!empty($searchData['update_date_start']) && $searchData['update_date_start']) {
  233.             $qb
  234.                 ->andWhere('c.update_date >= :update_date_start')
  235.                 ->setParameter('update_date_start'$searchData['update_date_start']);
  236.         }
  237.         if (!empty($searchData['update_datetime_end']) && $searchData['update_datetime_end']) {
  238.             $date $searchData['update_datetime_end'];
  239.             $qb
  240.                 ->andWhere('c.update_date < :update_date_end')
  241.                 ->setParameter('update_date_end'$date);
  242.         } elseif (!empty($searchData['update_date_end']) && $searchData['update_date_end']) {
  243.             $date = clone $searchData['update_date_end'];
  244.             $date->modify('+1 days');
  245.             $qb
  246.                 ->andWhere('c.update_date < :update_date_end')
  247.                 ->setParameter('update_date_end'$date);
  248.         }
  249.         // last_buy
  250.         if (!empty($searchData['last_buy_datetime_start']) && $searchData['last_buy_datetime_start']) {
  251.             $date $searchData['last_buy_datetime_start'];
  252.             $qb
  253.                 ->andWhere('c.last_buy_date >= :last_buy_start')
  254.                 ->setParameter('last_buy_start'$date);
  255.         } elseif (!empty($searchData['last_buy_start']) && $searchData['last_buy_start']) {
  256.             $qb
  257.                 ->andWhere('c.last_buy_date >= :last_buy_start')
  258.                 ->setParameter('last_buy_start'$searchData['last_buy_start']);
  259.         }
  260.         if (!empty($searchData['last_buy_datetime_end']) && $searchData['last_buy_datetime_end']) {
  261.             $date $searchData['last_buy_datetime_end'];
  262.             $qb
  263.                 ->andWhere('c.last_buy_date < :last_buy_end')
  264.                 ->setParameter('last_buy_end'$date);
  265.         } elseif (!empty($searchData['last_buy_end']) && $searchData['last_buy_end']) {
  266.             $date = clone $searchData['last_buy_end'];
  267.             $date->modify('+1 days');
  268.             $qb
  269.                 ->andWhere('c.last_buy_date < :last_buy_end')
  270.                 ->setParameter('last_buy_end'$date);
  271.         }
  272.         // status
  273.         if (!empty($searchData['customer_status']) && count($searchData['customer_status']) > 0) {
  274.             $qb
  275.                 ->andWhere($qb->expr()->in('c.Status'':statuses'))
  276.                 ->setParameter('statuses'$searchData['customer_status']);
  277.         }
  278.         // buy_product_name
  279.         if (isset($searchData['buy_product_name']) && StringUtil::isNotBlank($searchData['buy_product_name'])) {
  280.             $qb
  281.                 ->leftJoin('c.Orders''o')
  282.                 ->leftJoin('o.OrderItems''oi')
  283.                 ->andWhere('oi.product_name LIKE :buy_product_name')
  284.                 ->andWhere($qb->expr()->notIn('o.OrderStatus'':order_status'))
  285.                 ->setParameter('buy_product_name''%'.$searchData['buy_product_name'].'%')
  286.                 ->setParameter('order_status', [OrderStatus::PROCESSINGOrderStatus::PENDING]);
  287.         }
  288.         // Order By
  289.         if (isset($searchData['sortkey']) && !empty($searchData['sortkey'])) {
  290.             $sortOrder = (isset($searchData['sorttype']) && $searchData['sorttype'] == 'a') ? 'ASC' 'DESC';
  291.             $qb->orderBy(self::COLUMNS[$searchData['sortkey']], $sortOrder);
  292.             $qb->addOrderBy('c.update_date''DESC');
  293.             $qb->addOrderBy('c.id''DESC');
  294.         } else {
  295.             $qb->orderBy('c.update_date''DESC');
  296.             $qb->addOrderBy('c.id''DESC');
  297.         }
  298.         return $this->queries->customize(QueryKey::CUSTOMER_SEARCH$qb$searchData);
  299.     }
  300.     /**
  301.      * ユニークなシークレットキーを返す.
  302.      *
  303.      * @return string
  304.      */
  305.     public function getUniqueSecretKey()
  306.     {
  307.         do {
  308.             $key StringUtil::random(32);
  309.             $Customer $this->findOneBy(['secret_key' => $key]);
  310.             log_info('CustomerRepository getUniqueSecretKey', ['key' => $key]);
  311.         } while ($Customer);
  312.         return $key;
  313.     }
  314.     /**
  315.      * ユニークなパスワードリセットキーを返す
  316.      *
  317.      * @return string
  318.      */
  319.     public function getUniqueResetKey()
  320.     {
  321.         do {
  322.             $key StringUtil::random(32);
  323.             $Customer $this->findOneBy(['reset_key' => $key]);
  324.         } while ($Customer);
  325.         return $key;
  326.     }
  327.     /**
  328.      * 仮会員をシークレットキーで検索する.
  329.      *
  330.      * @param $secretKey
  331.      *
  332.      * @return Customer|null 見つからない場合はnullを返す.
  333.      */
  334.     public function getProvisionalCustomerBySecretKey($secretKey)
  335.     {
  336.         return $this->findOneBy([
  337.             'secret_key' => $secretKey,
  338.             'Status' => CustomerStatus::PROVISIONAL,
  339.         ]);
  340.     }
  341.     /**
  342.      * 本会員をemailで検索する.
  343.      *
  344.      * @param $email
  345.      *
  346.      * @return Customer|null 見つからない場合はnullを返す.
  347.      */
  348.     public function getRegularCustomerByEmail($email)
  349.     {
  350.         return $this->findOneBy([
  351.             'email' => $email,
  352.             'Status' => CustomerStatus::REGULAR,
  353.         ]);
  354.     }
  355.     /**
  356.      * 本会員をリセットキー、またはリセットキーとメールアドレスで検索する.
  357.      *
  358.      * @param $resetKey
  359.      * @param $email
  360.      *
  361.      * @return Customer|null 見つからない場合はnullを返す.
  362.      */
  363.     public function getRegularCustomerByResetKey($resetKey$email null)
  364.     {
  365.         $qb $this->createQueryBuilder('c')
  366.             ->where('c.reset_key = :reset_key AND c.Status = :status AND c.reset_expire >= :reset_expire')
  367.             ->setParameter('reset_key'$resetKey)
  368.             ->setParameter('status'CustomerStatus::REGULAR)
  369.             ->setParameter('reset_expire', new \DateTime());
  370.         if ($email) {
  371.             $qb
  372.                 ->andWhere('c.email = :email')
  373.                 ->setParameter('email'$email);
  374.         }
  375.         return $qb->setMaxResults(1)
  376.             ->getQuery()
  377.             ->getOneOrNullResult();
  378.     }
  379.     /**
  380.      * リセット用パスワードを生成する.
  381.      *
  382.      * @return string
  383.      */
  384.     public function getResetPassword()
  385.     {
  386.         return StringUtil::random(8);
  387.     }
  388.     /**
  389.      * 仮会員, 本会員の会員を返す.
  390.      * Eccube\Entity\CustomerのUniqueEntityバリデーションで使用しています.
  391.      *
  392.      * @param array $criteria
  393.      *
  394.      * @return Customer[]
  395.      */
  396.     public function getNonWithdrawingCustomers(array $criteria = [])
  397.     {
  398.         $criteria['Status'] = [
  399.             CustomerStatus::PROVISIONAL,
  400.             CustomerStatus::REGULAR,
  401.         ];
  402.         return $this->findBy($criteria);
  403.     }
  404. }