Skip to content

Instantly share code, notes, and snippets.

@danharper
Last active August 29, 2015 14:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save danharper/6f9cc956f2855a327d7e to your computer and use it in GitHub Desktop.
Save danharper/6f9cc956f2855a327d7e to your computer and use it in GitHub Desktop.
query params. experiment in something a little different
<?php
namespace param {
class QueryParam {
const SINGLE = 'single';
const MANY = 'many';
const MANY_CSV = 'csv';
public $queryField;
private $nullable = false;
private $type = self::SINGLE;
private $eachLimitations = [];
function __construct($queryField) {
$this->queryField = $queryField;
}
function int() {
$this->eachLimitations[] = new IntParam;
return $this;
}
function many() {
$this->type = static::MANY;
return $this;
}
function many_csv() {
$this->type = static::MANY_CSV;
return $this;
}
function nullable() {
$this->nullable = true;
return $this;
}
function only($only) {
$this->eachLimitations[] = new OneOfParam($only);
return $this;
}
function __invoke($input) {
$input = $this->runType($input);
if (is_array($input)) {
$input = array_map(function($in) { return $this->runLimitations($in); }, $input);
if ( ! $this->nullable) {
$input = array_filter($input, function($in) {
return ! is_null($in) && $in !== Param::NOPE;
});
}
$input = array_values($input);
return $input;
}
else {
$input = $this->runLimitations($input);
if ( ! $this->nullable && is_null($input)) {
$input = Param::NOPE;
}
return $input;
}
}
private function runLimitations($input) {
return array_reduce($this->eachLimitations, function($carry, $limitation) {
return call_user_func($limitation, $carry);
}, $input);
}
private function runType($input) {
if ($this->type === static::SINGLE) {
return is_array($input) ? reset($input) : $input;
}
if ($this->type === static::MANY) {
return is_array($input) ? $input : [$input];
}
if ($this->type === static::MANY_CSV && ! is_array($input)) {
return explode(',', $input);
}
return $input;
}
}
abstract class Param {
const NOPE = 'n9qughouy(&YU@H97t2uoehjdOUYGHPifj0qo9272)_+_=';
}
class IntParam extends Param {
function __invoke($input) {
return is_numeric($input) ? intval($input) : static::NOPE;
}
}
class StringParam extends Param {
function __invoke($input) {
return (string) $input;
}
}
class OneOfParam extends Param {
function __construct($oneOf) {
$this->oneOf = $oneOf;
}
function __invoke($input) {
return in_array($input, $this->oneOf) ? $input : static::NOPE;
}
}
function to($queryField) {
return new QueryParam($queryField);
}
function run($inputs, $map, $queryObject) {
foreach ($map as $inputField => $param) {
$result = call_user_func($param, $inputs[$inputField]);
if ($result !== Param::NOPE) {
$queryField = $param->queryField;
$queryObject->$queryField = $result;
}
}
return $queryObject;
}
}
namespace {
class InspectionState { const STATES = [100,200,300,400,500,900]; }
$map = [
'state_id' => param\to('stateId')->int()->many_csv()->only(InspectionState::STATES),
'clerk_id' => param\to('clerkId')->int()->nullable(),
];
$input = [
'state_id' => '100,foo,200,0',
'clerk_id' => ['22'],
];
$queryObject = (object) [];
$queryObject = param\run($input, $map, $queryObject);
print_r($queryObject);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment