jrq*_*ick 5 php cakephp cakephp-3.0
我正在尝试使用CakePHP创建一个允许搜索的API.例如:
http://localhost:8765/users/index/?username=admin
Run Code Online (Sandbox Code Playgroud)
哪个应该返回用户名等于'admin'的用户:
users: [
{
id: 3,
username: "admin",
image: "",
firstName: "Jeremy",
lastName: "Quick",
userTypeId: 1,
email: "jrquick@test.com",
groupId: 2
}
]
Run Code Online (Sandbox Code Playgroud)
到目前为止,我已经能够通过AppController中的自定义get()来完成此操作,该自定义get()检查模型上字段的$ _GET和$ _POST数组.但随着我添加更多功能(范围搜索,集合搜索和子表过滤),该功能变得越来越复杂,并且越来越复杂.是否有更好的,更CakePHP友好的方式来实现这一目标?无论是通过纯蛋糕还是插件?
我还没有找到似乎完全按照我想要的方式工作的答案,所以这是我当前的 get 命令。它确实允许按字段、连接表、大于/小于、数组等进行搜索。
如果有人有改进的建议,我会更新我的答案。
public function get() {
$response = new Response();
$model = $this->loadModel();
$fields = $this->getFields();
$joins = $this->getJoins();
$order = $this->getOrder();
$params = $this->getParams();
$limit = $this->getLimit();
$offset = $this->getOffset();
$query = $model->find('all', ['fields' => $fields]);
if (!is_null($joins)) {
$query->contain($joins);
}
if (sizeof($params['equals']) > 0) {
foreach ($params['equals'] as $equalsKey=>$equalsValue) {
$query->andWhere([$equalsKey => $equalsValue]);
}
}
if (sizeof($params['or']) > 0) {
foreach ($params['or'] as $orKey=>$orValue) {
$query->orWhere([$orKey => $orValue]);
}
}
if (!is_null($order)) {
$query->order([$order]);
}
if (!is_null($limit)) {
$query->limit($limit);
if (!is_null($offset)) {
$query->offset($offset);
}
}
$response->addMessage($model->table(), $query->toArray());
$response->respond($this);
}
private function getFields() {
$fields = [];
if (array_key_exists('fields', $_GET)) {
$fields = explode(',', $_GET['fields']);
}
return $fields;
}
private function getLimit() {
$limit = null;
if (array_key_exists('limit', $_GET)) {
$limit = $_GET['limit'];
}
return $limit;
}
private function getJoins() {
$joins = null;
if (array_key_exists('joins', $_GET)) {
$joins = explode(',', $_GET['joins']);
}
return $joins;
}
private function getOffset() {
$offset = null;
if (array_key_exists('offset', $_GET)) {
$offset = $_GET['limit'];
}
return $offset;
}
private function getOrder() {
$results = [];
if (array_key_exists('order', $_GET)) {
$orders = explode(',', $_GET['order']);
foreach ($orders as $order) {
$sign = substr($order, 0, 1);
$direction = 'ASC';
if (in_array($sign, ['+', '-'])) {
if ($sign === '-') {
$direction = 'DESC';
}
$order = substr($order, 1);
}
$result = $order;
if (strpos($result, '.') === false) {
$result = $this->loadModel()->alias() . '.' . $order;
}
$result = $result . ' ' . $direction;
$results[] = $result;
}
}
return (sizeof($results) == 0) ? null : implode(',', $results);
}
private function getParams() {
$params = [
'equals' => [],
'or' => []
];
$parentModel = $this->loadModel();
$array = array_merge($_GET, $_POST);
foreach ($array as $field=>$value) {
$comparisonType = 'equals';
$operator = substr($field, strlen($field) - 1);
if (in_array($operator, ['!', '>', '<'])) {
$field = substr($field, 0, strlen($field) - 1);
$operator .= '=';
} else if (in_array($operator, ['|'])) {
$field = substr($field, 0, strlen($field) - 1);
$comparisonType = 'or';
$operator = '=';
} else if (in_array($operator, ['%'])) {
$field = substr($field, 0, strlen($field) - 1);
$operator = 'LIKE';
$value = '%'.$value.'%';
} else {
$operator = '=';
}
if ($value == 'null') {
$operator = (strpos($operator, '!') === false) ? 'IS' : 'IS NOT';
$value = null;
}
$field = str_replace('_', '.', $field);
if (strpos($field, '.') === false) {
$alias = $parentModel->alias();
} else {
$fieldExplosion = explode('.', $field);
$alias = $fieldExplosion[0];
$field = $fieldExplosion[1];
}
$model = null;
if ($parentModel->alias() !== $alias) {
$association = $parentModel->associations()->get($alias);
if (!is_null($association)) {
$model = $this->loadModel($association->className());
}
} else {
$model = $parentModel;
}
if (!is_null($model)) {
if ($model->hasField(rtrim($field, 's')) && !$model->hasField($field)) {
$field = rtrim($field, 's');
$value = '(' . $value . ')';
$operator = ' IN';
}
if ($model->hasField($field)) {
$params[$comparisonType][$alias.'.'.$field . ' ' . $operator] = $value;
}
}
}
return $params;
}
Run Code Online (Sandbox Code Playgroud)