Builder::getLastSync()   B
last analyzed

Complexity

Conditions 5
Paths 4

Size

Total Lines 22
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 4
Bugs 0 Features 1
Metric Value
cc 5
eloc 9
c 4
b 0
f 1
nc 4
nop 4
dl 0
loc 22
rs 8.6737
1
<?php namespace Algorit\Synchronizer;
2
3
use Closure;
4
use Exception;
5
use Carbon\Carbon;
6
use Algorit\Synchronizer\Request\RequestInterface;
7
use Algorit\Synchronizer\Storage\SyncRepositoryInterface;
8
use Algorit\Synchronizer\Request\Contracts\SystemInterface;
9
use Algorit\Synchronizer\Request\Contracts\ResourceInterface;
10
11
class Builder {
12
13
	use LoggerTrait;
14
15
	/**
16
	 * The system request instance.
17
	 *
18
	 * @var object
19
	 */
20
	public $request;
21
22
	/**
23
	 * The current resource
24
	 *
25
	 * @var object
26
	 */
27
	protected $resource;
28
29
	/**
30
	 * The database repository instance.
31
	 *
32
	 * @var object
33
	 */
34
	protected $repository;
35
36
	/**
37
	 * The Sender instance.
38
	 *
39
	 * @var Sender
40
	 */
41
	protected $send;
42
43
	/**
44
	 * The Receiver instance.
45
	 *
46
	 * @var Receiver
47
	 */
48
	protected $receive;
49
50
	/**
51
	 * Class constructor.
52
	 *
53
	 * @param \Algorit\Synchronizer\Sender 	 $send
54
	 * @param \Algorit\Synchronizer\Receiver $receive
55
	 * @param \Algorit\Synchronizer\Storage\SyncRepositoryInterface $repository
56
	 * @return void
0 ignored issues
show
Comprehensibility Best Practice introduced by
Adding a @return annotation to constructors is generally not recommended as a constructor does not have a meaningful return value.

Adding a @return annotation to a constructor is not recommended, since a constructor does not have a meaningful return value.

Please refer to the PHP core documentation on constructors.

Loading history...
57
	 */
58
	public function __construct(Sender $send, Receiver $receive, SyncRepositoryInterface $repository)
59
	{
60
		$this->send = $send;
61
		$this->receive = $receive;
62
		$this->repository = $repository;
63
	}
64
65
	/**
66
	 * Set the Request and Resource
67
	 *
68
	 * @param  \Algorit\Synchronizer\Request\Contracts\RequestInterface  $request
69
	 * @param  \Algorit\Synchronizer\Request\Contracts\ResourceInterface $resource
70
	 * @return void
71
	 */
72
	public function start(RequestInterface $request, ResourceInterface $resource)
73
	{
74
		$this->request  = $request;
75
		$this->resource = $resource;
76
	}
77
78
	/**
79
	 * Get the request
80
	 *
81
	 * @param  void
82
	 * @return \Algorit\Synchronizer\Request\Contracts\RequestInterface
83
	 */
84
	public function getRequest()
85
	{
86
		return $this->request;
87
	}
88
89
	/**
90
	 * Get the resource
91
	 *
92
	 * @param  void
93
	 * @return \Algorit\Synchronizer\Request\Contracts\ResourceInterface
94
	 */
95
	public function getResource()
96
	{
97
		return $this->resource;
98
	}
99
100
	/**
101
	 * Create a current sync repository instance.
102
	 *
103
	 * @param  string  $entity
104
	 * @param  string  $type
105
	 * @return \Carbon\Carbon $lastSync
106
	 */
107
	private function createCurrentSync($entity, $type)
108
	{
109
		$sync = array(
110
			'entity'  => $entity,
111
			'type'    => $type,
112
			'class'   => get_class($this->request),
113
			'status'  => 'processing',
114
		);
115
116
		return $this->repository->setCurrentSync($this->repository->create($sync));
117
	}
118
119
	/**
120
	 * Get last sync date from repository. (Or try to...)
121
	 *
122
	 * @param  string|bool  $lastSync
123
	 * @param  string  		$entity
124
	 * @param  string  		$function
125
	 * @return mixed
126
	 */
127
	private function getLastSync($lastSync, $entity, $function, $format = 'Y-m-d H:i:s')
128
	{
129
		if($lastSync instanceof Carbon)
130
		{
131
			return $lastSync;
132
		}
133
134
		// Use 'default' last sync to use the default date on system config.
135
		if($lastSync === 'default' or $lastSync === 'all')
136
		{
137
			return false;
138
		}
139
140
		$lastSync = $this->repository->getLastSync($this->resource, $entity, $function);
141
142
		if($lastSync == false)
143
		{
144
			return false;
145
		}
146
147
		return Carbon::createFromFormat($format, $lastSync->created_at->format($format));
148
	}
149
150
	/**
151
	 * Process a closure inside a try statement
152
	 *
153
	 * @param  string 	$entity
154
	 * @param  mixed 	$lastSync
155
	 * @param  Closure 	$try
156
	 * @return mixed
157
	 */
158
	private function process($entity, $lastSync, $function, Closure $try)
159
	{
160
		$this->logger->info('Processing ' . $entity . ' request');
161
162
		try
163
		{
164
165
			$this->createCurrentSync($entity, $function);
166
167
			$lastSync = $this->getLastSync($lastSync, $entity, $function);
168
169
			return $this->updateBuild($try($entity, $lastSync));
170
		}
171
		catch(Exception $e)
172
		{
173
			return $this->updateFailedBuild($e);
174
		}
175
176
	}
177
178
	/**
179
	 * Update a build
180
	 *
181
	 * @param  array  $response
182
	 * @return array
183
	 */
184
	private function updateBuild(Array $response)
185
	{
186
		$this->repository->updateCurrentSync(array(
187
			'status' 	 => 'success',
188
			'started_at' => array_get($response, 'options')->lastSync->toDateTimeString(),
189
			'url' 	     => array_get($response, 'options')->url,
190
			'response'   => json_encode($response)
191
		));
192
193
		return $response;
194
	}
195
196
	/**
197
	 * Update a failed build
198
	 *
199
	 * @param  \Exception $e
200
	 * @return boolean
201
	 */
202
	private function updateFailedBuild(Exception $e)
203
	{
204
		$this->repository->updateFailedSync($e);
205
206
		$message = get_class($e) 	 . ': '
207
				   . $e->getMessage() . ' in '
208
				   . $e->getFile()    . ' on line '
209
				   . $e->getLine();
210
211
		$this->logger->error($message);
212
213
		return false;
214
	}
215
216
	/**
217
	 * Build from database
218
	 *
219
	 * @param  string  $entity
220
	 * @param  mixed   $lastSync
221
	 * @return array
222
	 */
223
	private function buildFromDatabase($entity, $lastSync)
224
	{
225
		// Receive from Database
226
		$data = $this->receive->fromDatabase($this->request, $entity, $lastSync);
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $data is correct as $this->receive->fromData...st, $entity, $lastSync) (which targets Algorit\Synchronizer\Receiver::fromDatabase()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
227
228
		// Touch current sync to set a new updated_at date.
229
		$this->repository->touchCurrentSync();
230
231
		return $data;
232
	}
233
234
	/**
235
	 * Add options to response
236
	 *
237
	 * @param  array $response
238
	 * @return array
239
	 */
240
	private function addRequestOptions(Array $response)
241
	{
242
		return [
243
			'options'  => $this->getRequest()->getOptions(),
244
			'response' => $response
245
		];
246
	}
247
248
	/**
249
	 * Receive data from ERP and send it to the repository
250
	 *
251
	 * Receive all system data.
252
	 *
253
	 * @param  string  $entity
254
	 * @param  mixed   $lastSync
255
	 * @return array
256
	 */
257
	public function fromErpToDatabase($entity, $lastSync = null)
258
	{
259
		return $this->process($entity, $lastSync, __FUNCTION__, function($entity, $lastSync)
260
		{
261
			// Receive from ERP
262
			$data = $this->receive->fromErp($this->request, $entity, $lastSync);
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $data is correct as $this->receive->fromErp(...st, $entity, $lastSync) (which targets Algorit\Synchronizer\Receiver::fromErp()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
263
264
			// Touch current sync to set a new updated_at date.
265
			$this->repository->touchCurrentSync();
266
267
			// Send to database
268
			$response = $this->send->toDatabase($this->request, $entity, $data);
0 ignored issues
show
Documentation introduced by
$data is of type null, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
Bug introduced by
Are you sure the assignment to $response is correct as $this->send->toDatabase(...equest, $entity, $data) (which targets Algorit\Synchronizer\Sender::toDatabase()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
269
270
			return $this->addRequestOptions($response);
0 ignored issues
show
Documentation introduced by
$response is of type null, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
271
		});
272
	}
273
274
	/**
275
	 * Send data from repository to ERP
276
	 *
277
	 * Usually send orders that was received from device.
278
	 *
279
	 * @param  string 	$entity
280
	 * @param  mixed 	$lastSync
281
	 * @return array
282
	 */
283
	public function fromDatabaseToErp($entity, $lastSync = null)
284
	{
285
		return $this->process($entity, $lastSync, __FUNCTION__, function($entity, $lastSync)
286
		{
287
			// Receive and touch
288
			$data = $this->buildFromDatabase($entity, $lastSync);
289
290
			// Send to ERP
291
			$response = $this->send->toErp($this->request, $entity, $data);
0 ignored issues
show
Bug introduced by
It seems like $data defined by $this->buildFromDatabase($entity, $lastSync) on line 288 can also be of type null; however, Algorit\Synchronizer\Sender::toErp() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
Bug introduced by
Are you sure the assignment to $response is correct as $this->send->toErp($this...equest, $entity, $data) (which targets Algorit\Synchronizer\Sender::toErp()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
292
293
			return $this->addRequestOptions($response);
0 ignored issues
show
Documentation introduced by
$response is of type null, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
294
		});
295
	}
296
297
	/**
298
	 * Send data to Api
299
	 *
300
	 * Send all Device data.
301
	 *
302
	 * @param  string 	$entity
303
	 * @param  mixed 	$lastSync
304
	 * @return array
305
	 */
306
	public function fromDatabaseToApi($entity, $lastSync = null)
307
	{
308
		return $this->process($entity, $lastSync, __FUNCTION__, function($entity, $lastSync)
309
		{
310
			// Receive and touch
311
			$data = $this->buildFromDatabase($entity, $lastSync);
312
313
			// Send to Api
314
			$response = $this->send->toApi($data);
0 ignored issues
show
Bug introduced by
It seems like $data defined by $this->buildFromDatabase($entity, $lastSync) on line 311 can also be of type null; however, Algorit\Synchronizer\Sender::toApi() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
Bug introduced by
Are you sure the assignment to $response is correct as $this->send->toApi($data) (which targets Algorit\Synchronizer\Sender::toApi()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
315
316
			return $this->addRequestOptions($response);
0 ignored issues
show
Documentation introduced by
$response is of type null, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
317
		});
318
	}
319
320
	/**
321
	 * Receive data from Api
322
	 *
323
	 * Usually receive orders from the device.
324
	 *
325
	 * @param  array 	$data
326
	 * @param  string 	$entity
327
	 * @param  mixed 	$lastSync
328
	 * @return array
329
	 */
330
	public function fromApiToDatabase(Array $data, $entity, $lastSync = null)
331
	{
332
		return $this->process($entity, $lastSync, __FUNCTION__, function($entity, $lastSync) use ($data)
0 ignored issues
show
Unused Code introduced by
The parameter $lastSync is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
333
		{
334
			// Touch current sync to set a new updated_at date.
335
			$this->repository->touchCurrentSync();
336
337
			// Send to database
338
			$response = $this->send->toDatabase($this->request, $entity, $data);
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $response is correct as $this->send->toDatabase(...equest, $entity, $data) (which targets Algorit\Synchronizer\Sender::toDatabase()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
339
340
			return $this->addRequestOptions($response);
0 ignored issues
show
Documentation introduced by
$response is of type null, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
341
		});
342
343
	}
344
345
}
346