Test Failed
Pull Request — master (#125)
by Litera
08:36
created

VisitorModel::findById()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace App\Models;
4
5
use Nette\Database\Context;
6
use Nette\Utils\Strings;
7
use \Exception;
8
use DateTime;
9
10
/**
11
 * Visitor
12
 *
13
 * class for handling visitors
14
 *
15
 * @created 2012-11-07
16
 * @author Tomas Litera <[email protected]>
17
 */
18
class VisitorModel extends BaseModel
19
{
20
21
	/** @var string	search pattern */
22
	public $search;
23
24
	/** @var Meeting Meeting class */
25
	public $Meeting;
26
27
	/** @var Meal Meals class */
28
	public $Meals;
29
30
	/** @var Program Programs class */
31
	public $Programs;
32
33
	/** @var Blocks Blocks class */
34
	public $Blocks;
35
36
	/** @var int meeting price */
37
	public $meeting_price;
38
39
	/** @var int meeting advance */
40
	private $meeting_advance;
41
42
	/**
43
	 * Array of database programs table columns
44
	 *
45
	 * @var array	dbColumns[]
46
	 */
47
	public $dbColumns = array();
48
49
	/**
50
	 * Array of form names
51
	 *
52
	 * @var array	formNames[]
53
	 */
54
	public $formNames = array();
55
56
	protected $table = 'kk_visitors';
57
58
	protected $columns = [
59
		'name',
60
		'surname',
61
		'nick',
62
		'email',
63
		'birthday',
64
		'street',
65
		'city',
66
		'postal_code',
67
		'group_num',
68
		'group_name',
69
		'troop_name',
70
		'province',
71
		'arrival',
72
		'departure',
73
		'comment',
74
		'question',
75
		'question2',
76
		'bill',
77
		'cost',
78
		'meeting',
79
	];
80
81
	/** konstruktor */
82
	public function __construct(
83
		MeetingModel $Meeting,
84
		MealModel $Meals,
85
		ProgramModel $Program,
86
		BlockModel $Blocks,
87
		Context $database
88
	) {
89
		$this->Meeting = $Meeting;
0 ignored issues
show
Documentation Bug introduced by
It seems like $Meeting of type object<App\Models\MeetingModel> is incompatible with the declared type object<App\Models\Meeting> of property $Meeting.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
90
		$this->meeting_price = $this->Meeting->getPrice('cost');
91
		$this->meeting_advance = $this->Meeting->getPrice('advance');
92
		$this->Meals = $Meals;
0 ignored issues
show
Documentation Bug introduced by
It seems like $Meals of type object<App\Models\MealModel> is incompatible with the declared type object<App\Models\Meal> of property $Meals.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
93
		$this->Programs = $Program;
0 ignored issues
show
Documentation Bug introduced by
It seems like $Program of type object<App\Models\ProgramModel> is incompatible with the declared type object<App\Models\Program> of property $Programs.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
94
		$this->Blocks = $Blocks;
0 ignored issues
show
Documentation Bug introduced by
It seems like $Blocks of type object<App\Models\BlockModel> is incompatible with the declared type object<App\Models\Blocks> of property $Blocks.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
95
		$this->dbColumns = array(
96
								"guid",
97
								"name",
98
								"surname",
99
								"nick",
100
								"birthday",
101
								"street",
102
								"city",
103
								"postal_code",
104
								"province",
105
								"group_num",
106
								"group_name",
107
								"troop_name",
108
								"bill",
109
								"cost",
110
								"email",
111
								"comment",
112
								"arrival",
113
								"departure",
114
								"question",
115
								"question2",
116
								"checked",
117
								"meeting",
118
								"hash"
119
							);
120
		$this->formNames = array("name", "description", "material", "tutor", "email", "capacity", "display_in_reg", "block", "category");
121
		$this->database = $database;
122
	}
123
124
	/**
125
	 * @return array
126
	 */
127
	public function getColumns()
128
	{
129
		return $this->columns;
130
	}
131
132
	/**
133
	 * Create a new visitor
134
	 *
135
	 * @return	string
136
	 */
137
	public function assemble(array $DB_data, $meals_data, $programs_data, $returnGuid = false)
138
	{
139
		$return = true;
140
141
		if(!$DB_data['province']) {
142
			$DB_data['province'] = 0;
143
		}
144
145
		$DB_data['birthday'] = new \DateTime($DB_data['birthday']);
146
		$DB_data['reg_daytime'] = (new \DateTime())->format('Y-m-d H:i:s');
147
		$DB_data['guid'] = md5(uniqid());
148
149
		$ID_visitor = $this->database
150
			->table($this->getTable())
151
			->insert($DB_data)->id;
152
153
		// visitor's id is empty and i must add one
154
		$meals_data['visitor'] = $ID_visitor;
155
156
		if($ID_visitor){
157
			// gets data from database
158
			$program_blocks = $this->Blocks->getProgramBlocks($DB_data['meeting']);
159
160
			foreach($program_blocks as $DB_blocks_data) {
161
				$bindingsData = array(
162
					'visitor' => $ID_visitor,
163
					'program' => $programs_data[$DB_blocks_data['id']],
164
				);
165
				// insert into binding table
166
				// var programs_data contains requested values in format block-id => program-id
167
				$bindingsData['guid'] = md5(uniqid());
168
				$result_binding = $this->database->query('INSERT INTO `kk_visitor-program`', $bindingsData);
169
170
				if(!$result_binding) {
171
					throw new Exception('Error while binding visitor`s program');
172
				}
173
			}
174
175
			if($return) {
176
177
				// create meals for visitor
178
				if(!$return = $this->Meals->create($meals_data)) {
179
					throw new Exception('Error while creating meals');
180
				}
181
			}
182
		} else {
183
			throw new Exception('Error while creating visitor');
184
		}
185
186
		//return $return;
187
		if($returnGuid) {
188
			return $DB_data['guid'];
189
		} else {
190
			return $ID_visitor;
191
		}
192
	}
193
194
	/**
195
	 * Modify a visitor
196
	 *
197
	 * @param	int		$visitor_id		ID of a visitor
0 ignored issues
show
Bug introduced by
There is no parameter named $visitor_id. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
198
	 * @param	array	$db_data		Visitor's database data
0 ignored issues
show
Documentation introduced by
There is no parameter named $db_data. Did you maybe mean $DB_data?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
199
	 * @param	array	$meals_data		Data of meals
200
	 * @param	array	$programs_data	Program's data
201
	 * @return	mixed					TRUE or array of errors
202
	 */
203
	public function modify($ID_visitor, $DB_data, $meals_data, $programs_data)
204
	{
205
		// for returning specific error
206
		$error = array('visitor' => true, 'meal' => true, 'program' => true);
207
208
		$DB_data['birthday'] = $this->convertToDateTime($DB_data['birthday']);
209
210
		$result = $this->database
0 ignored issues
show
Unused Code introduced by
$result is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
211
			->table($this->getTable())
212
			->where('id', $ID_visitor)
213
			->update($DB_data);
214
215
		// change meals
216
		$result = $this->Meals->update($ID_visitor, $meals_data);
217
		$error['meal'] = $result;
218
219
		// gets data from database
220
		$programBlocks = $this->Blocks->getProgramBlocks($DB_data['meeting']);
221
222
		// get program of visitor
223
		$oldPrograms = $this->getVisitorPrograms($ID_visitor);
224
225
		// update old data to new existing
226 View Code Duplication
		foreach($programBlocks as $programBlock) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
227
			$data = array('program' => $programs_data[$programBlock->id]);
228
			// read first value from array and shift it to the end
229
			$oldProgram = array_shift($oldPrograms);
230
231
			$result = $this->database
0 ignored issues
show
Unused Code introduced by
$result is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
232
				->table('kk_visitor-program')
233
				->where('visitor ? AND id ?', $ID_visitor, (empty($oldProgram)) ? $oldProgram : $oldProgram->id)
234
				->update($data);
235
		}
236
237
		return $ID_visitor;
238
	}
239
240
	/**
241
	 * Modify a visitor
242
	 *
243
	 * @param	int		$visitor_id		ID of a visitor
0 ignored issues
show
Bug introduced by
There is no parameter named $visitor_id. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
244
	 * @param	array	$db_data		Visitor's database data
0 ignored issues
show
Documentation introduced by
There is no parameter named $db_data. Did you maybe mean $DB_data?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
245
	 * @param	array	$meals_data		Data of meals
246
	 * @param	array	$programs_data	Program's data
247
	 * @return	mixed					TRUE or array of errors
248
	 */
249
	public function modifyByGuid($guid, $DB_data, $meals_data, $programs_data)
250
	{
251
		// for returning specific error
252
		$error = array('visitor' => true, 'meal' => true, 'program' => true);
253
254
		$DB_data['birthday'] = new \DateTime($DB_data['birthday']);
255
256
		$result = $this->database
0 ignored issues
show
Unused Code introduced by
$result is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
257
			->table($this->getTable())
258
			->where('guid', $guid)
259
			->update($DB_data);
260
261
		$visitor = $this->findByGuid($guid);
262
263
		// change meals
264
		$result = $this->Meals->update($visitor->id, $meals_data);
265
		$error['meal'] = $result;
266
267
		// gets data from database
268
		$programBlocks = $this->Blocks->getProgramBlocks($DB_data['meeting']);
269
270
		// get program of visitor
271
		$oldPrograms = $this->getVisitorPrograms($visitor->id);
272
273
		// update old data to new existing
274 View Code Duplication
		foreach($programBlocks as $programBlock) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
275
			$data = array('program' => $programs_data[$programBlock->id]);
276
			// read first value from array and shift it to the end
277
			$oldProgram = array_shift($oldPrograms);
278
279
			$result = $this->getDatabase()
0 ignored issues
show
Unused Code introduced by
$result is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
280
				->table('kk_visitor-program')
281
				->where('visitor ? AND id ?', $visitor->id, (empty($oldProgram)) ? $oldProgram : $oldProgram->id)
282
				->update($data);
283
		}
284
285
		return $guid;
286
	}
287
288
	/**
289
	 * Delete one or multiple record/s
290
	 *
291
	 * @param	int		ID/s of record
292
	 * @return	boolean
293
	 */
294
	public function delete($id)
295
	{
296
		return $this->getDatabase()
297
			->table($this->getTable())
298
			->where('id', $id)
299
			->update([
300
				'deleted' => '1'
301
			]);
302
	}
303
304
	/**
305
	 * Set as checked one or multiple record/s
306
	 *
307
	 * @param	int		ID/s of record
308
	 * @param 	int 	0 | 1
309
	 * @return	boolean
310
	 */
311
	public function checked($id, $value)
312
	{
313
		$checked = ['checked' => $value];
314
315
		return $this->getDatabase()
316
			->table($this->getTable())
317
			->where('id', $id)
318
			->update($checked);
319
	}
320
321
	/**
322
	 * Get count of visitors
323
	 *
324
	 * @return  integer
325
	 */
326
	public function getCount()
327
	{
328
		return $this->getDatabase()
329
			->table($this->getTable())
330
			->where('meeting ? AND deleted ?', $this->getMeetingId(), '0')
331
			->count('id');
332
	}
333
334
	/**
335
	 * @param  string $search
336
	 * @return $this
337
	 */
338
	public function setSearch($search)
339
	{
340
		$this->search = $search;
341
342
		return $this;
343
	}
344
345
	/**
346
	 * @return string
347
	 */
348
	protected function getSearch()
349
	{
350
		return $this->search;
351
	}
352
353
	/**
354
	 * @return string
355
	 */
356
	protected function buildSearchQuery()
357
	{
358
		$search = $this->getSearch();
359
360
		$query = '';
361
		if($search) {
362
			$query = "AND (`code` REGEXP '" . $search . "'
363
							OR `group_num` REGEXP '" . $search . "'
364
							OR `name` REGEXP '" . $search . "'
365
							OR `surname` REGEXP '" . $search . "'
366
							OR `nick` REGEXP '" . $search . "'
367
							OR `city` REGEXP '" . $search . "'
368
							OR `group_name` REGEXP '" . $search . "')";
369
		}
370
371
		return $query;
372
	}
373
374
	/**
375
	 * Modify the visitor's bill
376
	 *
377
	 * @param	int	ID/s of visitor
378
	 * @param	string	type of payment (pay | advance)
379
	 * @return	string	error message or true
380
	 */
381
	public function payCharge($query_id, $type)
382
	{
383
		$billData = $this->getBill($query_id);
384
385
		if($billData['bill'] < $this->Meeting->getPrice('cost')) {
386
			$bill = array('bill' => $this->Meeting->getPrice($type));
387
			$payResult = $this->getDatabase()
388
				->table($this->getTable())
389
				->where('id', $query_id)
390
				->update($bill);
391
392
			return $payResult;
393
		} else {
394
			throw new Exception('Charge already paid!');
395
		}
396
	}
397
398
	/**
399
	 * Get recipients by ids
400
	 *
401
	 * @param	mixed	ID of visitor
402
	 * @return	mixed	result
403
	 */
404
	public function getRecipients($ids)
405
	{
406
		return $this->getDatabase()
407
			->table($this->getTable())
408
			->select('email', 'name', 'surname')
409
			->where('id', $ids)
410
			->where('deleted', '0')
411
			->fetchAll();
412
	}
413
414
	/**
415
	 * Get visitor's programs
416
	 *
417
	 * @param	int		ID of visitor
418
	 * @return	mixed	result
419
	 */
420
	public function getVisitorPrograms($visitorId)
421
	{
422
		return $this->getDatabase()
423
			->table('kk_visitor-program')
424
			->select('id, program')
425
			->where('visitor', $visitorId)
426
			->fetchAll();
427
	}
428
429
	/**
430
	 * @param  string|DateTime $datetime
431
	 * @return DateTime
432
	 */
433
	protected function convertToDateTime($datetime): DateTime
434
	{
435
		if (is_string($datetime)) {
436
			$datetime = new DateTime($datetime);
437
		}
438
439
		return $datetime;
440
	}
441
442
	/**
443
	 * Render program switcher for unique visitor
444
	 *
445
	 * @param	int		ID of meeting
446
	 * @param	int		ID of visitor
447
	 * @return	string	html
448
	 */
449
	public function renderProgramSwitcher($meetingId, $visitorId)
450
	{
451
		$html = "";
452
453
		// gets data from database
454
		$programBlocks = $this->Blocks->getProgramBlocks($meetingId);
455
456
		// table is empty
457
		if(!$programBlocks){
458
			$html .= "<div class='emptyTable' style='width:400px;'>Nejsou žádná aktuální data.</div>\n";
459
		} else {
460
			foreach($programBlocks as $block) {
461
				$html .= "<div class='block-" . $block->id .  " ".Strings::webalize($block['day'])."'>".$block['day'].", ".$block['from']." - ".$block['to']." : ".$block['name']."</div>\n";
462
				// rendering programs in block
463
				if($block['program'] == 1) {
464
					$html .= "<div class='block-" . $block->id .  " programs ".Strings::webalize($block['day'])." ".Strings::webalize($block['name'])."'>".$this->Programs->getPrograms($block['id'], $visitorId)."</div>";
465
				}
466
				$html .= "<br />";
467
			}
468
		}
469
470
		return $html;
471
	}
472
473
	/**
474
	 * @return Row
475
	 */
476
	public function all()
477
	{
478
		return $this->getDatabase()->query('SELECT 	vis.id AS id,
479
								vis.guid AS guid,
480
								code,
481
								name,
482
								surname,
483
								nick,
484
								email,
485
								group_name,
486
								group_num,
487
								city,
488
								province_name AS province,
489
								bill,
490
								cost,
491
								birthday,
492
								checked
493
						FROM kk_visitors AS vis
494
						LEFT JOIN kk_provinces AS provs ON vis.province = provs.id
495
						WHERE meeting = ? AND vis.deleted = ? ' . $this->buildSearchQuery() . '
496
						ORDER BY vis.id ASC',
497
						$this->getMeetingId(), '0')->fetchAll();
498
	}
499
500
	/**
501
	 * Return visitor by id
502
	 *
503
	 * @param  int    $id
504
	 * @return ActiveRow
505
	 */
506
	public function findById($id)
507
	{
508
		return $this->find($id);
509
	}
510
511
	/**
512
	 * Return visitor by guid
513
	 *
514
	 * @param  string  $guid
515
	 * @return ActiveRow
516
	 */
517
	public function findByGuid($guid)
518
	{
519
		return $this->findBy('guid', $guid);
520
	}
521
522
	/**
523
	 * @param  array  $queryId
524
	 * @return string
525
	 */
526
	public function getSerializedMailAddress(array $queryId = [])
527
	{
528
		$recipientMailAddresses = '';
529
530
		$emails = $this->getDatabase()
531
			->table($this->getTable())
532
			->select('email')
533
			->where('id', $queryId)
534
			->group('email')
535
			->fetchAll();
536
537
		foreach($emails as $item){
538
			$recipientMailAddresses .= $item['email'] . ",\n";
539
		}
540
541
		$recipientMailAddresses = rtrim($recipientMailAddresses, "\n,");
542
543
		return $recipientMailAddresses;
544
	}
545
546
	/**
547
	 * @param  int  $id
548
	 * @return Visitor
549
	 */
550
	public function getBill($id)
551
	{
552
		return $this->getDatabase()
553
			->table($this->getTable())
554
			->select('bill')
555
			->where('id', $id)
556
			->fetch();
557
	}
558
559
	/**
560
	 * @param	int		ID of visitor
561
	 * @return	mixed	result
562
	 */
563
	public function findVisitorPrograms(int $visitorId)
564
	{
565
		return $this->getDatabase()
566
			->table('kk_visitor-program')
567
			->select('id, program')
568
			->where('visitor', $visitorId)
569
			->fetchAll();
570
	}
571
572
}
573