Skip to content

Commit

Permalink
Merge pull request #2285 from kiy0taka/feature/query-customize
Browse files Browse the repository at this point in the history
リポジトリで組み立てているQueryBuilderをカスタマイズする機構を実装
  • Loading branch information
Yangsin authored Apr 26, 2017
2 parents 342757a + 81b0ce4 commit 624c391
Show file tree
Hide file tree
Showing 20 changed files with 1,440 additions and 8 deletions.
28 changes: 28 additions & 0 deletions app/Acme/Entity/AdminProductListCustomizer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php


namespace Acme\Entity;


use Eccube\Annotation\QueryExtension;
use Eccube\Doctrine\Query\OrderByClause;
use Eccube\Doctrine\Query\OrderByCustomizer;
use Eccube\Repository\ProductRepository;

/**
* @QueryExtension(ProductRepository::QUERY_KEY_SEARCH_ADMIN)
*/
class AdminProductListCustomizer extends OrderByCustomizer
{
/**
* 常に商品IDでソートする。
*
* @param array $params
* @param $queryKey
* @return OrderByClause[]
*/
protected function createStatements($params, $queryKey)
{
return [new OrderByClause('p.id')];
}
}
18 changes: 18 additions & 0 deletions src/Eccube/Annotation/QueryExtension.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php


namespace Eccube\Annotation;
use Doctrine\Common\Annotations\Annotation\Target;
use Doctrine\ORM\Mapping\Annotation;

/**
* @Annotation
* @Target("CLASS")
*/
final class QueryExtension implements Annotation
{
/**
* @var array
*/
public $value;
}
188 changes: 188 additions & 0 deletions src/Eccube/Doctrine/Query/JoinClause.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
<?php
/*
* This file is part of EC-CUBE
*
* Copyright(c) 2000-2017 LOCKON CO.,LTD. All Rights Reserved.
*
* http://www.lockon.co.jp/
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/

namespace Eccube\Doctrine\Query;


use Doctrine\ORM\QueryBuilder;

/**
* JOIN句を組み立てるクラス
*/
class JoinClause
{

private $join;

private $alias;

private $conditionType;

private $condition;

private $indexBy;

private $leftJoin = false;

/**
* @var JoinClauseWhereCustomizer $whereCustomizer
*/
private $whereCustomizer;

/**
* @var JoinClauseOrderByCustomizer $orderByCustomizer
*/
private $orderByCustomizer;

/**
* JoinClause constructor.
* @param $leftJoin
* @param $join
* @param $alias
* @param $conditionType
* @param $condition
* @param $indexBy
*/
private function __construct($leftJoin, $join, $alias, $conditionType = null, $condition = null, $indexBy = null)
{
$this->leftJoin = $leftJoin;
$this->join = $join;
$this->alias = $alias;
$this->conditionType = $conditionType;
$this->condition = $condition;
$this->indexBy = $indexBy;
$this->whereCustomizer = new JoinClauseWhereCustomizer();
$this->orderByCustomizer = new JoinClauseOrderByCustomizer();
}

/**
* INNER JOIN用のファクトリメソッド。
*
* @see QueryBuilder::innerJoin()
* @param $join
* @param $alias
* @param $conditionType
* @param $condition
* @param $indexBy
* @return JoinClause
*/
public static function innerJoin($join, $alias, $conditionType = null, $condition = null, $indexBy = null)
{
return new JoinClause(false, $join, $alias, $conditionType, $condition, $indexBy);
}

/**
* LEFT JOIN用のファクトリメソッド。
*
* @see QueryBuilder::leftJoin()
* @param $join
* @param $alias
* @param $conditionType
* @param $condition
* @param $indexBy
* @return JoinClause
*/
public static function leftJoin($join, $alias, $conditionType = null, $condition = null, $indexBy = null)
{
return new JoinClause(true, $join, $alias, $conditionType, $condition, $indexBy);
}

/**
* WHERE句を追加します。
*
* @param WhereClause $whereClause
* @return $this
*/
public function addWhere(WhereClause $whereClause)
{
$this->whereCustomizer->add($whereClause);
return $this;
}

/**
* ORDER BY句を追加します。
* @param OrderByClause $orderByClause
* @return $this
*/
public function addOrderBy(OrderByClause $orderByClause)
{
$this->orderByCustomizer->add($orderByClause);
return $this;
}

public function build(QueryBuilder $builder) {
if ($this->leftJoin) {
$builder->leftJoin($this->join, $this->alias, $this->conditionType, $this->condition, $this->indexBy);
} else {
$builder->innerJoin($this->join, $this->alias, $this->conditionType, $this->condition, $this->indexBy);
}
$this->whereCustomizer->customize($builder, null, '');
$this->orderByCustomizer->customize($builder, null, '');
}
}

class JoinClauseWhereCustomizer extends WhereCustomizer
{
/**
* @var WhereClause[]
*/
private $whereClauses = [];

public function add(WhereClause $whereClause)
{
$this->whereClauses[] = $whereClause;
}

/**
* @param array $params
* @param $queryKey
* @return WhereClause[]
*/
protected function createStatements($params, $queryKey)
{
return $this->whereClauses;
}
}

class JoinClauseOrderByCustomizer extends OrderByCustomizer
{
/**
* @var OrderByClause[]
*/
private $orderByClauses = [];

public function add(OrderByClause $orderByClause)
{
$this->orderByClauses[] = $orderByClause;
}

/**
* @param array $params
* @param $queryKey
* @return OrderByClause[]
*/
protected function createStatements($params, $queryKey)
{
return $this->orderByClauses;
}
}
60 changes: 60 additions & 0 deletions src/Eccube/Doctrine/Query/JoinCustomizer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php
/*
* This file is part of EC-CUBE
*
* Copyright(c) 2000-2017 LOCKON CO.,LTD. All Rights Reserved.
*
* http://www.lockon.co.jp/
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/


namespace Eccube\Doctrine\Query;


use Doctrine\ORM\QueryBuilder;

/**
* JOIN句をカスタマイズするクラス。
*
* @package Eccube\Doctrine\Query
*/
abstract class JoinCustomizer implements QueryCustomizer
{

/**
* @param QueryBuilder $builder
* @param array $params
* @param string $queryKey
*/
public final function customize(QueryBuilder $builder, $params, $queryKey)
{
foreach ($this->createStatements($params, $queryKey) as $joinClause) {
$joinClause->build($builder);
}
}

/**
* 追加するJOIN句を組み立てます。
* このメソッドの戻り値が、元のクエリのJOIN句に追加されます。
*
* @param array $params
* @param $queryKey
* @return JoinClause[]
*/
public abstract function createStatements($params, $queryKey);

}
64 changes: 64 additions & 0 deletions src/Eccube/Doctrine/Query/OrderByClause.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?php
/*
* This file is part of EC-CUBE
*
* Copyright(c) 2000-2017 LOCKON CO.,LTD. All Rights Reserved.
*
* http://www.lockon.co.jp/
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/

namespace Eccube\Doctrine\Query;


/**
* ORDER BY句を組み立てるクラス。
*
* @package Eccube\Doctrine\Query
*/
class OrderByClause
{

private $sort;
private $order;

/**
* OrderByClause constructor.
* @param $sort
* @param string $order
*/
function __construct($sort, $order = 'asc')
{
$this->sort = $sort;
$this->order = $order;
}

/**
* @return string
*/
public function getSort()
{
return $this->sort;
}

/**
* @return string
*/
public function getOrder()
{
return $this->order;
}
}
Loading

0 comments on commit 624c391

Please sign in to comment.