Completed
Push — master ( 118c60...254398 )
by Litera
03:47
created

VisitorModel   B

Complexity

Total Complexity 36

Size/Duplication

Total Lines 519
Duplicated Lines 3.85 %

Coupling/Cohesion

Components 1
Dependencies 5

Importance

Changes 0
Metric Value
dl 20
loc 519
c 0
b 0
f 0
rs 8.8
wmc 36
lcom 1
cbo 5

20 Methods

Rating   Name   Duplication   Size   Complexity  
B __construct() 0 41 1
A getColumns() 0 4 1
A findByGuid() 0 4 1
B assemble() 0 56 8
B modify() 10 32 3
B modifyByGuid() 10 34 3
A updateOrCreateProgram() 0 22 2
A delete() 0 9 1
A checked() 0 9 1
A getCount() 0 7 1
A setSearch() 0 6 1
A getSearch() 0 4 1
A buildSearchQuery() 0 17 2
A payCharge() 0 17 2
A getRecipients() 0 9 1
A convertToDateTime() 0 8 2
B all() 0 24 1
A getSerializedMailAddress() 0 19 2
A getBill() 0 8 1
A findVisitorPrograms() 0 8 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

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
use Tracy\Debugger;
10
11
/**
12
 * Visitor
13
 *
14
 * class for handling visitors
15
 *
16
 * @created 2012-11-07
17
 * @author Tomas Litera <[email protected]>
18
 */
19
class VisitorModel extends BaseModel
20
{
21
22
	/** @var string	search pattern */
23
	public $search;
24
25
	/** @var Meeting Meeting class */
26
	public $Meeting;
27
28
	/** @var Meal Meals class */
29
	public $Meals;
30
31
	/** @var Program Programs class */
32
	public $Programs;
33
34
	/** @var Blocks Blocks class */
35
	public $Blocks;
36
37
	/** @var int meeting price */
38
	public $meeting_price;
39
40
	/** @var int meeting advance */
41
	private $meeting_advance;
42
43
	/**
44
	 * Array of database programs table columns
45
	 *
46
	 * @var array	dbColumns[]
47
	 */
48
	public $dbColumns = array();
49
50
	/**
51
	 * Array of form names
52
	 *
53
	 * @var array	formNames[]
54
	 */
55
	public $formNames = array();
56
57
	protected $table = 'kk_visitors';
58
59
	protected $columns = [
60
		'name',
61
		'surname',
62
		'nick',
63
		'email',
64
		'birthday',
65
		'street',
66
		'city',
67
		'postal_code',
68
		'group_num',
69
		'group_name',
70
		'troop_name',
71
		'province',
72
		'arrival',
73
		'departure',
74
		'comment',
75
		'question',
76
		'question2',
77
		'bill',
78
		'cost',
79
		'meeting',
80
	];
81
82
	/** konstruktor */
83
	public function __construct(
84
		MeetingModel $Meeting,
85
		MealModel $Meals,
86
		ProgramModel $Program,
87
		BlockModel $Blocks,
88
		Context $database
89
	) {
90
		$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...
91
		$this->meeting_price = $this->Meeting->getPrice('cost');
92
		$this->meeting_advance = $this->Meeting->getPrice('advance');
93
		$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...
94
		$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...
95
		$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...
96
		$this->dbColumns = array(
97
								"guid",
98
								"name",
99
								"surname",
100
								"nick",
101
								"birthday",
102
								"street",
103
								"city",
104
								"postal_code",
105
								"province",
106
								"group_num",
107
								"group_name",
108
								"troop_name",
109
								"bill",
110
								"cost",
111
								"email",
112
								"comment",
113
								"arrival",
114
								"departure",
115
								"question",
116
								"question2",
117
								"checked",
118
								"meeting",
119
								"hash"
120
							);
121
		$this->formNames = array("name", "description", "material", "tutor", "email", "capacity", "display_in_reg", "block", "category");
122
		$this->database = $database;
123
	}
124
125
	/**
126
	 * @return array
127
	 */
128
	public function getColumns()
129
	{
130
		return $this->columns;
131
	}
132
133
	/**
134
	 * @param  $guid
135
	 * @return ActiveRow
136
	 */
137
	public function findByGuid($guid)
138
	{
139
		return $this->findBy('guid', $guid);
140
	}
141
142
	/**
143
	 * Create a new visitor
144
	 *
145
	 * @return	string
146
	 */
147
	public function assemble(array $DB_data, $meals_data, $programs_data, $returnGuid = false)
148
	{
149
		$return = true;
150
151
		if(!$DB_data['province']) {
152
			$DB_data['province'] = 0;
153
		}
154
155
		$DB_data['birthday'] = new \DateTime($DB_data['birthday']);
156
		$DB_data['reg_daytime'] = (new \DateTime())->format('Y-m-d H:i:s');
157
		$DB_data['guid'] = md5(uniqid());
158
159
		$ID_visitor = $this->database
160
			->table($this->getTable())
161
			->insert($DB_data)->id;
162
163
		// visitor's id is empty and i must add one
164
		$meals_data['visitor'] = $ID_visitor;
165
166
		if($ID_visitor){
167
			// gets data from database
168
			$program_blocks = $this->Blocks->getProgramBlocks($DB_data['meeting']);
169
170
			foreach($program_blocks as $DB_blocks_data) {
171
				$bindingsData = array(
172
					'visitor' => $ID_visitor,
173
					'program' => $programs_data[$DB_blocks_data['id']],
174
				);
175
				// insert into binding table
176
				// var programs_data contains requested values in format block-id => program-id
177
				$bindingsData['guid'] = md5(uniqid());
178
				$result_binding = $this->database->query('INSERT INTO `kk_visitor-program`', $bindingsData);
179
180
				if(!$result_binding) {
181
					throw new Exception('Error while binding visitor`s program');
182
				}
183
			}
184
185
			if($return) {
186
187
				// create meals for visitor
188
				if(!$return = $this->Meals->create($meals_data)) {
189
					throw new Exception('Error while creating meals');
190
				}
191
			}
192
		} else {
193
			throw new Exception('Error while creating visitor');
194
		}
195
196
		//return $return;
197
		if($returnGuid) {
198
			return $DB_data['guid'];
199
		} else {
200
			return $ID_visitor;
201
		}
202
	}
203
204
	/**
205
	 * Modify a visitor
206
	 *
207
	 * @param	int		$visitor_id		ID of a visitor
0 ignored issues
show
Documentation introduced by
There is no parameter named $visitor_id. Did you maybe mean $visitor?

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...
208
	 * @param	array	$db_data		Visitor's database data
0 ignored issues
show
Bug introduced by
There is no parameter named $db_data. 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...
209
	 * @param	array	$meals_data		Data of meals
0 ignored issues
show
Bug introduced by
There is no parameter named $meals_data. 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...
210
	 * @param	array	$programs_data	Program's data
0 ignored issues
show
Documentation introduced by
There is no parameter named $programs_data. Did you maybe mean $programs?

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...
211
	 * @return	mixed					TRUE or array of errors
212
	 */
213
	public function modify(int $visitorId, array $visitor, array $meals, array $programs)
214
	{
215
		$visitor['birthday'] = $this->convertToDateTime($visitor['birthday']);
216
217
		$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...
218
			->table($this->getTable())
219
			->where('id', $visitorId)
220
			->update($visitor);
221
222
		// change meals
223
		$result = $this->Meals->updateOrCreate($visitorId, $meals);
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...
224
225
		// gets data from database
226
		$programBlocks = $this->Blocks->getProgramBlocks($visitor['meeting']);
227
228
		// get program of visitor
229
		$oldPrograms = $this->findVisitorPrograms($visitorId);
230
231
		// update old data to new existing
232 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...
233
			// read first value from array and shift it to the end
234
			$oldProgram = array_shift($oldPrograms);
235
236
			$this->updateOrCreateProgram(
237
				$visitorId,
238
				(empty($oldProgram)) ? $oldProgram : $oldProgram->id,
239
				$programs[$programBlock->id]
240
			);
241
		}
242
243
		return $visitorId;
244
	}
245
246
	/**
247
	 * Modify a visitor
248
	 *
249
	 * @param	int		$visitor_id		ID of a visitor
0 ignored issues
show
Documentation introduced by
There is no parameter named $visitor_id. Did you maybe mean $visitor?

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...
250
	 * @param	array	$db_data		Visitor's database data
0 ignored issues
show
Bug introduced by
There is no parameter named $db_data. 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...
251
	 * @param	array	$meals_data		Data of meals
0 ignored issues
show
Bug introduced by
There is no parameter named $meals_data. 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...
252
	 * @param	array	$programs_data	Program's data
0 ignored issues
show
Documentation introduced by
There is no parameter named $programs_data. Did you maybe mean $programs?

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...
253
	 * @return	mixed					TRUE or array of errors
254
	 */
255
	public function modifyByGuid($guid, $visitor, $meals, $programs)
256
	{
257
		$visitor['birthday'] = $this->convertToDateTime($visitor['birthday']);
258
259
		$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...
260
			->table($this->getTable())
261
			->where('guid', $guid)
262
			->update($visitor);
263
264
		$visitor = $this->findByGuid($guid);
265
266
		// change meals
267
		$result = $this->Meals->updateOrCreate($visitor->id, $meals);
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...
268
269
		// gets data from database
270
		$programBlocks = $this->Blocks->getProgramBlocks($visitor['meeting']);
271
272
		// get program of visitor
273
		$oldPrograms = $this->findVisitorPrograms($visitor->id);
274
275
		// update old data to new existing
276 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...
277
			// read first value from array and shift it to the end
278
			$oldProgram = array_shift($oldPrograms);
279
280
			$this->updateOrCreateProgram(
281
				$visitor->id,
282
				(empty($oldProgram)) ? $oldProgram : $oldProgram->id,
283
				$programs[$programBlock->id]
284
			);
285
		}
286
287
		return $guid;
288
	}
289
290
	/**
291
	 * @param int $visitorId
292
	 * @param int $oldProgramId
293
	 * @param int $newProgramId
294
	 * @return mixed
295
	 */
296
	public function updateOrCreateProgram(int $visitorId, int $oldProgramId, int $newProgramId)
297
	{
298
		$result = $this->getDatabase()
299
			->table('kk_visitor-program')
300
			->where('visitor ? AND id ?', $visitorId, $oldProgramId)
301
			->update([
302
				'program' => $newProgramId,
303
			]);
304
305
		if(!$result) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $result of type integer|null is loosely compared to false; this is ambiguous if the integer can be zero. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
306
			$result = $this->getDatabase()
307
				->table('kk_visitor-program')
308
				->where('visitor ? AND id ?', $visitorId, $oldProgramId)
309
				->insert([
310
					'guid'    => $this->generateGuid(),
311
					'visitor' => $visitorId,
312
					'program' => $newProgramId,
313
				]);
314
		}
315
316
		return $result;
317
	}
318
319
	/**
320
	 * Delete one or multiple record/s
321
	 *
322
	 * @param	int		ID/s of record
323
	 * @return	boolean
324
	 */
325
	public function delete($id)
326
	{
327
		return $this->getDatabase()
328
			->table($this->getTable())
329
			->where('id', $id)
330
			->update([
331
				'deleted' => '1'
332
			]);
333
	}
334
335
	/**
336
	 * Set as checked one or multiple record/s
337
	 *
338
	 * @param	int		ID/s of record
339
	 * @param 	int 	0 | 1
340
	 * @return	boolean
341
	 */
342
	public function checked($id, $value)
343
	{
344
		$checked = ['checked' => $value];
345
346
		return $this->getDatabase()
347
			->table($this->getTable())
348
			->where('id', $id)
349
			->update($checked);
350
	}
351
352
	/**
353
	 * Get count of visitors
354
	 *
355
	 * @return  integer
356
	 */
357
	public function getCount()
358
	{
359
		return $this->getDatabase()
360
			->table($this->getTable())
361
			->where('meeting ? AND deleted ?', $this->getMeetingId(), '0')
362
			->count('id');
363
	}
364
365
	/**
366
	 * @param  string $search
367
	 * @return $this
368
	 */
369
	public function setSearch($search)
370
	{
371
		$this->search = $search;
372
373
		return $this;
374
	}
375
376
	/**
377
	 * @return string
378
	 */
379
	protected function getSearch()
380
	{
381
		return $this->search;
382
	}
383
384
	/**
385
	 * @return string
386
	 */
387
	protected function buildSearchQuery()
388
	{
389
		$search = $this->getSearch();
390
391
		$query = '';
392
		if($search) {
393
			$query = "AND (`code` REGEXP '" . $search . "'
394
							OR `group_num` REGEXP '" . $search . "'
395
							OR `name` REGEXP '" . $search . "'
396
							OR `surname` REGEXP '" . $search . "'
397
							OR `nick` REGEXP '" . $search . "'
398
							OR `city` REGEXP '" . $search . "'
399
							OR `group_name` REGEXP '" . $search . "')";
400
		}
401
402
		return $query;
403
	}
404
405
	/**
406
	 * Modify the visitor's bill
407
	 *
408
	 * @param	int	ID/s of visitor
409
	 * @param	string	type of payment (pay | advance)
410
	 * @return	string	error message or true
411
	 */
412
	public function payCharge($ids, $type)
413
	{
414
		$bill = $this->getBill($ids)['bill'];
415
		$cost = $this->Meeting->getPrice('cost');
416
417
		if($bill < $cost) {
418
			$newBill = ['bill' => $this->Meeting->getPrice($type)];
419
			$payResult = $this->getDatabase()
420
				->table($this->getTable())
421
				->where('id', $ids)
422
				->update($newBill);
423
424
			return $payResult;
425
		} else {
426
			throw new Exception('Charge already paid!');
427
		}
428
	}
429
430
	/**
431
	 * Get recipients by ids
432
	 *
433
	 * @param	mixed	ID of visitor
434
	 * @return	mixed	result
435
	 */
436
	public function getRecipients($ids)
437
	{
438
		return $this->getDatabase()
439
			->table($this->getTable())
440
			->select('email, name, surname')
441
			->where('id', $ids)
442
			->where('deleted', '0')
443
			->fetchAll();
444
	}
445
446
	/**
447
	 * @param  string|DateTime $datetime
448
	 * @return DateTime
449
	 */
450
	protected function convertToDateTime($datetime): DateTime
451
	{
452
		if (is_string($datetime)) {
453
			$datetime = new DateTime($datetime);
454
		}
455
456
		return $datetime;
457
	}
458
459
	/**
460
	 * @return Row
461
	 */
462
	public function all()
463
	{
464
		return $this->getDatabase()
465
			->query('SELECT 	vis.id AS id,
466
								vis.guid AS guid,
467
								code,
468
								name,
469
								surname,
470
								nick,
471
								email,
472
								group_name,
473
								group_num,
474
								city,
475
								province_name AS province,
476
								bill,
477
								cost,
478
								birthday,
479
								checked
480
						FROM kk_visitors AS vis
481
						LEFT JOIN kk_provinces AS provs ON vis.province = provs.id
482
						WHERE meeting = ? AND vis.deleted = ? ' . $this->buildSearchQuery() . '
483
						ORDER BY vis.id ASC',
484
						$this->getMeetingId(), '0')->fetchAll();
485
	}
486
487
	/**
488
	 * @param  array  $queryId
489
	 * @return string
490
	 */
491
	public function getSerializedMailAddress(array $queryId = [])
492
	{
493
		$recipientMailAddresses = '';
494
495
		$emails = $this->getDatabase()
496
			->table($this->getTable())
497
			->select('email')
498
			->where('id', $queryId)
499
			->group('email')
500
			->fetchAll();
501
502
		foreach($emails as $item){
503
			$recipientMailAddresses .= $item['email'] . ",\n";
504
		}
505
506
		$recipientMailAddresses = rtrim($recipientMailAddresses, "\n,");
507
508
		return $recipientMailAddresses;
509
	}
510
511
	/**
512
	 * @param  int  $id
513
	 * @return Visitor
514
	 */
515
	public function getBill($id)
516
	{
517
		return $this->getDatabase()
518
			->table($this->getTable())
519
			->select('bill')
520
			->where('id', $id)
521
			->fetch();
522
	}
523
524
	/**
525
	 * @param	int		ID of visitor
526
	 * @return	mixed	result
527
	 */
528
	public function findVisitorPrograms(int $visitorId)
529
	{
530
		return $this->getDatabase()
531
			->table('kk_visitor-program')
532
			->select('id, program')
533
			->where('visitor', $visitorId)
534
			->fetchAll();
535
	}
536
537
}
538