Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions src/Api/BaseController.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,20 @@ class BaseController extends Controller
*/
protected $customConditions = null;

/**
* Specify the custom limit
*
* @var int
*/
protected $customLimit = null;

/**
* Specify the sort limit
*
* @var strong
*/
protected $customSort = null;

/**
* Send a response when needed.
*
Expand Down
2 changes: 2 additions & 0 deletions src/Contracts/Api/CrudBehaviorTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ protected function processRequest(RequestInterface $request): array
$parse->setCustomColumns($this->customColumns);
$parse->setCustomTableJoins($this->customTableJoins);
$parse->setCustomConditions($this->customConditions);
$parse->setCustomLimit($this->customLimit);
$parse->setCustomSort($this->customSort);
$parse->appendParams($this->additionalSearchFields);
$parse->appendCustomParams($this->additionalCustomSearchFields);
$parse->appendRelationParams($this->additionalRelationSearchFields);
Expand Down
31 changes: 31 additions & 0 deletions src/Contracts/Converter/CustomQueriesTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

namespace Baka\Http\Contracts\Converter;

use Exception;
use Phalcon\Mvc\Model\MetaData\Memory as MetaDataMemory;
use Phalcon\Di;

trait CustomQueriesTrait
{
/**
Expand All @@ -25,6 +29,20 @@ trait CustomQueriesTrait
*/
protected $customConditions = null;

/**
* Custom Limit.
*
* @var int
*/
protected $limit;

/**
* Custom Sort.
*
* @var string
*/
protected $sort;

/**
* Set the custom columns provide by the user.
*
Expand Down Expand Up @@ -64,4 +82,17 @@ public function setCustomConditions(?string $query) : void
$this->customConditions = ' ' . $query;
}
}

/**
* Overwrite the limit of the current Request.
*
* @param integer $limit
* @return void
*/
public function setCustomLimit(?int $limit): void
{
if (is_null($limit)) {
$this->limit = $limit;
}
}
}
62 changes: 8 additions & 54 deletions src/Converter/RequestUriToElasticSearch.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,8 @@

namespace Baka\Http\Converter;

use Baka\Database\CustomFields\CustomFields;
use Baka\Database\CustomFields\Modules;
use Baka\Database\Model;
use Exception;
use Phalcon\Di;
use Phalcon\Mvc\Model\ResultsetInterface;
use Baka\Http\Contracts\Converter\CustomQueriesTrait;

/**
* Base QueryParser. Parse GET request for a API to a array Phalcon Model find and FindFirst can intepret.
Expand Down Expand Up @@ -100,66 +95,25 @@ public function convert(): array
}
}

// Prepare the search parameters.
$this->prepareParams($params);

// Sorting logic for related searches.
// @TODO Explore this in the future. There might be better ways to carry it out.
$sort = '';
if (array_key_exists('sort', $this->request)) {
$sort = $this->request['sort'];

if (!empty($sort)) {
// Get the model, column and sort order from the sent parameter.
list($modelColumn, $order) = explode('|', $sort);
// Check to see whether this is a related sorting by looking for a .
if (strpos($modelColumn, '.') !== false) {
// We are using a related sort.
// Get the namespace for the models from the configuration.
$modelNamespace = \Phalcon\Di::getDefault()->getConfig()->namespace->models;
// Get the model name and the sort column from the sent parameter
list($model, $column) = explode('.', $modelColumn);
// Convert the model name into camel case.
$modelName = str_replace(' ', '', ucwords(str_replace('_', ' ', $model)));
// Create the model name with the appended namespace.
$modelName = $modelNamespace . '\\' . $modelName;

// Make sure the model exists.
if (!class_exists($modelName)) {
throw new Exception('Related model does not exist.');
}

// Instance the model so we have access to the getSource() function.
$modelObject = new $modelName();
// Instance meta data memory to access the primary keys for the table.
$metaData = new \Phalcon\Mvc\Model\MetaData\Memory();
// Get the first matching primary key.
// @TODO This will hurt on compound primary keys.
$primaryKey = $metaData->getPrimaryKeyAttributes($modelObject)[0];
// We need the table to exist in the query in order for the related sort to work.
// Therefore we add it to comply with this by comparing the primary key to not being NULL.
$this->relationSearchFields[$modelName][] = [
$primaryKey, ':', '$$',
];

$sort = " ORDER BY {$modelObject->getSource()}.{$column} {$order}";
unset($modelObject);
} else {
$sort = " ORDER BY {$modelColumn} {$order}";
}
if (!empty($this->request['sort'])) {
$this->setCustomSort(trim($this->request['sort']));
}
}

// Prepare the search parameters.
$this->prepareParams($params);

// Append any additional user parameters
$this->appendAdditionalParams();
//base on th eesarch params get the raw query
$rawSql = $this->prepareCustomSearch();

//sort
if (!empty($sort)) {
$rawSql['sql'] .= $sort;
if (!is_null($this->sort)) {
$rawSql['sql'] .= $this->sort;
}

// Calculate the corresponding offset
$this->offset = ($this->page - 1) * $this->limit;
$rawSql['sql'] .= " LIMIT {$this->limit} OFFSET {$this->offset}";
Expand Down
123 changes: 70 additions & 53 deletions src/Converter/RequestUriToSql.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
use Phalcon\Di;
use Phalcon\Mvc\Model\ResultsetInterface;
use Baka\Http\Contracts\Converter\CustomQueriesTrait;
use Phalcon\Mvc\Model\MetaData\Memory as MetaDataMemory;
use Phalcon\Di\Injectable;
use ReflectionClass;

/**
* Base QueryParser. Parse GET request for a API to a array Phalcon Model find and FindFirst can intepret.
Expand All @@ -24,7 +27,7 @@
* Partials:
* offset=20
*/
class RequestUriToSql extends \Phalcon\Di\Injectable implements ConverterInterface
class RequestUriToSql extends Injectable implements ConverterInterface
{
use CustomQueriesTrait;

Expand Down Expand Up @@ -53,6 +56,11 @@ class RequestUriToSql extends \Phalcon\Di\Injectable implements ConverterInterfa
*/
protected $limit = 25;

/**
* @var string
*/
protected $sort = null;

/**
* @var int
*/
Expand Down Expand Up @@ -166,64 +174,23 @@ public function convert(): array
}
}

// Prepare the search parameters.
$this->prepareParams($params);

// Sorting logic for related searches.
// @TODO Explore this in the future. There might be better ways to carry it out.
$sort = '';
if (array_key_exists('sort', $this->request)) {
$sort = $this->request['sort'];

if (!empty($sort)) {
// Get the model, column and sort order from the sent parameter.
list($modelColumn, $order) = explode('|', $sort);
// Check to see whether this is a related sorting by looking for a .
if (strpos($modelColumn, '.') !== false) {
// We are using a related sort.
// Get the namespace for the models from the configuration.
$modelNamespace = \Phalcon\Di::getDefault()->getConfig()->namespace->models;
// Get the model name and the sort column from the sent parameter
list($model, $column) = explode('.', $modelColumn);
// Convert the model name into camel case.
$modelName = str_replace(' ', '', ucwords(str_replace('_', ' ', $model)));
// Create the model name with the appended namespace.
$modelName = $modelNamespace . '\\' . $modelName;

// Make sure the model exists.
if (!class_exists($modelName)) {
throw new Exception('Related model does not exist.');
}

// Instance the model so we have access to the getSource() function.
$modelObject = new $modelName();
// Instance meta data memory to access the primary keys for the table.
$metaData = new \Phalcon\Mvc\Model\MetaData\Memory();
// Get the first matching primary key.
// @TODO This will hurt on compound primary keys.
$primaryKey = $metaData->getPrimaryKeyAttributes($modelObject)[0];
// We need the table to exist in the query in order for the related sort to work.
// Therefore we add it to comply with this by comparing the primary key to not being NULL.
$this->relationSearchFields[$modelName][] = [
$primaryKey, ':', '$$',
];

$sort = " ORDER BY {$modelObject->getSource()}.{$column} {$order}";
unset($modelObject);
} else {
$sort = " ORDER BY {$modelColumn} {$order}";
}
if (!empty($this->request['sort'])) {
$this->setCustomSort(trim($this->request['sort']));
}
}

// Prepare the search parameters.
$this->prepareParams($params);

// Append any additional user parameters
$this->appendAdditionalParams();
//base on th eesarch params get the raw query
$rawSql = $this->prepareCustomSearch();

//sort
if (!empty($sort)) {
$rawSql['sql'] .= $sort;
if (!is_null($this->sort)) {
$rawSql['sql'] .= $this->sort;
}

// Calculate the corresponding offset
Expand All @@ -241,8 +208,8 @@ public function convert(): array
*/
protected function prepareCustomSearch($hasSubquery = false): array
{
$metaData = new \Phalcon\Mvc\Model\MetaData\Memory();
$classReflection = (new \ReflectionClass($this->model));
$metaData = new MetaDataMemory();
$classReflection = (new ReflectionClass($this->model));
$classname = $this->model->getSource();

$primaryKey = null;
Expand Down Expand Up @@ -401,7 +368,7 @@ protected function prepareNormalSql(array $searchCriteria, string $classname, st
}

if ($value = 'null') {
$logicConector = !$vKey ? " " . $andOr .' (' : ' OR ';
$logicConector = !$vKey ? ' ' . $andOr . ' (' : ' OR ';
$sql .= $logicConector . $classname . '.' . $searchField . ' IS NULL';
} else {
if (!$vKey) {
Expand Down Expand Up @@ -577,7 +544,7 @@ protected function prepareParams(array $unparsed): void
protected function parseRelationParameters(array $unparsed): array
{
$parseRelationParameters = [];
$modelNamespace = \Phalcon\Di::getDefault()->getConfig()->namespace->models;
$modelNamespace = Di::getDefault()->getConfig()->namespace->models;

foreach ($unparsed as $model => $query) {
$modelName = str_replace(' ', '', ucwords(str_replace('_', ' ', $model)));
Expand Down Expand Up @@ -967,4 +934,54 @@ public static function parseRelationShips(string $relationships, &$results): arr
unset($results);
return $newResults;
}

/**
* Set CustomSort for the query.
*
* @param string $sort
* @return string
*/
public function setCustomSort(?string $sort): void
{
if (!is_null($sort)) {
// Get the model, column and sort order from the sent parameter.
list($modelColumn, $order) = explode('|', $sort);
// Check to see whether this is a related sorting by looking for a .
if (strpos($modelColumn, '.') !== false) {
// We are using a related sort.
// Get the namespace for the models from the configuration.
$modelNamespace = Di::getDefault()->getConfig()->namespace->models;
// Get the model name and the sort column from the sent parameter
list($model, $column) = explode('.', $modelColumn);
// Convert the model name into camel case.
$modelName = str_replace(' ', '', ucwords(str_replace('_', ' ', $model)));
// Create the model name with the appended namespace.
$modelName = $modelNamespace . '\\' . $modelName;

// Make sure the model exists.
if (!class_exists($modelName)) {
throw new Exception('Related model does not exist.');
}

// Instance the model so we have access to the getSource() function.
$modelObject = new $modelName();
// Instance meta data memory to access the primary keys for the table.
$metaData = new MetaDataMemory();

// Get the first matching primary key.
// @TODO This will hurt on compound primary keys.
$primaryKey = $metaData->getPrimaryKeyAttributes($modelObject)[0];
// We need the table to exist in the query in order for the related sort to work.
// Therefore we add it to comply with this by comparing the primary key to not being NULL.
$this->relationSearchFields[$modelName][] = [
$primaryKey, ':', '$$',
];

$this->sort = " ORDER BY {$modelObject->getSource()}.{$column} {$order}";
unset($modelObject);
} else {
$this->sort = " ORDER BY {$modelColumn} {$order}";
}
}
}
}
2 changes: 1 addition & 1 deletion tests/_support/_generated/AcceptanceTesterActions.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?php //[STAMP] 06f0c50b8403e3dd406e2091751a7f21
<?php //[STAMP] 918ba77d34fe7a8d0c2867a0719c9490
namespace _generated;

// This class was automatically generated by build task
Expand Down
2 changes: 1 addition & 1 deletion tests/_support/_generated/FunctionalTesterActions.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?php //[STAMP] e71198425890983c7e8b855ce8869dfe
<?php //[STAMP] 687ac9418f2c92429bf9f72b6877801a
namespace _generated;

// This class was automatically generated by build task
Expand Down
2 changes: 1 addition & 1 deletion tests/_support/_generated/UnitTesterActions.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?php //[STAMP] 2e8c06b53f883e54ed1b6b526b3a2cdd
<?php //[STAMP] b7832d73decc5eeb919e30350651163e
namespace _generated;

// This class was automatically generated by build task
Expand Down