1
|
|
|
<?php declare(strict_types=1); |
2
|
|
|
|
3
|
|
|
namespace WyriHaximus\React\Cake\Orm; |
4
|
|
|
|
5
|
|
|
use Cake\Cache\Cache; |
6
|
|
|
use Cake\Core\Configure; |
7
|
|
|
use Cake\Datasource\ConnectionManager; |
8
|
|
|
use Cake\Datasource\Exception\PageOutOfBoundsException; |
9
|
|
|
use Cake\Datasource\Paginator; |
10
|
|
|
use Cake\ORM\Query; |
11
|
|
|
use Cake\ORM\TableRegistry; |
12
|
|
|
use React\EventLoop\LoopInterface; |
13
|
|
|
use React\Promise\Deferred; |
14
|
|
|
use function React\Promise\resolve; |
15
|
|
|
use WyriHaximus\React\ChildProcess\Messenger\ChildInterface; |
16
|
|
|
use WyriHaximus\React\ChildProcess\Messenger\Messages\Payload; |
17
|
|
|
use WyriHaximus\React\ChildProcess\Messenger\Messenger; |
18
|
|
|
use function WyriHaximus\React\futurePromise; |
19
|
|
|
|
20
|
|
|
final class WorkerChild implements ChildInterface |
21
|
|
|
{ |
22
|
|
|
private $messenger; |
23
|
|
|
private $loop; |
24
|
|
|
|
25
|
|
|
/** |
26
|
|
|
* WorkerChild constructor. |
27
|
|
|
*/ |
28
|
|
|
public function __construct(Messenger $messenger, LoopInterface $loop) |
29
|
|
|
{ |
30
|
|
|
$this->messenger = $messenger; |
31
|
|
|
$this->loop = $loop; |
32
|
|
|
|
33
|
|
|
$this->messenger->registerRpc('table.call', function (Payload $payload) { |
34
|
|
|
$deferred = new Deferred(); |
35
|
|
|
$this->loop->futureTick(function () use ($payload, $deferred) { |
36
|
|
|
$this->handleTableCall($payload, $deferred); |
37
|
|
|
}); |
38
|
|
|
|
39
|
|
|
return $deferred->promise(); |
40
|
|
|
}); |
41
|
|
|
|
42
|
|
|
$this->messenger->registerRpc('paginate', function (Payload $payload) { |
43
|
|
|
return futurePromise($this->loop, $payload)->then(function ($payload) { |
44
|
|
|
return $this->handlePaginateCall($payload); |
45
|
|
|
}); |
46
|
|
|
}); |
47
|
|
|
} |
48
|
|
|
|
49
|
|
|
/** |
50
|
|
|
* @inheritDoc |
51
|
|
|
*/ |
52
|
|
|
public static function create(Messenger $messenger, LoopInterface $loop) |
53
|
|
|
{ |
54
|
|
|
require dirname(dirname(dirname(dirname(__DIR__)))) . '/config/paths.php'; |
55
|
|
|
require CORE_PATH . 'config' . DS . 'bootstrap.php'; |
56
|
|
|
Configure::config('default', new Configure\Engine\PhpConfig()); |
57
|
|
|
Configure::load('app', 'default', false); |
58
|
|
|
Cache::setConfig(Configure::consume('Cache')); |
|
|
|
|
59
|
|
|
ConnectionManager::setConfig(Configure::consume('Datasources')); |
|
|
|
|
60
|
|
|
|
61
|
|
|
return new self($messenger, $loop); |
62
|
|
|
} |
63
|
|
|
|
64
|
|
|
/** |
65
|
|
|
* @param Payload $payload |
66
|
|
|
* @param Deferred $deferred |
67
|
|
|
*/ |
68
|
|
|
protected function handleTableCall(Payload $payload, Deferred $deferred) |
69
|
|
|
{ |
70
|
|
|
$result = call_user_func_array([ |
71
|
|
|
TableRegistry::get( |
|
|
|
|
72
|
|
|
$payload['table']/*, |
|
|
|
|
73
|
|
|
[ |
74
|
|
|
'className' => $payload['className'], |
75
|
|
|
'table' => $payload['table'], |
76
|
|
|
]*/ |
77
|
|
|
), |
78
|
|
|
$payload['function'], |
79
|
|
|
], unserialize($payload['arguments'])); |
80
|
|
|
|
81
|
|
|
if (!($result instanceof Query)) { |
82
|
|
|
$deferred->resolve([ |
83
|
|
|
'result' => serialize($result), |
84
|
|
|
]); |
85
|
|
|
|
86
|
|
|
return; |
87
|
|
|
} |
88
|
|
|
|
89
|
|
|
foreach ($result->all() as $row) { |
90
|
|
|
$deferred->notify([ |
|
|
|
|
91
|
|
|
'row' => $row, |
92
|
|
|
]); |
93
|
|
|
} |
94
|
|
|
|
95
|
|
|
$deferred->resolve(); |
96
|
|
|
} |
97
|
|
|
|
98
|
|
|
/** |
99
|
|
|
* @param Payload $payload |
100
|
|
|
* @param Deferred $deferred |
|
|
|
|
101
|
|
|
*/ |
102
|
|
|
protected function handlePaginateCall(Payload $payload) |
103
|
|
|
{ |
104
|
|
|
$object = TableRegistry::get( |
|
|
|
|
105
|
|
|
$payload['table']/*, |
|
|
|
|
106
|
|
|
[ |
107
|
|
|
'className' => $payload['className'], |
108
|
|
|
'table' => $payload['table'], |
109
|
|
|
]*/ |
110
|
|
|
); |
111
|
|
|
$paginator = new Paginator(); |
112
|
|
|
|
113
|
|
|
try { |
114
|
|
|
$items = $paginator->paginate($object, $payload['params'], $payload['settings'])->toArray(); |
115
|
|
|
$eos = false; |
116
|
|
|
} catch (PageOutOfBoundsException $pageOutOfBoundsException) { |
117
|
|
|
$items = []; |
118
|
|
|
$eos = true; |
119
|
|
|
} |
120
|
|
|
|
121
|
|
|
return resolve([ |
122
|
|
|
'items' => $items, |
123
|
|
|
'eos' => $eos, |
124
|
|
|
'pagingParams' => $paginator->getPagingParams(), |
125
|
|
|
]); |
126
|
|
|
} |
127
|
|
|
} |
128
|
|
|
|
This check looks at variables that are passed out again to other methods.
If the outgoing method call has stricter type requirements than the method itself, an issue is raised.
An additional type check may prevent trouble.