Skip to content

Commit

Permalink
Prevent unncessery calls to getFilterValidator and getValidationModel
Browse files Browse the repository at this point in the history
Attempt to set sources at Filter->validate
  • Loading branch information
nohponex committed Sep 27, 2016
1 parent 73181c1 commit 369eddc
Show file tree
Hide file tree
Showing 4 changed files with 137 additions and 95 deletions.
2 changes: 1 addition & 1 deletion src/Controller/Controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ public static function assertExists(
* @throws \Exception
*/
public static function assertUnknownError(
mixed $assert,
$assert,
string $exceptionMessage = 'Unknown error'
) {
if (!$assert) {
Expand Down
16 changes: 13 additions & 3 deletions src/Controller/Post.php
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ public static function handlePost(

//Validate resource type
$typeValidator
->setSource($source->getPath() . '/type')
->setSource(new Pointer($source->getPath() . '/type'))
->parse($resource->type);

//Throw exception if resource id is forced
Expand All @@ -129,9 +129,15 @@ public static function handlePost(
}

//on each validate

//todo
foreach ($requestQueue as $i => $q) {
$validationModel->attributes
->setSource(new Pointer('/data/' . $i . '/attributes'))
->parse($q->attributes);
}

//on each call validation callback
//todo

//post

Expand All @@ -149,13 +155,17 @@ public static function handlePost(
$queueItem->attributes
);

Controller::assertUnknownError($id);
Controller::assertUnknownError(
$id,
'Unknown error while posting resource'
);

//POST item's relationships
$relationships = $queueItem->relationships;

foreach ($relationships as $key => $relationship) {
//Call post relationship method to post each of relationships pairs
//todo fix
foreach ($relationship->resources as $resourceId) {
call_user_func(
$relationship->callback,
Expand Down
210 changes: 120 additions & 90 deletions src/Directive/Filter.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
use Phramework\Exceptions\IncorrectParametersException;
use Phramework\Exceptions\RequestException;
use Phramework\Exceptions\Source\Parameter;
use Phramework\Exceptions\Source\Pointer;
use Phramework\JSONAPI\ResourceModel;
use Phramework\Operator\Operator;
use Phramework\Util\Util;
Expand Down Expand Up @@ -148,12 +149,11 @@ public function __construct(
* $filter->validate(Article::class);
* ```
* @todo add relationship idAttribute validators
* @todo add correct pointers
*/
public function validate(ResourceModel $model) : bool
{
$idAttribute = $model->getIdAttribute();
$filterValidator = $model->getFilterValidator();
$validationModel = $model->getValidationModel();
//$idAttribute = $model->getIdAttribute();

/**
* Validate primary
Expand All @@ -164,7 +164,12 @@ public function validate(ResourceModel $model) : bool

//Run parse, if any value is incorrect IncorrectParametersException will be thrown
foreach ($this->primary as &$id) {
$id = $idAttributeValidator->parse($id);
$id = $idAttributeValidator
//todo add correct source
->setSource(
new Parameter('filter[' . $model->getResourceType() . ']')
)
->parse($id);
}

/**
Expand All @@ -186,9 +191,10 @@ public function validate(ResourceModel $model) : bool

$relationshipObject = $model->getRelationship($relationshipKey);
$relationshipObjectModel = $relationshipObject->getResourceModel();

$relationshipValidationModel = $relationshipObjectModel->getValidationModel();
$relationshipFilterValidationModel = $relationshipObjectModel->getValidationModel();

$relationshipIdValidator = $relationshipObjectModel->getIdAttributeValidator();

/*$relationshipFilterValidationModel = $relationshipObjectModel->getValidationModel();
if ($relationshipFilterValidationModel !== null
&& isset($relationshipFilterValidationModel->properties->{$relationshipObjectModel->getIdAttribute()})) {
Expand All @@ -205,11 +211,16 @@ public function validate(ResourceModel $model) : bool
];
} else {
$relationshipValidator = [UnsignedIntegerValidator::class, 'parseStatic'];
}
}*/

//Run validator, if any value is incorrect IncorrectParametersException will be thrown
foreach ($relationshipValue as $id) {
call_user_func($relationshipValidator, $id);
$id = $relationshipIdValidator
//todo add correct source
->setSource(
new Parameter('filter[' . $relationshipKey . ']')
)
->parse($id);
}
}
}
Expand All @@ -225,91 +236,110 @@ public function validate(ResourceModel $model) : bool
*/
$filterable = $model->getFilterableAttributes();

foreach ($this->attributes as $filterAttribute) {
$attribute = $filterAttribute->getAttribute();
$operator = $filterAttribute->getOperator();
$operand = $filterAttribute->getOperand();
if (!empty($this->attributes)) {
$filterValidator = $model->getFilterValidator();
$validationModel = $model->getValidationModel(); //used as fallback when $filterValidator is not available

/**
* @var bool
*/
$isJSONFilter = ($filterAttribute instanceof FilterJSONAttribute);
foreach ($this->attributes as $filterAttribute) {
$attribute = $filterAttribute->getAttribute();
$operator = $filterAttribute->getOperator();
$operand = $filterAttribute->getOperand();

if (!property_exists($filterable, $attribute)) {
throw new RequestException(sprintf(
'Filter attribute "%s" not allowed',
$attribute
));
}
//todo add correct source
$source = new Parameter('filter[' . $attribute . ']');

$attributeValidator = null;

//Attempt to use filter validation resourceModel first
//todo rewrite with better indentation
if ($filterValidator
//&& isset($filterValidator)
&& isset($filterValidator->properties->{$attribute})
) {
$attributeValidator =
$filterValidator->properties->{$attribute};
} elseif ($validationModel
&& isset(
$validationModel->attributes,
$validationModel->attributes->properties->{$attribute})
) { //Then attempt to use attribute validation resourceModel first
$attributeValidator =
$validationModel->attributes->properties->{$attribute};
} else {
//todo add source
throw new \Exception(sprintf(
'Filter attribute "%s" has not a filter validator',
$attribute
));
}
/**
* @var bool
*/
$isJSONFilter = ($filterAttribute instanceof FilterJSONAttribute);

$operatorClass = $filterable->{$attribute};
if (!property_exists($filterable, $attribute)) {
//todo add source
throw new RequestException(sprintf(
'Filter attribute "%s" not allowed',
$attribute
));
}

if ($isJSONFilter && ($operatorClass & Operator::CLASS_JSONOBJECT) === 0) {
//todo add source
throw new RequestException(sprintf(
'Filter attribute "%s" is not accepting JSON object filtering',
$attribute
));
}
$attributeValidator = null;

//Check if operator is allowed
if (!$isJSONFilter && !in_array(
$operator,
Operator::getByClassFlags($operatorClass)
)) {
//todo add source
throw new RequestException(sprintf(
'Filter operator "%s" is not allowed for attribute "%s"',
$operator,
$attribute
));
}
//Attempt to use filter validation resourceModel first
//todo rewrite with better indentation
if ($filterValidator
//&& isset($filterValidator)
&& isset($filterValidator->properties->{$attribute})
) {
$attributeValidator =
$filterValidator->properties->{$attribute};
} elseif ($validationModel
&& isset(
$validationModel->attributes,
$validationModel->attributes->properties->{$attribute})
) { //Then attempt to use attribute validation resourceModel first
$attributeValidator =
$validationModel->attributes->properties->{$attribute};
} else {
//todo add source
throw new \Exception(sprintf(
'Filter attribute "%s" has not a filter validator',
$attribute
));
}

$operatorClass = $filterable->{$attribute};

if ($isJSONFilter && ($operatorClass & Operator::CLASS_JSONOBJECT) === 0) {
//todo add source
throw new RequestException(sprintf(
'Filter attribute "%s" is not accepting JSON object filtering',
$attribute
));
}

//Check if operator is allowed
if (!$isJSONFilter && !in_array(
$operator,
Operator::getByClassFlags($operatorClass)
)
) {
//todo add source
throw new RequestException(sprintf(
'Filter operator "%s" is not allowed for attribute "%s"',
$operator,
$attribute
));
}

//Validate filterAttribute operand against filter validator or validator if set
if (!in_array($operator, Operator::getNullableOperators())) {
if ($isJSONFilter) {
//If filter validator is set for dereference JSON object property
if ($filterValidator
&& isset($filterValidator->properties->{$attribute})
&& isset($filterValidator->properties->{$attribute}
->properties->{$filterAttribute->getKey()})
) {
$attributePropertyValidator = $filterValidator->properties
->{$attribute}->properties->{$filterAttribute->getKey()};

$attributePropertyValidator->parse($operand);
//Validate filterAttribute operand against filter validator or validator if set
if (!in_array($operator, Operator::getNullableOperators())) {
if ($isJSONFilter) {
//If filter validator is set for dereference JSON object property
if ($filterValidator
&& isset($filterValidator->properties->{$attribute})
&& isset($filterValidator->properties->{$attribute}
->properties->{$filterAttribute->getKey()})
) {
$attributePropertyValidator = $filterValidator->properties
->{$attribute}->properties->{$filterAttribute->getKey()};

$attributePropertyValidator
//todo add correct pointers
->setSource(
$source
)
->parse($operand);
}
//todo
//} else {
// //**NOTE** Remain unparsed!
//}
} else {
$attributeValidator
->setSource(
$source
)
->parse($operand);
}
//todo
//} else {
// //**NOTE** Remain unparsed!
//}
} else {
$attributeValidator->parse($operand);
}
}
}
Expand Down Expand Up @@ -371,10 +401,10 @@ public static function parseFromRequest(
$values = array_map(
'strval',
array_map('trim', explode(',', trim($filterValue)))
//array_map(
// $function,
// array_map('trim', explode(',', trim($filterValue)))
//)
//array_map(
// $function,
// array_map('trim', explode(',', trim($filterValue)))
//)
);

$filterPrimary = $values;
Expand Down
4 changes: 3 additions & 1 deletion src/Resource.php
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,9 @@ public static function parseFromRecord(
$directives,
$flags
) {
return $relationshipObject->getCallbacks()->{'GET'}(
$cb = $relationshipObject->getCallbacks()->{'GET'};

return $cb(
$resource->id,
$directives,
$flags // use $flagRelationshipsAttributes to enable/disable parsing of relationship attributes
Expand Down

0 comments on commit 369eddc

Please sign in to comment.