absences_Right   F
last analyzed

Complexity

Total Complexity 139

Size/Duplication

Total Lines 1363
Duplicated Lines 12.69 %

Coupling/Cohesion

Components 4
Dependencies 17

Test Coverage

Coverage 25.58%

Importance

Changes 0
Metric Value
wmc 139
lcom 4
cbo 17
dl 173
loc 1363
rs 0.6314
c 0
b 0
f 0
ccs 143
cts 559
cp 0.2558

54 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A getByUuid() 0 7 1
B getRow() 0 29 4
A getKind() 0 4 1
A getKindLabel() 0 11 2
A getSyncStatus() 0 4 1
A getSyncStatusLabel() 0 5 1
A setType() 0 5 1
A getType() 0 10 2
A setRgroup() 0 5 1
A getRgroup() 14 14 3
A getRgroupLabel() 11 11 3
A getRgroupSortkey() 11 11 3
A getUnitLabel() 13 13 3
A getYear() 11 11 2
A setRightRule() 0 5 1
A getRightRule() 9 9 2
A setRightCet() 0 5 1
A getRightCet() 9 9 2
A addInPeriod() 0 6 1
A getInperiodRules() 0 4 1
A getReportedFrom() 0 15 4
A getReport() 0 22 3
B getOrCreateReport() 0 60 6
A isAccessibleOnMonth() 10 10 1
A saveQuantityIncMonth() 12 12 1
C monthlyQuantityUpdate() 0 78 10
B isAccessibleByValidityPeriod() 6 14 5
A isAccessibleIfFixed() 0 14 4
A isAvailable() 0 4 3
A getStatus() 0 18 4
B periodText() 0 20 5
A getDirFieldLabel() 0 5 1
F getAccessConditions() 38 134 21
A getAgentIterator() 0 8 1
A getCollectionIterator() 0 8 1
A getAgentRightIterator() 0 8 1
B getAgentUsage() 0 42 4
A addMovement() 16 16 2
B isResulted() 0 22 4
A archive() 0 6 1
A getSortKey() 0 4 1
A setSortKey() 0 5 1
A getSortLabel() 0 4 1
A getIconClassName() 0 5 1
B insert() 0 84 1
B update() 0 41 1
A getQuantityAlertTypes() 0 21 3
A getIncrementIterator() 0 7 1
A getIncrementQuantity() 13 13 2
A getDynamicConfigurationIterator() 0 9 1
A getDynamicTypes() 0 15 2
B getQuantityIncMonth() 0 22 4
A getMovementIterator() 0 9 1

How to fix   Duplicated Code    Complexity   

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:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like absences_Right often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use absences_Right, and based on these observations, apply Extract Interface, too.

1
<?php
2
/************************************************************************
3
 * OVIDENTIA http://www.ovidentia.org                                   *
4
 ************************************************************************
5
 * Copyright (c) 2003 by CANTICO ( http://www.cantico.fr )              *
6
 *                                                                      *
7
 * This file is part of Ovidentia.                                      *
8
 *                                                                      *
9
 * Ovidentia is free software; you can redistribute it and/or modify    *
10
 * it under the terms of the GNU General Public License as published by *
11
 * the Free Software Foundation; either version 2, or (at your option)  *
12
 * any later version.													*
13
 *																		*
14
 * This program is distributed in the hope that it will be useful, but  *
15
 * WITHOUT ANY WARRANTY; without even the implied warranty of			*
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.					*
17
 * See the  GNU General Public License for more details.				*
18
 *																		*
19
 * You should have received a copy of the GNU General Public License	*
20
 * along with this program; if not, write to the Free Software			*
21
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,*
22
 * USA.																	*
23
************************************************************************/
24
25
require_once dirname(__FILE__).'/record.class.php';
26
require_once dirname(__FILE__).'/type.class.php';
27
require_once dirname(__FILE__).'/rgroup.class.php';
28
29
/**
30
 * Abscence Right
31
 *
32
 * 
33
 * 
34
 * @property int 		$id_creditor
35
 * @property int 		$kind
36
 * @property string 	$date_entry
37
 * @property string 	$createdOn
38
 * @property string 	$date_begin
39
 * @property string 	$date_end
40
 * @property float 		$quantity
41
 * @property string 	$quantity_unit
42
 * @property float 		$quantity_inc_month
43
 * @property float 		$quantity_inc_max
44
 * @property string		$quantity_inc_last
45
 * @property int 		$id_type
46
 * @property string 	$description
47
 * @property string 	$active
48
 * @property string 	$cbalance
49
 * @property string 	$date_begin_valid
50
 * @property string 	$date_end_valid
51
 * @property string 	$date_end_fixed
52
 * @property string 	$date_begin_fixed
53
 * @property int        $hide_empty
54
 * @property int 		$no_distribution
55
 * @property int 		$id_rgroup
56
 * @property string 	$earlier
57
 * @property int 		$earlier_begin_valid
58
 * @property int 		$earlier_end_valid
59
 * @property string 	$later
60
 * @property int 		$later_begin_valid
61
 * @property int 		$later_end_valid
62
 * @property int		$delay_before
63
 * @property int		$use_in_cet
64
 * @property float		$cet_quantity
65
 * @property int		$id_report_type
66
 * @property string 	$date_end_report
67
 * @property string		$description_report
68
 * @property int		$id_reported_from
69
 * @property int		$sync_status
70
 * @property string		$sync_update
71
 * @property string		$uuid
72
 * @property int		$archived
73
 * @property int		$sortkey
74
 * @property int		$require_approval
75
 * 
76
 * @property int		$quantity_alert_days
77
 * @property int		$quantity_alert_types
78
 * @property string		$quantity_alert_begin
79
 * @property string		$quantity_alert_end
80
 * 
81
 * @property int		$dynconf_types
82
 * @property string		$dynconf_begin
83
 * @property string		$dynconf_end
84
 * 
85
 * @property string     $renewal_uid
86
 * @property int        $renewal_parent     Right ID of the right in the previous period
87
 * 
88
 */
89
class absences_Right extends absences_Record implements absences_RightSort 
90
{
91
	/**
92
	 * Genre du droit default
93
	 * @var int
94
	 */
95
	const REGULAR 	= 1;
96
	
97
	/**
98
	 * Genre du droit a date fixe
99
	 * @var int
100
	 */
101
	const FIXED		= 2;
102
	
103
	/**
104
	 * Genre du droit compte epargne temps
105
	 * @var int
106
	 */
107
	const CET		= 4;
108
	
109
	/**
110
	 * Ajout periodique de solde sur le droit
111
	 * @var int
112
	 */
113
	const INCREMENT = 8;
114
115
	
116
	/**
117
	 * Droit a recuperation (cree apres une approbation de declaration de jours travailles donnant droit a recuperation)
118
	 * @var int
119
	 */
120
	const RECOVERY	= 16;
121
	
122
	/**
123
	 * Droit de report (cree automatiquement)
124
	 * @var int
125
	 */
126
	const REPORT	= 32;
127
	
128
	
129
	
130
	
131
	
132
	const SYNC_CLIENT 		= 1;
133
	const SYNC_CLIENT_END 	= 2;
134
	const SYNC_CLIENT_ERROR	= 3;
135
	
136
	const SYNC_SERVER 		= 8;
137
	
138
	
139
	
140
	
141
	/**
142
	 * 
143
	 * @var absences_Type
144
	 */
145
	private $type;
146
	
147
	
148
	/**
149
	 * @var absences_Rgroup
150
	 */
151
	private $rgroup;
152
	
153
	
154
	/**
155
	 * 
156
	 * @var absences_RightRule
157
	 */
158
	private $right_rule;
159
	
160
	/**
161
	 * 
162
	 * @var absences_RightCet
163
	 */
164
	private $right_cet;
165
	
166
	
167
	/**
168
	 * List of unsaved inperiod rules
169
	 * @var array
170
	 */
171
	private $inperiod = array();
172
	
173
	/**
174
	 *
175
	 * @var absences_Right
176
	 */
177
	private $reported_from;
178
	
179
	/**
180
	 *
181
	 * @var absences_Right
182
	 */
183
	private $report;
184
	
185
	
186
	/**
187
	 * 
188
	 * @var string
189
	 */
190
	private $_uuid;
191
	
192 88
	
193
	public function __construct($id)
194 88
	{
195 88
		$this->id = $id;
196
	}
197
	
198
	
199
	/**
200
	 * 
201
	 * @param string $uuid
202
	 * @return absences_Right
203
	 */
204
	public static function getByUuid($uuid)
205
	{
206
		$right = new absences_Right(null);
207
		$right->_uuid = $uuid;
208
		
209
		return $right;
210
	}
211
	
212
	/**
213
	 * Table row as an array
214
	 * @return array
215 76
	 */
216
	public function getRow()
217 76
	{
218 76
		if (null === $this->row)
219 46
		{
220
			global $babDB;
221
			
222
			$query = '
223
				SELECT 
224
					r.*
225 46
				FROM absences_rights r	
226
				WHERE ';
227 46
			
228 46
			if (isset($this->id))
229 46
			{
230 46
				$query .= 'r.id='.$babDB->quote($this->id);
231
			} elseif (isset($this->_uuid))
232
			{
233
				$query .= 'r.uuid='.$babDB->quote($this->_uuid);
234 9
			} else {
235
				return false;
236
			}
237 46
			
238
			$res = $babDB->db_query($query);
239 46
			
240 46
			$this->setRow($babDB->db_fetch_assoc($res));
241
		}
242 76
		
243
		return $this->row;
244
	}
245
246
	
247
	/**
248
	 * La nature du droit
249
	 * @return int
250 14
	 */
251
	public function getKind()
252 14
	{
253
		return (int) $this->kind;
254
	}
255
	
256
	/**
257
	 * @return string
258 9
	 */
259 9
	public function getKindLabel()
260
	{
261
		$arr = absences_kinds();
262
		$kind = $this->getKind();
263
		
264
		if (!isset($arr[$kind])) {
265
		    return '';
266
		}
267
		
268 9
		return $arr[$kind];
269
	}
270
	
271
	/**
272
	 * @return int
273 9
	 */
274 9
	public function getSyncStatus()
275
	{
276
		return (int) $this->sync_status;
277
	}
278
	
279
	/**
280
	 * @return string
281
	 */
282
	public function getSyncStatusLabel()
283
	{
284
		$arr = absences_syncStatus();
285
		return $arr[$this->getSyncStatus()];
286
	}
287
	
288
	
289
	/**
290
	 *
291
	 * @param absences_Type $type
292
	 * @return absences_Right
293 9
	 */
294
	public function setType(absences_Type $type)
295
	{
296
		$this->type = $type;
297
		return $this;
298
	}
299
	
300
	
301
	/**
302
	 * @return absences_Type
303 10
	 */
304
	public function getType()
305 1
	{
306 1
		if (!isset($this->type))
307 10
		{
308 1
			$row = $this->getRow();
309 10
			$this->type = new absences_Type($row['id_type']);
310
		}
311 1
	
312
		return $this->type;
313
	}
314
	
315
	
316
	
317
	/**
318
	 *
319
	 * @param absences_Rgroup $rgroup
320
	 * @return absences_Right
321
	 */
322
	public function setRgroup(absences_Rgroup $rgroup)
323
	{
324
		$this->rgroup = $rgroup;
325
		return $this;
326
	}
327
	
328
	
329
	/**
330
	 * @return absences_Rgroup
331 9
	 */
332 View Code Duplication
	public function getRgroup()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
333
	{
334
		if (!isset($this->rgroup))
335
		{
336
			$row = $this->getRow();
337
			if (empty($row['id_rgroup']))
338
			{
339
				return null;
340
			}
341
			$this->rgroup = new absences_Rgroup($row['id_rgroup']);
342
		}
343 9
	
344 9
		return $this->rgroup;
345
	}
346
	
347
	/**
348
	 * 
349
	 * @return string
350 9
	 */
351 View Code Duplication
	public function getRgroupLabel()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
352
	{
353
		$rgroup = $this->getRgroup();
354
		
355
		if (null === $rgroup || !$rgroup->getRow())
356
		{
357
			return null;
358
		}
359
		
360
		return $rgroup->name;
361
	}
362
	
363
	
364
	
365
	/**
366
	 *
367
	 * @return int
368
	 */
369 View Code Duplication
	public function getRgroupSortkey()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
370
	{
371
		$rgroup = $this->getRgroup();
372
	
373
		if (null === $rgroup || !$rgroup->getRow())
374
		{
375
			return null;
376
		}
377
	
378
		return $rgroup->sortkey;
379
	}
380
	
381
	
382
	/**
383
	 * @return string
384
	 */
385 View Code Duplication
	public function getUnitLabel()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
386
	{
387
		switch($this->quantity_unit)
388
		{
389
			case 'D':
390
				return absences_translate('day(s)');
391
	
392
			case 'H':
393
				return absences_translate('hour(s)');
394
		}
395
	
396
		return '';
397
	}
398
	
399
	/**
400
	 * Start date year
401
	 * @return int
402
	 */
403 View Code Duplication
	public function getYear()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
404
	{
405
		$year = (int) substr($this->date_begin, 0, 4);
406
		
407
		if (0 === $year)
408
		{
409
			return null;
410
		}
411
		
412
		return $year;
413
	}
414
	
415
	
416
	/**
417
	 * 
418
	 * @param absences_RightRule $RightRule
419
	 */
420
	public function setRightRule(absences_RightRule $RightRule)
421
	{
422
		$this->rightrule = $RightRule;
0 ignored issues
show
Bug introduced by
The property rightrule does not seem to exist. Did you mean right_rule?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
423
		return $this;
424
	}
425
	
426
	/**
427
	 * @return absences_RightRule
428 10
	 */
429 View Code Duplication
	public function getRightRule()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
430 10
	{
431 10
		if (!isset($this->right_rule))
432 10
		{
433 10
			require_once dirname(__FILE__).'/right_rule.class.php';
434 10
			$this->right_rule = absences_RightRule::getFromRight($this->id);	
435 10
		}
436
		return $this->right_rule;
437
	}
438
	
439
	
440
	
441
	
442
	/**
443
	 *
444
	 * @param absences_RightCet $RightCet
445
	 */
446
	public function setRightCet(absences_RightCet $RightCet)
447
	{
448
		$this->right_cet = $RightCet;
449
		return $this;
450
	}
451
	
452
	/**
453
	 * @return absences_RightCet
454
	 */
455 View Code Duplication
	public function getRightCet()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
456
	{
457
		if (!isset($this->right_cet))
458
		{
459
			require_once dirname(__FILE__).'/right_cet.class.php';
460
			$this->right_cet = absences_RightCet::getFromRight($this->id);
461
		}
462
		return $this->right_cet;
463
	}
464
	
465
	
466
	
467
	/**
468
	 * 
469
	 * @param absences_RightInPeriod $inperiod
470
	 */
471
	public function addInPeriod(absences_RightInPeriod $inperiod)
472
	{
473
		$this->inperiod[] = $inperiod;
474
		$inperiod->setRight($this);
475
		return $this;
476
	}
477
	
478
	
479
	/**
480
	 * @return multitype:absences_RightInPeriod
0 ignored issues
show
Documentation introduced by
The doc-type multitype:absences_RightInPeriod could not be parsed: Unknown type name "multitype:absences_RightInPeriod" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
481
	 */
482
	public function getInperiodRules()
483
	{
484
		return $this->inperiod;
485
	}
486
	
487
	
488
	/**
489
	 * Get the source right of report or false if the right is not a report
490
	 * @return absences_Right | false
491
	 */
492
	public function getReportedFrom()
493
	{
494
		if (!isset($this->reported_from))
495
		{
496
			if (self::REPORT !== $this->getKind() || empty($this->id_reported_from))
497
			{
498
				$this->reported_from = false;
0 ignored issues
show
Documentation Bug introduced by
It seems like false of type false is incompatible with the declared type object<absences_Right> of property $reported_from.

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...
499
			} else {
500
			
501
				$this->reported_from = new absences_Right($this->id_reported_from);
502
			}
503
		}
504
		
505
		return $this->reported_from;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The expression $this->reported_from; of type false|absences_Right adds false to the return on line 505 which is incompatible with the return type documented by absences_Right::getReportedFrom of type absences_Right. It seems like you forgot to handle an error condition.
Loading history...
506
	}
507
	
508
	
509
	/**
510
	 * Get the report right if exists
511
	 * @return absences_Right | false
512
	 */
513
	public function getReport()
514
	{
515
		if (!isset($this->report))
516
		{
517
			global $babDB;
518
			
519
			$res = $babDB->db_query('SELECT * FROM absences_rights WHERE id_reported_from='.$babDB->quote($this->id));
520
			if (0 === $babDB->db_num_rows($res))
521
			{
522
				$this->report = false;
0 ignored issues
show
Documentation Bug introduced by
It seems like false of type false is incompatible with the declared type object<absences_Right> of property $report.

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...
523
			} else {
524
				
525
				$row = $babDB->db_fetch_assoc($res);
526
				$right = new absences_Right($row['id']);
527
				$right->setRow($row);
528
				
529
				$this->report = $right;
530
			}
531
		}
532
		
533
		return $this->report;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The expression $this->report; of type false|absences_Right adds false to the return on line 533 which is incompatible with the return type documented by absences_Right::getReport of type absences_Right. It seems like you forgot to handle an error condition.
Loading history...
534
	}
535
	
536
	
537
	/**
538
	 * Get the report right or create it if not exists
539
	 * @return absences_Right | null
540
	 */
541
	public function getOrCreateReport()
542
	{
543
		$right = $this->getReport();
544
		
545
		if (false !== $right)
546
		{
547
			return $right;
548
		}
549
		
550
		
551
		if (empty($this->date_end_report) || '0000-00-00'===$this->date_end_report)
552
		{
553
			return null;
554
		}
555
		
556
		
557
		$description = empty($this->description_report) ? $this->description : $this->description_report;
558
		$id_type = empty($this->id_report_type) ? $this->id_type : $this->id_report_type;
559
		
560
		global $babDB;
561
		
562
		$babDB->db_query('INSERT INTO absences_rights (
563
				kind, 
564
				description, 
565
		        createdOn,
566
				date_entry, 
567
				date_begin, 
568
				date_end,
569
				date_begin_valid,
570
				date_end_valid,
571
				quantity_unit,
572
				id_type,
573
				cbalance,
574
				use_in_cet,
575
				id_reported_from
576
			) 
577
				VALUES 
578
			(
579
				'.$babDB->quote(self::REPORT).',
580
				'.$babDB->quote($description).',
581
		        NOW(),
582
				NOW(),
583
				'.$babDB->quote($this->date_begin).',
584
				'.$babDB->quote($this->date_end_report).',
585
				'.$babDB->quote($this->date_begin_valid).',
586
				'.$babDB->quote($this->date_end_report).',
587
				'.$babDB->quote($this->quantity_unit).',
588
				'.$babDB->quote($id_type).',
589
				'.$babDB->quote('N').',
590
				'.$babDB->quote('0').',
591
				'.$babDB->quote($this->id).'
592
			)');
593
		
594
		
595
		$id_report = $babDB->db_insert_id();
596
		
597
		$this->report = new absences_Right($id_report);
598
		
599
		return $this->report;
600
	}
601
	
602
	
603
	
604
	/**
605
	 * Tester si le droit est disponible dans le mois en cours (en fonction de la periode de conges demandee)
606
	 * si cette methode renvoi true, il n'y a pas de fin de validite dans le mois en cours sauf si validoperlap est actif
607
	 *
608
	 * si on ce base sur cette methode pour determiner si un droit doit etre incremente dans le mois
609
	 *  - le droit sera incremente si pas de fin de validite dans le mois
610
	 *  - le droit sera incremente si le chevauchement est active et que la fin de validite est dans le mois
611
	 *
612
	 *
613
	 * @return bool
614 10
	 */
615 View Code Duplication
	public function isAccessibleOnMonth()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
616 10
	{
617 10
		require_once $GLOBALS['babInstallPath'].'utilit/dateTime.php';
618 10
		$begin = new BAB_DateTime(date('Y'), date('n'), 1);
619
		$end = new BAB_DateTime(date('Y'), date('n'), date('t'), 23, 59, 59);
620 10
		
621
		$rightRule = $this->getRightRule();
622 10
	
623
		return $rightRule->isAccessibleOnPeriod($begin->getTimeStamp(), $end->getTimeStamp());
624
	}
625
	
626
	
627 9
	
628 View Code Duplication
	protected function saveQuantityIncMonth($quantity)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
629 9
	{
630
	    require_once dirname(__FILE__).'/increment_right.class.php';
631 9
	
632 9
	    $increment = new absences_IncrementRight();
633 9
	    $increment->id_right = $this->id;
634 9
	    $increment->quantity = $quantity;
635 9
	    $increment->createdOn = date('Y-m-d H:i:s');
636
	    $increment->monthkey = date('Ym');
637 9
	
638 9
	    $increment->saveOrUpdate();
639
	}
640
	
641
	
642
	
643
	
644
	/**
645
	 * Increment quantity for the month if not allready done
646
	 * return true if quantity has been modified
647
	 *
648
	 * @param LibTimer_eventHourly $event optional event if the action is done via a background task
649
	 *
650
	 * @return bool
651 14
	 */
652
	public function monthlyQuantityUpdate(LibTimer_eventHourly $event = null)
653 14
	{
654 14
	    if ($this->getKind() !== absences_Right::INCREMENT || $this->quantity_inc_month<='0.00')
655
	    {
656
	        return false;
657
	    }
658 14
659 14
	    require_once $GLOBALS['babInstallPath'].'utilit/dateTime.php';
660
	    $limit = new BAB_DateTime(date('Y'), date('n'), 1);
661 14
662 14
	    if ($this->quantity_inc_last >= $limit->getIsoDateTime())
663 3
	    {
664
	        return false;
665
	    }
666 11
667 11
	    $quantity = (float) $this->quantity;
668
	    $quantity += $this->getIncrementQuantity();
669 11
	    
670
	    $initial_quantity = $quantity;
671 11
	    
672 11
	    if ($this->quantity_inc_last !== '0000-00-00 00:00:00' && $this->isAccessibleOnMonth())
673
	    {
674
	        // Do not increment the first month
675
	        // Do not increment if the full month is not totally available
676 10
	        
677
	        $quantity_inc_month = $this->getQuantityIncMonth($quantity);
678 10
	        
679
	        if (0 !== (int) round(100 * $quantity_inc_month)) {
680 9
	        
681
    	        $quantity += $quantity_inc_month;
682 9
    	        
683
    	        $this->saveQuantityIncMonth($quantity_inc_month);
684 9
    
685 9
    	        $message = sprintf(
686 9
    	            absences_translate('The quantity of right "%s" has been modified from %s to %s by the monthly update'), 
687 9
                    $this->description,
688
                    $initial_quantity,
689 9
                    $quantity
690
    	        );
691 9
    	        
692
    	        $this->addMovement($message, '', 0);
693 9
    	        
694
    	        if (isset($event)) {
695
    	            $event->log('absences', $message);
696 9
    	        }
697 10
	        }
698
	    }
699 11
	    	
700
	    global $babDB;
701 11
	    	
702 11
	    $babDB->db_query('UPDATE absences_rights SET 
703 11
				quantity_inc_last='.$babDB->quote($limit->getIsoDateTime()).'
704
			WHERE id='.$babDB->quote($this->id));
705 11
	    
706
	    if ($this->quantity_inc_last !== '0000-00-00 00:00:00') {
707
    	    // update the modified quantites but not the first month
708
    	    // agentRight have their own isAccessibleOnMonth method because the period can be different
709 10
    	    
710 10
    	    $modified = $this->getAgentRightIterator();
711
    	    $modified->modified_quantity = true;
712 10
    	    
713
    	    foreach ($modified as $agentRight)
714
    	    {
715 8
    	        /*@var $agentRight absences_AgentRight */
716 10
    	        $agentRight->monthlyQuantityUpdate($event);
717
    	    }
718
    	    
719
    	    
720 10
    	    // UPDATE the current instance
721
    	    $this->quantity_inc_last = $limit->getIsoDateTime();
722 10
    	    
723
    	    return true;
724
	    }
725
	    
726 1
	    // UPDATE the current instance
727 1
	    $this->quantity_inc_last = $limit->getIsoDateTime();
728
	    return false;
729
	}
730
	
731
	
732
	
733
	
734
	/**
735
	 * Tester si le droit est accessible en fonction de la periode de validite du droit
736
	 * @see absences_AgentRight::isAccessibleByValidityPeriod()
737
	 * @return bool
738
	 */
739
	public function isAccessibleByValidityPeriod()
740
	{
741
		$access= true;
742
		
743 View Code Duplication
		if( $this->date_begin_valid != '0000-00-00' && (bab_mktime($this->date_begin_valid." 00:00:00") > mktime())){
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...
744
			$access= false;
745
		}
746
		
747 View Code Duplication
		if( $this->date_end_valid != '0000-00-00' && (bab_mktime($this->date_end_valid." 23:59:59") < mktime())){
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...
748
			$access= false;
749
		}
750
		
751
		return $access;
752
	}
753
	
754
	/**
755
	 * Test if the vacation right is visible to the end user by testing properties of fixed vacation right
756
	 * if the right is not a fixed vacation right, this method return true
757
	 * 
758
	 * @return bool
759
	 */
760
	public function isAccessibleIfFixed()
761
	{
762
		if ($this->kind != self::FIXED)
763
		{
764
			return true;
765
		}
766
		
767
		// dont't display vacations with fixed dates that are gone
768
		if( $this->date_end_fixed != '0000-00-00 00:00:00' && (bab_mktime($this->date_end_fixed) < mktime())){
769
			return false;
770
		}
771
		
772
		return true;
773
	}
774
	
775
	
776
	/**
777
	 * If the right is displayed as available in the manager list
778
	 * Test if the right is accessible for the user to display information in exported file
779
	 * pour l'export de l'agent et pour l'export des droits
780
	 * 
781
	 * @return bool
782
	 */
783
	public function isAvailable()
784
	{
785
		return ('Y' == $this->active && $this->isAccessibleByValidityPeriod() && $this->isAccessibleIfFixed());
786
	}
787
	
788
	
789
	public function getStatus()
790
	{
791
		if ($this->archived)
792
		{
793
			return absences_translate('Archived');
794
		}
795
		
796
		
797
		if ('Y' == $this->active)
798
		{
799
			return absences_translate('Active');
800
		}
801
		
802
		if ('N' == $this->active)
803
		{
804
			return absences_translate('Disabled for appliquant, usable by managers and delegated managers');
805
		}
806
	}
807
	
808
	
809
	/**
810
	 * Get a period description in text
811
	 * @param string $begin
812
	 * @param string $end
813
	 */
814
	private function periodText($begin, $end)
815
	{
816
		if ('0000-00-00'=== $begin && '0000-00-00' === $end) {
817
			return null;
818
		}
819
		
820
		$d1 = bab_shortDate(bab_mktime($begin), false);
821
		$d2 = bab_shortDate(bab_mktime($end), false);
822
		
823
		if (!$d1) {
824
		    $d1 = absences_translate('??/??/????');
825
		}
826
		
827
		if (!$d2) {
828
		    $d2 = absences_translate('??/??/????');
829
		}
830
		
831
		
832
		return sprintf(absences_translate('the %s and the %s'), $d1, $d2);
833
	}
834
	
835
	
836
	/**
837
	 * 
838
	 * @param string $name
839
	 * @return string
840
	 */
841
	private function getDirFieldLabel($name)
842
	{
843
		$fields = bab_getDirEntry(BAB_REGISTERED_GROUP, BAB_DIR_ENTRY_ID_GROUP);
844
		return $fields[$name]['name'];
845
	}
846
	
847
	
848
	
849
	
850
	/**
851
	 * Get access conditions as a string
852
	 * of null if there are no access conditions
853
	 * @return string
854
	 */
855
	public function getAccessConditions()
856
	{
857
		global $babDB;
858
		$conditions = array();
859
		
860
		
861
		// Disponibilite en fonction de la date de saisie de la demande de conges
862
		if ('0000-00-00' !== $this->date_begin_valid)
863
		{
864
			$period = $this->periodText($this->date_begin_valid, $this->date_end_valid);
865
			$conditions[] = sprintf(absences_translate('To create a vacation request at a date beetween %s.'), $period);
866
		}
867
		
868
		
869
		$rightRules = $this->getRightRule();
870
		
871
		// Disponibilite en fonction de la periode de conges demandee
872
		$res = $rightRules->getInPeriodRes();
873
		if ($babDB->db_num_rows($res) > 0)
874
		{
875
			$s = array();
876
			
877
			while ($arr = $babDB->db_fetch_assoc($res))
878
			{
879
				$d1 = bab_shortDate(bab_mktime($arr['period_start']), false);
880
				$d2 = bab_shortDate(bab_mktime($arr['period_end']), false);
881
				
882
				
883
				switch($arr['right_inperiod'])
884
				{
885
					case 1: $subcond = sprintf(absences_translate('beetween the %s and the %s'), $d1, $d2);	break;
886
					case 2: $subcond = sprintf(absences_translate('before the %s or after the %s'), $d1, $d2);	break;
887
				}
888
				
889
				$s[] = $subcond;
0 ignored issues
show
Bug introduced by
The variable $subcond does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
890
			}
891
			
892
			$conditions[] = absences_translate('To apply for a vacation period').' '.implode(', ', $s).'.';
893
		}
894
		
895
		// Attribution du droit en fonction des jours demandes et valides
896
897
		if ($rightRules->getRow() && $rightRules->trigger_nbdays_min && $rightRules->trigger_nbdays_max)
898
		{
899
			$text = sprintf(absences_translate('To have requested at least %d days but less than %d days'), $rightRules->trigger_nbdays_min, $rightRules->trigger_nbdays_max);
900
			if ($rightRules->trigger_type)
901
			{
902
				$text .= ' '. sprintf(absences_translate('of type %s'), $rightRules->getType()->name);
903
			}
904
			
905
			$periods = array();
906
			$p1 = $this->periodText($rightRules->trigger_p1_begin, $rightRules->trigger_p1_end);
907
			$p2 = $this->periodText($rightRules->trigger_p2_begin, $rightRules->trigger_p2_end);
908
			
909
			if ($p1) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $p1 of type null|string is loosely compared to true; this is ambiguous if the string can be empty. 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 string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
910
				$periods[] = sprintf(absences_translate('beetween %s'), $p1);
911
			}
912
			
913
			if ($p2) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $p2 of type null|string is loosely compared to true; this is ambiguous if the string can be empty. 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 string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
914
				$periods[] = sprintf(absences_translate('beetween %s'), $p2);
915
			}
916
			$text .= ' '.implode(' '.absences_translate('or').' ', $periods).'.';
917
			
918
			$conditions[] = $text;
919
		}
920
		
921
		// Disponibilite en fonction d'une date anterieure
922
		
923 View Code Duplication
		if ($this->earlier)
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...
924
		{
925
			$f = $this->getDirFieldLabel($this->earlier);
926
			$cond = array();
927
			
928
			if ($this->earlier_begin_valid)
929
			{
930
				$cond[] = sprintf(absences_translate('%d years later "%s"'), $this->earlier_begin_valid, $f);
931
			} else {
932
				$cond[] = sprintf(absences_translate('after "%s"'), $f);
933
			}
934
			
935
			if ($this->earlier_end_valid)
936
			{
937
				$cond[] = sprintf(absences_translate('in the %d years next to "%s"'), $this->earlier_end_valid, $f);
938
			} 
939
			
940
			$conditions[] = absences_translate('To request a period').' '.implode(' '.absences_translate('and').' ', $cond).'.';
941
		}
942
		
943
		
944
		// Disponibilite en fonction d'une date posterieure
945
		
946 View Code Duplication
		if ($this->later)
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...
947
		{
948
			$f = $this->getDirFieldLabel($this->later);
949
			$cond = array();
950
			
951
			if ($this->later_begin_valid)
952
			{
953
				$cond[] = sprintf(absences_translate('in the %d years preceding "%s"'), $this->later_begin_valid, $f);
954
			} else {
955
				$cond[] = sprintf(absences_translate('after "%s"'), $f);
956
			}
957
			
958
			if ($this->later_end_valid)
959
			{
960
				$cond[] = sprintf(absences_translate('at least %d years before the "%s"'), $this->later_end_valid, $f);
961
			}
962
			
963
			$conditions[] = absences_translate('To request a period').' '.implode(' '.absences_translate('and').' ', $cond).'.';
964
		}
965
		
966
		if($this->delay_before)
967
		{
968
			$conditions[] = sprintf(absences_translate('To request a period at least %s days before.'), $this->delay_before);
969
		}
970
		
971
		
972
		if (0 ===count($conditions))
973
		{
974
			return null;
975
		}
976
		
977
		
978
		$text = absences_translate('The condition to access this vacation right is', 'The conditions to access this vacation right are:', count($conditions));
979
		
980
		foreach($conditions as $c)
981
		{
982
			$text .= " \n".$c;
983
		}
984
		
985
		
986
		return $text;
987
		
988
	}
989
	
990
	
991
	
992
	
993
	/**
994
	 * Agents associated to vacation right
995
	 * @return absences_AgentIterator
996
	 */
997
	public function getAgentIterator()
998
	{
999
		require_once dirname(__FILE__).'/agent.class.php';
1000
		$I = new absences_AgentIterator;
1001
		$I->setRight($this);
1002
		
1003
		return $I;
1004
	}
1005
	
1006
	/**
1007
	 * Collections associated to vacation right
1008
	 * @return absences_CollectionIterator
1009
	 */
1010
	public function getCollectionIterator()
1011
	{
1012
		require_once dirname(__FILE__).'/collection.class.php';
1013
		$I = new absences_CollectionIterator;
1014
		$I->setRight($this);
1015
		
1016
		return $I;
1017
	}
1018
	
1019
	
1020
	/**
1021
	 * @return absences_AgentRightStatIterator
1022 10
	 */
1023
	public function getAgentRightIterator()
1024 10
	{
1025 10
		require_once dirname(__FILE__).'/agent_right.class.php';
1026 10
		$I = new absences_AgentRightStatIterator;
1027
		$I->setRight($this);
1028 10
		
1029
		return $I;
1030
	}
1031
	
1032
	
1033
	/**
1034
	 * determiner le nombre de d'agent avec ce droit non solde
1035
	 * @return int
1036
	 */
1037
	public function getAgentUsage()
1038
	{
1039
		$last_available = 0;
1040
		$last_waiting = 0;
1041
		$last_agents = 0;
1042
		$last_agents_iu = 0;
1043
		
1044
		
1045
		foreach($this->getAgentRightIterator() as $agent_right)
1046
		{
1047
			/*@var $agent_right absences_AgentRight */
1048
			
1049
			$waiting = $agent_right->getWaitingQuantity();
1050
			if (0 !== (int) round(100 * $waiting))
1051
			{
1052
				$last_agents_iu++;
1053
			}
1054
			
1055
			$available = $agent_right->getAvailableQuantity();
1056
			if (0 !== (int) round(100 * $available))
1057
			{
1058
				$last_agents++;
1059
				$last_agents_iu++;
1060
			}
1061
			
1062
			
1063
			
1064
			
1065
			$last_waiting += $waiting;
1066
			$last_available += $available; 
1067
				
1068
		}
1069
		
1070
		
1071
		
1072
		return array(
1073
			'available' => absences_quantity($last_available, $this->quantity_unit),
1074
			'waiting' => absences_quantity($last_waiting, $this->quantity_unit),
1075
			'agents' => $last_agents,
1076
			'agents_iu' => $last_agents_iu
1077
		);
1078
	}
1079
	
1080
	
1081
	
1082
	
1083
	
1084
	/**
1085
	 *
1086
	 * @param string $message	Generated message
1087
	 * @param string $comment	Author comment
1088 9
	 */
1089 View Code Duplication
	public function addMovement($message, $comment = '', $id_author = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
1090 9
	{
1091
		require_once dirname(__FILE__).'/movement.class.php';
1092 9
	
1093 9
		$movement = new absences_Movement();
1094 9
		$movement->message = $message;
1095
		$movement->comment = $comment;
1096 9
		
1097 9
		if (isset($id_author))
1098 9
		{
1099 9
			$movement->id_author = $id_author;
1100
		}
1101 9
		
1102 9
		$movement->setRight($this);
1103 9
		$movement->save();
1104
	}
1105
	
1106
	
1107
	
1108
	/**
1109
	 * Tester si tout les beneficiaires du droit on consome tout le solde
1110
	 * @return bool
1111
	 */
1112
	public function isResulted()
1113
	{
1114
		if ($this->cbalance === 'N')
1115
		{
1116
			// soldes negatifs autorises
1117
			// considere comme solde si le droit n'est pas dispo
1118
			return !$this->isAvailable();
1119
		}
1120
		
1121
		
1122
		foreach($this->getAgentRightIterator() as $agent_right)
1123
		{
1124
			if ($agent_right->getAvailableQuantity() > 0)
1125
			{
1126
				// tout n'a pas ete consome
1127
				return false;
1128
			}
1129
		}
1130
		
1131
		// tout a ete consome et le droit n'est pas dispo
1132
		return !$this->isAvailable();
1133
	}
1134
	
1135
	
1136
	
1137
	
1138
	/**
1139
	 * Archiver le droit
1140
	 */
1141
	public function archive()
1142
	{
1143
		global $babDB;
1144
		
1145
		$babDB->db_query('UPDATE absences_rights SET archived='.$babDB->quote(1).' WHERE id='.$babDB->quote($this->id));
1146
	}
1147
	
1148
	
1149
	/**
1150
	 * Method used with bab_Sort
1151
	 */
1152
	public function getSortKey()
1153
	{
1154
		return $this->sortkey;
1155
	}
1156
	
1157
	public function setSortKey($i)
1158
	{
1159
		global $babDB;
1160
		$babDB->db_query('UPDATE absences_rights SET sortkey='.$babDB->quote($i).' WHERE id='.$babDB->quote($this->id));
1161
	}
1162
	
1163
	public function getSortLabel()
1164
	{
1165
		return $this->description;
1166
	}
1167
	
1168
	
1169
	public function getIconClassName()
1170
	{
1171
		bab_functionality::includeOriginal('Icons');
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class bab_functionality as the method includeOriginal() does only exist in the following sub-classes of bab_functionality: Func_Archive, Func_Archive_Zip, Func_Archive_Zip_ZipArchive, Func_Archive_Zip_Zlib, Func_CalendarBackend, Func_CalendarBackend_Ovi, Func_ContextActions, Func_ContextActions_Article, Func_ContextActions_ArticleTopic, Func_Home, Func_Home_Ovidentia, Func_Icons, Func_Icons_Default, Func_Ovml, Func_Ovml_Container, Func_Ovml_Container_Addon, Func_Ovml_Container_Article, Func_Ovml_Container_ArticleCategories, Func_Ovml_Container_ArticleCategory, Func_Ovml_Container_ArticleCategoryNext, Func_Ovml_Container_ArticleCategoryPrevious, Func_Ovml_Container_ArticleFiles, Func_Ovml_Container_ArticleNext, Func_Ovml_Container_ArticlePrevious, Func_Ovml_Container_ArticleTopic, Func_Ovml_Container_ArticleTopicNext, Func_Ovml_Container_ArticleTopicPrevious, Func_Ovml_Container_ArticleTopics, Func_Ovml_Container_Articles, Func_Ovml_Container_ArticlesHomePages, Func_Ovml_Container_CalendarCategories, Func_Ovml_Container_CalendarEventDomains, Func_Ovml_Container_CalendarEvents, Func_Ovml_Container_CalendarGroupEvents, Func_Ovml_Container_CalendarResourceEvents, Func_Ovml_Container_CalendarUserEvents, Func_Ovml_Container_Calendars, Func_Ovml_Container_DbDirectories, Func_Ovml_Container_DbDirectory, Func_Ovml_Container_DbDirectoryAcl, Func_Ovml_Container_DbDirectoryEntry, Func_Ovml_Container_DbDirectoryEntryFields, Func_Ovml_Container_DbDirectoryFields, Func_Ovml_Container_DbDirectoryMemberFields, Func_Ovml_Container_DbDirectoryMembers, Func_Ovml_Container_Delegation, Func_Ovml_Container_DelegationAdministrators, Func_Ovml_Container_DelegationItems, Func_Ovml_Container_DelegationManaged, Func_Ovml_Container_Delegations, Func_Ovml_Container_DelegationsCategories, Func_Ovml_Container_DelegationsCategory, Func_Ovml_Container_DelegationsManaged, Func_Ovml_Container_Faq, Func_Ovml_Container_FaqNext, Func_Ovml_Container_FaqPrevious, Func_Ovml_Container_FaqQuestion, Func_Ovml_Container_FaqQuestionNext, Func_Ovml_Container_FaqQuestionPrevious, Func_Ovml_Container_FaqQuestions, Func_Ovml_Container_FaqSubCategories, Func_Ovml_Container_FaqSubCategory, Func_Ovml_Container_Faqs, Func_Ovml_Container_File, Func_Ovml_Container_FileFields, Func_Ovml_Container_FileNext, Func_Ovml_Container_FilePrevious, Func_Ovml_Container_Files, Func_Ovml_Container_Folder, Func_Ovml_Container_FolderNext, Func_Ovml_Container_FolderPrevious, Func_Ovml_Container_Folders, Func_Ovml_Container_Forum, Func_Ovml_Container_ForumNext, Func_Ovml_Container_ForumPrevious, Func_Ovml_Container_Forums, Func_Ovml_Container_IfEqual, Func_Ovml_Container_IfGreaterThan, Func_Ovml_Container_IfGreaterThanOrEqual, Func_Ovml_Container_IfIsSet, Func_Ovml_Container_IfLessThan, Func_Ovml_Container_IfLessThanOrEqual, Func_Ovml_Container_IfNotEqual, Func_Ovml_Container_IfNotIsSet, Func_Ovml_Container_IfUserMemberOfGroups, Func_Ovml_Container_Multipages, Func_Ovml_Container_ObjectsInfo, Func_Ovml_Container_OrgPathToEntity, Func_Ovml_Container_OrgUserEntities, Func_Ovml_Container_OvmlArray, Func_Ovml_Container_OvmlArrayFields, Func_Ovml_Container_OvmlSoap, Func_Ovml_Container_ParentsArticleCategory, Func_Ovml_Container_Post, Func_Ovml_Container_PostFiles, Func_Ovml_Container_RecentArticles, Func_Ovml_Container_RecentComments, Func_Ovml_Container_RecentFaqQuestions, Func_Ovml_Container_RecentFiles, Func_Ovml_Container_RecentPosts, Func_Ovml_Container_RecentThreads, Func_Ovml_Container_SitemapCustomNode, Func_Ovml_Container_SitemapEntries, Func_Ovml_Container_SitemapEntry, Func_Ovml_Container_SitemapPath, Func_Ovml_Container_Soap, Func_Ovml_Container_SubFolders, Func_Ovml_Container_Tags, Func_Ovml_Container_Thread, Func_Ovml_Container_TmProjects, Func_Ovml_Container_TmSpaces, Func_Ovml_Container_TmTaskFields, Func_Ovml_Container_TmTasks, Func_Ovml_Container_WaitingArticles, Func_Ovml_Container_WaitingComments, Func_Ovml_Container_WaitingFiles, Func_Ovml_Container_WaitingPosts, Func_Ovml_Function, Func_Ovml_Function_AOAddition, Func_Ovml_Function_AODivision, Func_Ovml_Function_AOModulus, Func_Ovml_Function_AOMultiplication, Func_Ovml_Function_AOSubtraction, Func_Ovml_Function_AddStyleSheet, Func_Ovml_Function_Addon, Func_Ovml_Function_Ajax, Func_Ovml_Function_ArticleTree, Func_Ovml_Function_CurrentNode, Func_Ovml_Function_FileTree, Func_Ovml_Function_Get, Func_Ovml_Function_GetCookie, Func_Ovml_Function_GetCsrfProtectToken, Func_Ovml_Function_GetCurrentAdmGroup, Func_Ovml_Function_GetLanguage, Func_Ovml_Function_GetPageTitle, Func_Ovml_Function_GetPath, Func_Ovml_Function_GetSelectedSkinPath, Func_Ovml_Function_GetSessionVar, Func_Ovml_Function_GetVar, Func_Ovml_Function_Header, Func_Ovml_Function_IfNotIsSet, Func_Ovml_Function_Include, Func_Ovml_Function_NextArticle, Func_Ovml_Function_Post, Func_Ovml_Function_PreviousArticle, Func_Ovml_Function_PreviousOrNextArticle, Func_Ovml_Function_PutArray, Func_Ovml_Function_PutSoapArray, Func_Ovml_Function_PutVar, Func_Ovml_Function_Recurse, Func_Ovml_Function_Request, Func_Ovml_Function_SetCookie, Func_Ovml_Function_SetSessionVar, Func_Ovml_Function_SitemapCustomNodeId, Func_Ovml_Function_SitemapMenu, Func_Ovml_Function_SitemapPosition, Func_Ovml_Function_SitemapUrl, Func_Ovml_Function_Translate, Func_Ovml_Function_UrlContent, Func_Ovml_Function_WebStat, Func_PortalAuthentication, Func_PortalAuthentication_AuthOvidentia, Func_PwdComplexity, Func_PwdComplexity_DefaultPortal, Func_SearchUi, Func_SitemapDynamicNode, Func_SitemapDynamicNode_Topic, Func_UserEditor, Func_WorkingHours, Func_WorkingHours_Ovidentia, Ovml_Container_Sitemap, bab_ArithmeticOperator, bab_Ovml_Container_Operator, bab_rgp. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
1172
		return Func_Icons::ACTIONS_ARROW_RIGHT;
1173
	}
1174
	
1175
	
1176
	
1177
	
1178
	/**
1179
	 * Insert new right
1180 8
	 */
1181
	public function insert()
1182
	{
1183
		require_once $GLOBALS['babInstallPath'].'utilit/uuid.php';
1184
		global $babDB;
1185
		
1186
		$babDB->db_query("INSERT INTO absences_rights 
1187
			(
1188
				id_creditor,
1189
				kind,
1190
		        createdOn,
1191
				date_entry,
1192
				date_begin,
1193
				date_end,
1194
				quantity,
1195
				quantity_unit,
1196
				quantity_inc_month,
1197
				quantity_inc_max,
1198
				id_type,
1199
				description,
1200
				active,
1201
				cbalance,
1202
				date_begin_valid,
1203
				date_end_valid,
1204
				date_end_fixed,
1205
				date_begin_fixed,
1206
		        hide_empty,
1207
				no_distribution,
1208
				use_in_cet,
1209
				cet_quantity,
1210
				id_rgroup,  
1211
				earlier,
1212
				earlier_begin_valid,
1213
				earlier_end_valid,  
1214
				later,
1215
				later_begin_valid,
1216
				later_end_valid,
1217
				delay_before,
1218
				sync_status,
1219 8
				sync_update,
1220
				uuid,
1221
				archived
1222
			) 
1223
		VALUES 
1224
			(
1225
				".$babDB->quote(bab_getUserId()).",
1226
				".$babDB->quote($this->getKind()).",
1227
		        NOW(),
1228
				NOW(),
1229
				".$babDB->quote($this->date_begin).",
1230
				".$babDB->quote($this->date_end).",
1231
				".$babDB->quote($this->quantity).",
1232
				".$babDB->quote($this->quantity_unit).",
1233
				".$babDB->quote($this->quantity_inc_month).",
1234
				".$babDB->quote($this->quantity_inc_max).",
1235
				".$babDB->quote($this->id_type).",
1236
				".$babDB->quote($this->description).",
1237
				".$babDB->quote($this->active).",
1238
				".$babDB->quote($this->cbalance).",
1239
				".$babDB->quote($this->date_begin_valid).",
1240
				".$babDB->quote($this->date_end_valid).",
1241
				".$babDB->quote($this->date_end_fixed).",
1242
				".$babDB->quote($this->date_begin_fixed).",
1243
		        ".$babDB->quote($this->hide_empty).",
1244 5
				".$babDB->quote($this->no_distribution).",
1245
				".$babDB->quote($this->use_in_cet).",
1246
				".$babDB->quote($this->cet_quantity).",
1247
				".$babDB->quote($this->id_rgroup).",
1248
				".$babDB->quote($this->earlier).",
1249
				".$babDB->quote($this->earlier_begin_valid).",
1250
				".$babDB->quote($this->earlier_end_valid).",
1251
				".$babDB->quote($this->later).",
1252
				".$babDB->quote($this->later_begin_valid).",
1253
				".$babDB->quote($this->later_end_valid).",
1254
				".$babDB->quote($this->delay_before).",
1255
				".$babDB->quote($this->sync_status).",
1256
				".$babDB->quote($this->sync_update).",
1257
				".$babDB->quote($this->uuid).",
1258
				".$babDB->quote($this->archived)."
1259
			)
1260
		");
1261
		
1262
		
1263
		$this->id = $babDB->db_insert_id();
1264
	}
1265
	
1266
	
1267
	/**
1268
	 * Update by UUID
1269
	 */
1270
	public function update()
1271
	{
1272
		global $babDB;
1273
		
1274
		$query = 'UPDATE absences_rights SET 
1275
				kind='.$babDB->quote($this->kind).',
1276
				date_entry=NOW(),
1277
				date_begin='.$babDB->quote($this->date_begin).',
1278
				date_end='.$babDB->quote($this->date_end).',
1279
				quantity='.$babDB->quote($this->quantity).',
1280
				quantity_unit='.$babDB->quote($this->quantity_unit).',
1281
				quantity_inc_month='.$babDB->quote($this->quantity_inc_month).',
1282
				quantity_inc_max='.$babDB->quote($this->quantity_inc_max).',
1283
				description='.$babDB->quote($this->description).',
1284
				active='.$babDB->quote($this->active).',
1285
				cbalance='.$babDB->quote($this->cbalance).',
1286
				date_begin_valid='.$babDB->quote($this->date_begin_valid).',
1287
				date_end_valid='.$babDB->quote($this->date_end_valid).',
1288
				date_end_fixed='.$babDB->quote($this->date_end_fixed).',
1289
				date_begin_fixed='.$babDB->quote($this->date_begin_fixed).',
1290
				hide_empty='.$babDB->quote($this->hide_empty).',
1291
				no_distribution='.$babDB->quote($this->no_distribution).',
1292
				use_in_cet='.$babDB->quote($this->use_in_cet).',
1293
				cet_quantity='.$babDB->quote($this->cet_quantity).',
1294
				earlier='.$babDB->quote($this->earlier).',
1295
				earlier_begin_valid='.$babDB->quote($this->earlier_begin_valid).',
1296
				earlier_end_valid='.$babDB->quote($this->earlier_end_valid).',
1297
				later='.$babDB->quote($this->later).',
1298
				later_begin_valid='.$babDB->quote($this->later_begin_valid).',
1299
				later_end_valid='.$babDB->quote($this->later_end_valid).',
1300
				delay_before='.$babDB->quote($this->delay_before).',
1301
				sync_status='.$babDB->quote($this->sync_status).',
1302
				sync_update='.$babDB->quote($this->sync_update).',
1303
				archived='.$babDB->quote($this->archived).' 
1304
			WHERE uuid='.$babDB->quote($this->uuid).' 
1305
		';
1306
		
1307
		bab_debug($query);
1308
		
1309
		$babDB->db_query($query);
1310
	}
1311
	
1312
	
1313
	/**
1314
	 * 
1315
	 * @return string
1316
	 */
1317
	public function getQuantityAlertTypes()
1318
	{
1319
		$types = explode(',',$this->quantity_alert_types);
1320
		
1321
		if (empty($types))
1322
		{
1323
			return '';
1324
		}
1325
		
1326
		global $babDB;
1327
		
1328
		$res = $babDB->db_query('SELECT name FROM absences_types WHERE id IN('.$babDB->quote($types).')');
1329
		
1330
		$r = array();
1331
		while ($arr = $babDB->db_fetch_assoc($res))
1332
		{
1333
			$r[] = $arr['name'];
1334
		}
1335
		
1336
		return implode(', ', $r);
1337
	}
1338
1339 42
	
1340
	/**
1341 42
	 * @return absences_IncrementRight[]
1342 42
	 */
1343 42
	public function getIncrementIterator()
1344 42
	{
1345
	    require_once dirname(__FILE__).'/increment_right.class.php';
1346
	    $I = new absences_IncrementRightIterator;
1347
	    $I->setRight($this);
1348
	    return $I;
1349
	}
1350
	
1351
	
1352
	/**
1353
	 * Quantitee attribuee sur le droit par la mise a jour mensuelle
1354 23
	 * a condition qu'il n'y ai pas de quantite specifique pour l'agent
1355
	 * @param string $date     YYYY-MM-DD
1356 23
	 * @return float
1357 23
	 */
1358 23 View Code Duplication
	public function getIncrementQuantity($date = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
1359
	{
1360 23
	    $n = 0.0;
1361
	    $I = $this->getIncrementIterator();
1362 9
	    $I->upto = $date;
1363 23
	    
1364
	    foreach($I as $d)
1365 23
	    {
1366
	        $n += (float) $d->quantity;
1367
	    }
1368
	    
1369
	    return $n;
1370
	}
1371
	
1372
	
1373
	
1374
	public function getDynamicConfigurationIterator()
1375
	{
1376
		require_once dirname(__FILE__).'/dynamic_configuration.class.php';
1377
		
1378
		$I = new absences_DynamicConfigurationIterator;
1379
		$I->setRight($this);
1380
		
1381
		return $I;
1382
	}
1383
	
1384
	/**
1385
	 * @return array
1386
	 */
1387
	public function getDynamicTypes()
1388
	{
1389
		global $babDB;
1390
		
1391
		$arr = explode(',', $this->dynconf_types);
1392
		$r = array();
1393
		
1394
		$res = $babDB->db_query('SELECT name FROM absences_types WHERE id IN('.$babDB->quote($arr).')');
1395
		while ($arr = $babDB->db_fetch_assoc($res))
1396
		{
1397
			$r[] = $arr['name'];
1398
		}
1399
		
1400
		return $r;
1401
	}
1402
	
1403
	
1404
	/**
1405
	 * Quantite a ajouter pour le mois
1406
	 * tiens compte de la quantite max
1407
	 * 
1408 10
	 * @param float $current_quantity		Can be the right quantity or the user right quantity
1409
	 * 
1410 10
	 * @return float
1411 10
	 */
1412
	public function getQuantityIncMonth($current_quantity)
1413 10
	{
1414
		$add_quantity = (float) $this->quantity_inc_month;
1415 10
		$max = (float) $this->quantity_inc_max;
1416
1417 10
		$textmax = (int) round($max * 100);
1418 10
		
1419
		$new = ($add_quantity + $current_quantity);
1420 4
		
1421 4
		if ($textmax > 0 && $new > $max)
1422 3
		{
1423
		    
1424
			if ($current_quantity >= $max)
1425 2
			{
1426
				return 0.0;
1427
			}
1428 8
			
1429
			return ($max - $current_quantity);
1430
		}
1431
		
1432
		return $add_quantity;
1433
	}
1434
	
1435
	
1436
	/**
1437
	 * Movements related to the right
1438
	 * @return absences_MovementIterator
1439
	 */
1440
	public function getMovementIterator()
1441
	{
1442
	    require_once dirname(__FILE__).'/movement.class.php';
1443
	
1444
	    $I = new absences_MovementIterator();
1445
	    $I->setRight($this);
1446
	
1447
	    return $I;
1448
	}
1449
	
1450
	
1451
}
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
class absences_RightIterator extends absences_Iterator
1464
{
1465
	
1466
	/**
1467
	 * 
1468
	 * @var int | array
1469
	 */
1470
	public $kind;
1471
	
1472
	/**
1473
	 * les droit pas incrmentees depuis le premier jour du mois
1474
	 * @var ???
1475
	 */
1476
	public $increment;
1477
	
1478
	/**
1479
	 * 
1480
	 * @var bool
1481
	 */
1482
	public $active;
1483
	
1484
	
1485
	/**
1486
	 * 
1487
	 * @var int | array
1488
	 */
1489
	public $sync_status;
1490
	
1491
	
1492
	/**
1493
	 * 
1494
	 * @var int
1495
	 */
1496
	public $archived = 0;
1497
1498
1499
	public function getObject($data)
1500
	{
1501
		$right = new absences_Right($data['id']);
1502
		$right->setRow($data);
1503
1504
1505
		return $right;
1506
	}
1507
1508
	public function executeQuery()
1509
	{
1510
		if(is_null($this->_oResult))
1511
		{
1512
			global $babDB;
1513
1514
			$query = '
1515
			SELECT
1516
				r.*
1517
			FROM
1518
				absences_rights r
1519
			';
1520
			
1521
			$where = array();
1522
1523
			if (isset($this->kind))
1524
			{
1525
				$where[] = 'r.kind IN('.$babDB->quote($this->kind).')';
1526
			}
1527
1528
			if (isset($this->increment))
1529
			{
1530
				require_once $GLOBALS['babInstallPath'].'utilit/dateTime.php';
1531
				$limit = new BAB_DateTime(date('Y'), date('n'), 1);
1532
				
1533
				$where[] = 'r.quantity_inc_last<'.$babDB->quote($limit->getIsoDateTime());
1534
				$where[] = "r.quantity_inc_month>'0.00'";
1535
			}
1536
			
1537
			if (isset($this->active))
1538
			{
1539
				$where[] = 'r.active='.$babDB->quote($this->active ? 'Y' : 'N');
1540
			}
1541
			
1542
			if (isset($this->sync_status))
1543
			{
1544
				$where[] = 'r.sync_status IN('.$babDB->quote($this->sync_status).')';
1545
			}
1546
			
1547
			if (isset($this->archived))
1548
			{
1549
				$where[] = 'r.archived='.$babDB->quote($this->archived);
1550
			}
1551
			
1552
			if ($where)
0 ignored issues
show
Bug Best Practice introduced by
The expression $where of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
1553
			{
1554
				$query .= ' WHERE '.implode(' AND ', $where);
1555
			}
1556
			
1557
			bab_debug($query);
1558
1559
			$this->setMySqlResult($this->getDataBaseAdapter()->db_query($query));
1560
		}
1561
	}
1562
}
1563