ここに示す方法と同様のページネーションを実装しました。
検索\モデル\コーステーブル
class CourseTable {
const RELEVANCE_TITLE = 5;
const RELEVANCE_DESCRIPTION = 2;
const RELEVANCE_MIN = 3;
protected $tableGateway;
public function __construct(TableGateway $tableGateway) {
$this->tableGateway = $tableGateway;
}
public function findAllByCriteria(CourseSearchInput $input) {
$concatDelimiter = self::CONCAT_DELIMITER;
$select = new Select();
$where = $this->buildWhereFromCriteria($input);
$having = new Having();
$select->columns(array(
...
));
$select->from($this->tableGateway->getTable());
$select
->join('...)) // and some more JOINs
;
$where
// condition
;
$having
->greaterThanOrEqualTo('relevance', self::RELEVANCE_MIN);
;
$select->where($where, Predicate::OP_AND);
$select->having($having);
$select->group(array('courses.id'));
$adapter = new \Zend\Paginator\Adapter\DbSelect($select, $this->tableGateway->getAdapter());
$paginator = new \Zend\Paginator\Paginator($adapter);
return $paginator;
// $resultSet = $this->tableGateway->selectWith($select);
// return $resultSet;
}
public function buildRelevanceExpressionFromCriteria(CourseSearchInput $input) {
$criteria = $input->getArrayCopy();
$relevanceTitle = self::RELEVANCE_TITLE;
$relevanceDescription = self::RELEVANCE_DESCRIPTION;
$expressionSQL = <<<SQL
MATCH (coursedata.title) AGAINST ('{$criteria['keyword']}') * $relevanceTitle +
MATCH (coursedata.description) AGAINST ('{$criteria['keyword']}') * $relevanceDescription
SQL;
return new Expression($expressionSQL);
}
function buildWhereFromCriteria(CourseSearchInput $input) {
...
}
}
検索\コントローラー\検索コントローラー
class SearchController extends AbstractActionController {
protected $courseTable;
public function searchAction() {
return $this->redirect()->toRoute('search-courses');
}
public function searchCoursesAction() {
$form = $this->getServiceLocator()->get('Search\Form\CourseSearchForm');
$request = $this->getRequest();
if ($request->isPost()) {
$courseSearchInput = new CourseSearchInput();
$form->setInputFilter($courseSearchInput->getInputFilter());
$form->setData($request->getPost());
if ($form->isValid()) {
$courseSearchInput->exchangeArray($form->getData());
// $courses = $this->getCourseTable()->findAllByCriteria($courseSearchInput);
$courses = $this->getCourseTable()->findAllByCriteria($courseSearchInput);
$test = $courses->count();
} else {
$courses = null;
}
} else {
$courses = null;
}
return new ViewModel(array(
'form' => $form,
'courses' => $courses,
'cities' => $this->getServiceLocator()->get('Cache\Model\CityStorage')->getCities(),
));
}
function getCourseTable() {
...
}
}
例外がスローされるようになりました。
File:
/var/www/path/to/project/vendor/zendframework/zendframework/library/Zend/Db/Adapter/Driver/Pdo/Statement.php:245
Message:
Statement could not be executed
Stapelüberwachung:
#0 /var/www/path/to/project/vendor/zendframework/zendframework/library/Zend/Paginator/Adapter/DbSelect.php(122): Zend\Db\Adapter\Driver\Pdo\Statement->execute()
#1 /var/www/path/to/project/vendor/zendframework/zendframework/library/Zend/Paginator/Paginator.php(881): Zend\Paginator\Adapter\DbSelect->count()
#2 /var/www/path/to/project/vendor/zendframework/zendframework/library/Zend/Paginator/Paginator.php(343): Zend\Paginator\Paginator->_calculatePageCount()
#3 /var/www/path/to/project/module/Search/src/Search/Controller/SearchController.php(38): Zend\Paginator\Paginator->count()
#4 /var/www/path/to/project/vendor/zendframework/zendframework/library/Zend/Mvc/Controller/AbstractActionController.php(83): Search\Controller\SearchController->searchCoursesAction()
#5 [internal function]: Zend\Mvc\Controller\AbstractActionController->onDispatch(Object(Zend\Mvc\MvcEvent))
#6 /var/www/path/to/project/vendor/zendframework/zendframework/library/Zend/EventManager/EventManager.php(460): call_user_func(Array, Object(Zend\Mvc\MvcEvent))
#7 /var/www/path/to/project/vendor/zendframework/zendframework/library/Zend/EventManager/EventManager.php(204): Zend\EventManager\EventManager->triggerListeners('dispatch', Object(Zend\Mvc\MvcEvent), Object(Closure))
#8 /var/www/path/to/project/vendor/zendframework/zendframework/library/Zend/Mvc/Controller/AbstractController.php(117): Zend\EventManager\EventManager->trigger('dispatch', Object(Zend\Mvc\MvcEvent), Object(Closure))
#9 /var/www/path/to/project/vendor/zendframework/zendframework/library/Zend/Mvc/DispatchListener.php(114): Zend\Mvc\Controller\AbstractController->dispatch(Object(Zend\Http\PhpEnvironment\Request), Object(Zend\Http\PhpEnvironment\Response))
#10 [internal function]: Zend\Mvc\DispatchListener->onDispatch(Object(Zend\Mvc\MvcEvent))
#11 /var/www/path/to/project/vendor/zendframework/zendframework/library/Zend/EventManager/EventManager.php(460): call_user_func(Array, Object(Zend\Mvc\MvcEvent))
#12 /var/www/path/to/project/vendor/zendframework/zendframework/library/Zend/EventManager/EventManager.php(204): Zend\EventManager\EventManager->triggerListeners('dispatch', Object(Zend\Mvc\MvcEvent), Object(Closure))
#13 /var/www/path/to/project/vendor/zendframework/zendframework/library/Zend/Mvc/Application.php(294): Zend\EventManager\EventManager->trigger('dispatch', Object(Zend\Mvc\MvcEvent), Object(Closure))
#14 /var/www/path/to/project/public/index.php(12): Zend\Mvc\Application->run()
#15 {main}
そして、前のものは次のとおりです。
Previous Exception:
PDOException
File:
/var/www/path/to/project/vendor/zendframework/zendframework/library/Zend/Db/Adapter/Driver/Pdo/Statement.php:240
Message:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'relevance' in 'having clause'
Stapelüberwachung:
#0 /var/www/path/to/project/vendor/zendframework/zendframework/library/Zend/Db/Adapter/Driver/Pdo/Statement.php(240): PDOStatement->execute()
#1 /var/www/path/to/project/vendor/zendframework/zendframework/library/Zend/Paginator/Adapter/DbSelect.php(122): Zend\Db\Adapter\Driver\Pdo\Statement->execute()
#2 /var/www/path/to/project/vendor/zendframework/zendframework/library/Zend/Paginator/Paginator.php(881): Zend\Paginator\Adapter\DbSelect->count()
#3 /var/www/path/to/project/vendor/zendframework/zendframework/library/Zend/Paginator/Paginator.php(343): Zend\Paginator\Paginator->_calculatePageCount()
#4 /var/www/path/to/project/module/Search/src/Search/Controller/SearchController.php(38): Zend\Paginator\Paginator->count()
#5 /var/www/path/to/project/vendor/zendframework/zendframework/library/Zend/Mvc/Controller/AbstractActionController.php(83): Search\Controller\SearchController->searchCoursesAction()
#6 [internal function]: Zend\Mvc\Controller\AbstractActionController->onDispatch(Object(Zend\Mvc\MvcEvent))
#7 /var/www/path/to/project/vendor/zendframework/zendframework/library/Zend/EventManager/EventManager.php(460): call_user_func(Array, Object(Zend\Mvc\MvcEvent))
#8 /var/www/path/to/project/vendor/zendframework/zendframework/library/Zend/EventManager/EventManager.php(204): Zend\EventManager\EventManager->triggerListeners('dispatch', Object(Zend\Mvc\MvcEvent), Object(Closure))
#9 /var/www/path/to/project/vendor/zendframework/zendframework/library/Zend/Mvc/Controller/AbstractController.php(117): Zend\EventManager\EventManager->trigger('dispatch', Object(Zend\Mvc\MvcEvent), Object(Closure))
#10 /var/www/path/to/project/vendor/zendframework/zendframework/library/Zend/Mvc/DispatchListener.php(114): Zend\Mvc\Controller\AbstractController->dispatch(Object(Zend\Http\PhpEnvironment\Request), Object(Zend\Http\PhpEnvironment\Response))
#11 [internal function]: Zend\Mvc\DispatchListener->onDispatch(Object(Zend\Mvc\MvcEvent))
#12 /var/www/path/to/project/vendor/zendframework/zendframework/library/Zend/EventManager/EventManager.php(460): call_user_func(Array, Object(Zend\Mvc\MvcEvent))
#13 /var/www/path/to/project/vendor/zendframework/zendframework/library/Zend/EventManager/EventManager.php(204): Zend\EventManager\EventManager->triggerListeners('dispatch', Object(Zend\Mvc\MvcEvent), Object(Closure))
#14 /var/www/path/to/project/vendor/zendframework/zendframework/library/Zend/Mvc/Application.php(294): Zend\EventManager\EventManager->trigger('dispatch', Object(Zend\Mvc\MvcEvent), Object(Closure))
#15 /var/www/path/to/project/public/index.php(12): Zend\Mvc\Application->run()
#16 {main}
フレームワークのバグですか?
編集
$test = $select->getSqlString($this->tableGateway->getAdapter()->getPlatform());
前の行で生成されたクエリ$adapter = new \Zend\Paginator\Adapter\DbSelect($select, $this->tableGateway->getAdapter());
:
SELECT `courses`.`id` AS `id`,
`courses`.`title` AS `title`,
`courses`.`description` AS `description`,
DATE_FORMAT(courses.startdate, "%e\.%m\.%Y") AS `startDate`,
DATE_FORMAT(courses.enddate, "%e\.%m\.%Y") AS `endDate`,
DATE_FORMAT(courses.starttime, "%H\:%i") AS `startTime`,
DATE_FORMAT(courses.endtime, "%H\:%i") AS `endTime`,
`allproviders`.`displayedname` AS `providerName`,
`allproviders`.`providertype` AS `providerType`,
`cities`.`name` AS `city`,
`weekdays`.`labelde` AS `weekday`,
`levelsmin`.`usrlevel` AS `usrLevelMin`,
`levelsmin`.`unilevel` AS `uniLevelMin`,
`levelsmax`.`usrlevel` AS `usrLevelMax`,
`levelsmax`.`unilevel` AS `uniLevelMax`,
MATCH (coursedata.title) AGAINST ('Salsa') * 5 + MATCH (coursedata.description) AGAINST ('Salsa') * 2 AS `relevance`,
GROUP_CONCAT(trainers.name SEPARATOR '|||') AS `trainers`
FROM `courses`
INNER JOIN `allproviders` ON `courses`.`provider_id` = `allproviders`.`providerid`
INNER JOIN `cities` ON `allproviders`.`city_id` = `cities`.`id`
INNER JOIN `weekdays` ON `courses`.`weekday_id` = `weekdays`.`id`
LEFT JOIN `levels` AS `levelsmin` ON `courses`.`levelmin_id` = `levelsmin`.`id`
LEFT JOIN `levels` AS `levelsmax` ON `courses`.`levelmax_id` = `levelsmax`.`id`
INNER JOIN `coursedata` ON `courses`.`id` = `coursedata`.`id`
INNER JOIN `courses_trainers` ON `courses`.`id` = `courses_trainers`.`course_id`
INNER JOIN `trainers` ON `trainer_id` = `trainers`.`id`
WHERE `cities`.`id` = '23'
AND `weekdays`.`id` IN ('1',
'2',
'3',
'4',
'5',
'6',
'7')
AND `courses`.`enddate` > NOW()
GROUP BY `courses`.`id` HAVING `relevance` >= '3'