Skip to content

Commit 72e8ed0

Browse files
committed
Implemented ArrayAdapter;
1 parent 7ee5ed5 commit 72e8ed0

File tree

4 files changed

+381
-0
lines changed

4 files changed

+381
-0
lines changed

spec/suite/Adapters/ArraySpec.php

Lines changed: 252 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,252 @@
1+
<?php
2+
3+
namespace Spec\Adapters;
4+
5+
use DataTables\Adapters\ArrayAdapter;
6+
use DataTables\ParamsParser;
7+
use Phalcon\Mvc\Model\Query;
8+
9+
describe("Array", function() {
10+
11+
beforeEach(function() {
12+
13+
$di = \Phalcon\DI::getDefault();
14+
15+
$query = $di->get('modelsManager')->createQuery("SELECT * FROM \Spec\Models\User")->execute();
16+
$this->array = $query->toArray();
17+
18+
});
19+
20+
it("should work withot any filter", function() {
21+
22+
$dataTables = new ArrayAdapter(20);
23+
$dataTables->setArray($this->array);
24+
$dataTables->setParser(new ParamsParser(10));
25+
26+
$response = $dataTables->getResponse();
27+
expect($dataTables->getParser())->toBeA('object');
28+
expect(array_keys($response))->toBe(['draw', 'recordsTotal', 'recordsFiltered', 'data']);
29+
expect($response['recordsTotal'])->toBe(100);
30+
expect($response['recordsFiltered'])->toBe(100);
31+
expect(count($response['data']))->toBe(10);
32+
33+
foreach($response['data'] as $data) {
34+
expect(array_keys($data))->toBe(['id', 'name', 'email', 'balance', 'DT_RowId']);
35+
expect($data['DT_RowId'])->toBe($data['id']);
36+
}
37+
38+
});
39+
40+
describe("Limit&Offset", function() {
41+
42+
beforeEach(function() {
43+
44+
$_GET = ['start' => 2, 'length' => 1];
45+
46+
});
47+
48+
it("should work with start&length", function() {
49+
50+
$dataTables = new ArrayAdapter(20);
51+
$dataTables->setArray($this->array);
52+
$dataTables->setParser(new ParamsParser(10));
53+
$response = $dataTables->getResponse();
54+
expect(count($response['data']))->toBe(1);
55+
56+
$dataOne = $response['data'];
57+
58+
$_GET['start'] = 3;
59+
$dataTables = new ArrayAdapter(20);
60+
$dataTables->setArray($this->array);
61+
$dataTables->setParser(new ParamsParser(10));
62+
$response = $dataTables->getResponse();
63+
expect(count($response['data']))->toBe(1);
64+
expect($response['data'])->not->toBe($dataOne);
65+
66+
});
67+
68+
it("should work with a filter", function() {
69+
70+
$_GET['search'] = ['value' => 'kr'];
71+
$_GET['columns'] = [
72+
[
73+
'data' => 'name',
74+
'searchable' => "true"
75+
]
76+
];
77+
78+
$dataTables = new ArrayAdapter(20);
79+
$dataTables->setArray($this->array);
80+
$dataTables->setParser(new ParamsParser(10));
81+
$dataTables->setColumns(['name']);
82+
$response = $dataTables->getResponse();
83+
expect(count($response['data']))->toBe(1);
84+
85+
});
86+
87+
afterEach(function() {
88+
89+
unset($_GET);
90+
91+
});
92+
93+
});
94+
95+
it("should work with a global search", function() {
96+
97+
$_GET = [
98+
'search' => ['value' => 'kr'],
99+
'columns' => [
100+
[
101+
'data' => 'name',
102+
'searchable' => "true"
103+
]
104+
]
105+
];
106+
107+
$dataTables = new ArrayAdapter(20);
108+
$dataTables->setArray($this->array);
109+
$dataTables->setColumns(['name', 'email']);
110+
$dataTables->setParser(new ParamsParser(10));
111+
112+
$response = $dataTables->getResponse();
113+
expect(count($response['data']))->toBe(3);
114+
$names = array_reduce($response['data'], function($carry, $item) {
115+
$carry[] = $item['name'];
116+
return $carry;
117+
});
118+
119+
expect($names)->toBe(['krajcik.rylee', 'kraig.mann', 'kara.krajcik']);
120+
121+
});
122+
123+
it("should work with a column search", function() {
124+
125+
$_GET = [
126+
'columns' => [
127+
[
128+
'data' => 'name',
129+
'searchable' => "true",
130+
'search' => [
131+
'value' => 'be'
132+
]
133+
]
134+
]
135+
];
136+
137+
$dataTables = new ArrayAdapter(20);
138+
$dataTables->setArray($this->array);
139+
$dataTables->setColumns(['name', 'email']);
140+
$dataTables->setParser(new ParamsParser(10));
141+
142+
$response = $dataTables->getResponse();
143+
expect(count($response['data']))->toBe(5);
144+
$names = array_reduce($response['data'], function($carry, $item) {
145+
$carry[] = $item['name'];
146+
return $carry;
147+
});
148+
expect($names)->toBe(['beahan.abbigail', 'gebert', 'breitenberg.ted', 'marvin.maybelle', 'zabernathy']);
149+
150+
});
151+
152+
it("should work with a column&global search", function() {
153+
154+
$_GET = [
155+
'columns' => [
156+
[
157+
'data' => 'name',
158+
'searchable' => "true",
159+
'search' => [
160+
'value' => 'be'
161+
]
162+
],
163+
[
164+
'data' => 'email',
165+
'searchable' => "true",
166+
'search' => [
167+
'value' => "@gmail.com"
168+
]
169+
]
170+
]
171+
];
172+
173+
$dataTables = new ArrayAdapter(20);
174+
$dataTables->setArray($this->array);
175+
$dataTables->setColumns(['name', 'email']);
176+
$dataTables->setParser(new ParamsParser(10));
177+
178+
$response = $dataTables->getResponse();
179+
expect(count($response['data']))->toBe(3);
180+
$names = array_reduce($response['data'], function($carry, $item) {
181+
$carry[] = $item['name'];
182+
return $carry;
183+
});
184+
expect($names)->toBe(['gebert', 'marvin.maybelle', 'zabernathy']);
185+
186+
});
187+
188+
it("should order", function() {
189+
190+
$_GET = [
191+
'columns' => [
192+
[
193+
'data' => 'name',
194+
'searchable' => "true",
195+
]
196+
],
197+
'order' => [
198+
[
199+
'column' => 'name',
200+
'dir' => 'desc'
201+
]
202+
]
203+
];
204+
205+
$dataTables = new ArrayAdapter(20);
206+
$dataTables->setArray($this->array);
207+
$dataTables->setColumns(['name', 'email']);
208+
$dataTables->setParser(new ParamsParser(10));
209+
210+
$response = $dataTables->getResponse();
211+
expect(count($response['data']))->toBe(10);
212+
expect($response['data'][0]['name'])->toBe('zcremin');
213+
214+
});
215+
216+
it("should order asc", function() {
217+
218+
$_GET = [
219+
'columns' => [
220+
[
221+
'data' => 'name',
222+
'searchable' => "true",
223+
]
224+
],
225+
'order' => [
226+
[
227+
'column' => 'name',
228+
'dir' => 'asc'
229+
]
230+
]
231+
];
232+
233+
$dataTables = new ArrayAdapter(20);
234+
$dataTables->setArray($this->array);
235+
$dataTables->setColumns(['name', 'email']);
236+
$dataTables->setParser(new ParamsParser(10));
237+
238+
$response = $dataTables->getResponse();
239+
expect(count($response['data']))->toBe(10);
240+
expect($response['data'][0]['name'])->toBe('adelia13');
241+
242+
});
243+
244+
afterEach(function() {
245+
246+
unset($_GET);
247+
unset($_POST);
248+
unset($_REQUEST);
249+
250+
});
251+
252+
});

spec/suite/DataTableSpec.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,32 @@
3838

3939
});
4040

41+
it("should create a ArrayAdapter", function() {
42+
43+
$array = $this->di->get('modelsManager')
44+
->createQuery("SELECT * FROM \Spec\Models\User")
45+
->execute()->toArray();
46+
47+
$dataTables = new DataTable();
48+
$response = $dataTables->fromArray($array)->getResponse();
49+
expect($dataTables->getParams())->toBe([
50+
"draw" => null,
51+
"start" => 1,
52+
"length" => 20,
53+
"columns" => [],
54+
"search" => [],
55+
"order" => []
56+
]);
57+
expect(count($response['data']))->toBe(20);
58+
expect(array_keys($response))->toBe(['draw', 'recordsTotal', 'recordsFiltered', 'data']);
59+
60+
foreach($response['data'] as $data) {
61+
expect(array_keys($data))->toBe(['id', 'name', 'email', 'balance', 'DT_RowId']);
62+
expect($data['DT_RowId'])->toBe($data['id']);
63+
}
64+
65+
});
66+
4167
it("should create a QueryBuilder", function() {
4268

4369
$builder = $this->di->get('modelsManager')

src/Adapters/ArrayAdapter.php

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
<?php
2+
3+
namespace DataTables\Adapters;
4+
5+
class ArrayAdapter extends AdapterInterface {
6+
7+
protected $array = [];
8+
protected $filter = [];
9+
protected $order = [];
10+
11+
public function setArray(array $array) {
12+
$this->array = $array;
13+
}
14+
15+
public function getResponse() {
16+
$limit = $this->parser->getLimit();
17+
$offset = $this->parser->getOffset();
18+
$total = count($this->array);
19+
20+
$this->bind('global_search', function($column, $search) {
21+
$this->filter[$column][] = $search;
22+
});
23+
24+
$this->bind('column_search', function($column, $search) {
25+
$this->filter[$column][] = $search;
26+
});
27+
28+
$this->bind('order', function($order) {
29+
$this->order = $order;
30+
});
31+
32+
if(count($this->filter)) {
33+
$items = array_filter($this->array, function($item) {
34+
$check = true;
35+
36+
foreach($this->filter as $column=>$filters) {
37+
foreach($filters as $search) {
38+
$check = (strpos($item[$column], $search) !== false);
39+
if (!$check) break 2;
40+
}
41+
}
42+
43+
if ($check) {
44+
return $item;
45+
}
46+
});
47+
} else {
48+
$items = $this->array;
49+
}
50+
51+
$filtered = count($items);
52+
53+
if ($this->order) {
54+
$args = [];
55+
56+
foreach($this->order as $order) {
57+
$tmp = [];
58+
list($column, $dir) = explode(' ', $order);
59+
60+
foreach($items as $key=>$item) {
61+
$tmp[$key] = $item[$column];
62+
}
63+
64+
$args[] = $tmp;
65+
$args[] = ($dir == 'desc') ? SORT_DESC : SORT_ASC;
66+
}
67+
68+
69+
$args[] = &$items;
70+
call_user_func_array('array_multisort', $args);
71+
}
72+
73+
if ($offset > 1) {
74+
$items = array_slice($items, $offset);
75+
}
76+
77+
if ($limit) {
78+
$items = array_slice($items, 0, $limit);
79+
}
80+
81+
return $this->formResponse([
82+
'total' => (int)$total,
83+
'filtered' => (int)$filtered,
84+
'data' => $items,
85+
]);
86+
}
87+
88+
}

0 commit comments

Comments
 (0)