Skip to content

Commit

Permalink
Before handler to facilitate #151
Browse files Browse the repository at this point in the history
  • Loading branch information
mevdschee committed Mar 12, 2017
1 parent 7ff9ff9 commit 4cf339c
Show file tree
Hide file tree
Showing 7 changed files with 48 additions and 13 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ $api = new PHP_CRUD_API(array(
'tenancy_function'=>function($cmd,$db,$tab,$col) { return null; },
'input_sanitizer'=>function($cmd,$db,$tab,$col,$typ,$val) { return $val; },
'input_validator'=>function($cmd,$db,$tab,$col,$typ,$val,$ctx) { return true; },
'before'=>function($cmd,$db,$tab,$id,$in) { /* adjust array $in */ },
'after'=>function($cmd,$db,$tab,$id,$in,$out) { /* do something */ },
// configurable options
'allow_origin'=>'*',
Expand Down Expand Up @@ -756,6 +757,11 @@ PUT http://localhost/api.php/categories/2
{"name":"Internet","icon":null}
```

## Automatic fields

Before any operation the 'before' function is called that allows you to do set some automatic fields.
Note that the 'inputs' parameter is writable and is an array. The array may contain NULL values on invalid JSON.

## Custom actions

After any operation the 'after' function is called that allows you to do some custom actions.
Expand Down
23 changes: 19 additions & 4 deletions api.php
Original file line number Diff line number Diff line change
Expand Up @@ -1134,14 +1134,25 @@ protected function parseGetParameterArray($get,$name,$characters) {
return $values;
}

protected function applyBeforeHandler($parameters,&$inputs) {
$callback = $parameters['before'];
if (is_callable($callback,true)) {
$action = $parameters['action'];
$database = $parameters['database'];
$table = $parameters['tables'][0];
$id = $parameters['key'][0];
$callback($action,$database,$table,$id,$inputs);
}
}

protected function applyAfterHandler($parameters,$output) {
$callback = $parameters['after'];
if (is_callable($callback,true)) {
$action = $parameters['action'];
$database = $parameters['database'];
$table = $parameters['tables'][0];
$id = $parameters['key'][0];
$input = isset($parameters['inputs'])?$parameters['inputs']:false;
$input = $parameters['inputs'];
$callback($action,$database,$table,$id,$input,$output);
}
}
Expand Down Expand Up @@ -1868,11 +1879,14 @@ protected function getParameters($settings) {
if ($column_authorizer) $this->applyColumnAuthorizer($column_authorizer,$action,$database,$fields);

$multi = strpos($key[0],',')!==false;
$inputs = array();
if (strlen($post)) {
// input
$multi = $post[0]=='[';
$contexts = $this->retrieveInputs($post);
$inputs = array();
if ($before) {
$this->applyBeforeHandler(compact('action','database','tables','key','before'),$contexts);
}
foreach ($contexts as $context) {
$input = $this->filterInputByFields($context,$fields[$tables[0]]);

Expand All @@ -1885,7 +1899,7 @@ protected function getParameters($settings) {
}
}

return compact('action','database','tables','key','page','filters','fields','orderings','transform','multi','inputs','collect','select','after');
return compact('action','database','tables','key','page','filters','fields','orderings','transform','multi','inputs','collect','select','before','after');
}

protected function addWhereFromFilters($filters,&$sql,&$params) {
Expand Down Expand Up @@ -2121,6 +2135,7 @@ public function __construct($config) {
$input_validator = isset($input_validator)?$input_validator:null;
$auto_include = isset($auto_include)?$auto_include:null;
$allow_origin = isset($allow_origin)?$allow_origin:null;
$before = isset($before)?$before:null;
$after = isset($after)?$after:null;

$db = isset($db)?$db:null;
Expand Down Expand Up @@ -2173,7 +2188,7 @@ public function __construct($config) {
}

$this->db = $db;
$this->settings = compact('method', 'request', 'get', 'post', 'origin', 'database', 'table_authorizer', 'record_filter', 'column_authorizer', 'tenancy_function', 'input_sanitizer', 'input_validator', 'after', 'auto_include', 'allow_origin');
$this->settings = compact('method', 'request', 'get', 'post', 'origin', 'database', 'table_authorizer', 'record_filter', 'column_authorizer', 'tenancy_function', 'input_sanitizer', 'input_validator', 'before', 'after', 'auto_include', 'allow_origin');
}

public static function php_crud_api_transform(&$tables) {
Expand Down
5 changes: 3 additions & 2 deletions tests/blog_mysql.sql
Original file line number Diff line number Diff line change
Expand Up @@ -125,10 +125,11 @@ CREATE TABLE `products` (
`name` varchar(255) NOT NULL,
`price` decimal(10,2) NOT NULL,
`properties` JSON NOT NULL,
`created_at` datetime(3) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

INSERT INTO `products` (`id`, `name`, `price`, `properties`) VALUES
(1, 'Calculator', '23.01', '{"depth":false,"model":"TRX-120","width":100,"height":null}');
INSERT INTO `products` (`id`, `name`, `price`, `properties`, `created_at`) VALUES
(1, 'Calculator', '23.01', '{"depth":false,"model":"TRX-120","width":100,"height":null}', '1970-01-01 01:01:01.001');

-- 2016-11-05 13:11:47
7 changes: 4 additions & 3 deletions tests/blog_postgresql.sql
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,8 @@ CREATE TABLE products (
id serial NOT NULL,
name character varying(255) NOT NULL,
price decimal(10,2) NOT NULL,
properties jsonb NOT NULL
properties jsonb NOT NULL,
created_at timestamp NOT NULL
);

--
Expand Down Expand Up @@ -204,8 +205,8 @@ INSERT INTO "events" ("name", "datetime", "visitors") VALUES
-- Data for Name: events; Type: TABLE DATA; Schema: public; Owner: postgres
--

INSERT INTO "products" ("name", "price", "properties") VALUES
('Calculator', '23.01', '{"depth":false,"model":"TRX-120","width":100,"height":null}');
INSERT INTO "products" ("name", "price", "properties", "created_at") VALUES
('Calculator', '23.01', '{"depth":false,"model":"TRX-120","width":100,"height":null}', '1970-01-01 01:01:01.001');

--
-- Name: categories_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace:
Expand Down
5 changes: 3 additions & 2 deletions tests/blog_sqlite.sql
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,10 @@ CREATE TABLE `products` (
`id` integer NOT NULL PRIMARY KEY AUTOINCREMENT,
`name` text(255) NOT NULL,
`price` text(12) NOT NULL,
`properties` json NOT NULL
`properties` json NOT NULL,
`created_at` datetime NOT NULL
);

INSERT INTO `products` (`id`, `name`, `price`, `properties`) VALUES (1, 'Calculator', '23.01', '{"depth":false,"model":"TRX-120","width":100,"height":null}');
INSERT INTO `products` (`id`, `name`, `price`, `properties`, `created_at`) VALUES (1, 'Calculator', '23.01', '{"depth":false,"model":"TRX-120","width":100,"height":null}', '1970-01-01 01:01:01.001');

--
3 changes: 2 additions & 1 deletion tests/blog_sqlserver.sql
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ CREATE TABLE [products](
[name] [nvarchar](max) NOT NULL,
[price] [decimal](10,2) NOT NULL,
[properties] [xml] NOT NULL,
[created_at] [datetime2](3) NOT NULL,
CONSTRAINT [PK_products] PRIMARY KEY CLUSTERED
(
[id] ASC
Expand Down Expand Up @@ -288,7 +289,7 @@ SET IDENTITY_INSERT [events] OFF
GO
SET IDENTITY_INSERT [products] ON
GO
INSERT [products] ([id], [name], [price], [properties]) VALUES (1, N'Calculator', N'23.01', N'<root type="object"><depth type="boolean">false</depth><model type="string">TRX-120</model><width type="number">100</width><height type="null" /></root>')
INSERT [products] ([id], [name], [price], [properties], [created_at]) VALUES (1, N'Calculator', N'23.01', N'<root type="object"><depth type="boolean">false</depth><model type="string">TRX-120</model><width type="number">100</width><height type="null" /></root>', '1970-01-01 01:01:01.001')
GO
SET IDENTITY_INSERT [products] OFF
GO
Expand Down
12 changes: 11 additions & 1 deletion tests/tests.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ private function action($method,$url,$data='')
'tenancy_function'=>function($action,$database,$table,$column) { return ($table=='users'&&$column=='id')?1:null; },
'input_sanitizer'=>function($action,$database,$table,$column,$type,$value) { return is_string($value)?strip_tags($value):$value; },
'input_validator'=>function($action,$database,$table,$column,$type,$value,$context) { return ($column=='category_id' && !is_numeric($value))?'must be numeric':true; },
'after' => function ($action,$database,$table,$id,$input,$output) { file_put_contents('log.txt',var_export(array($action,$database,$table,$id,$input,$output),true),FILE_APPEND); },
'before' => function ($action,$database,$table,$id,$inputs) { if ($action=='create') foreach ($inputs as $input) if ($input) $input->created_at = date('Y-m-d H:i:s',1386752948); },
'after' => function ($action,$database,$table,$id,$inputs,$output) { file_put_contents('log.txt',var_export(array($action,$database,$table,$id,$inputs,$output),true),FILE_APPEND); },
// for tests
'method' =>$method,
'request' =>$url['path'],
Expand Down Expand Up @@ -780,4 +781,13 @@ public function testWriteProductProperties()
$test->get('/products/1?columns=id,properties');
$test->expect('{"id":1,"properties":{"depth":false,"model":"TRX-120","width":100,"height":123}}');
}

public function testAddProducts()
{
$test = new API($this);
$test->post('/products','{"name":"Laptop","price":"1299.99"}');
$test->expect('2');
$test->get('/products/2');
$test->expect('{"id":2,"name":"Laptop","price":"1299.99","properties":null,"created_at":"2013-12-11 10:09:08.000"}');
}
}

0 comments on commit 4cf339c

Please sign in to comment.