This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | namespace JhFlexiTime\Service; |
||
4 | |||
5 | use JhFlexiTime\Entity\RunningBalance; |
||
6 | use JhFlexiTime\Repository\BalanceRepositoryInterface; |
||
7 | use JhFlexiTime\Repository\BookingRepositoryInterface; |
||
8 | use JhUser\Repository\UserRepositoryInterface; |
||
9 | use JhFlexiTime\Repository\UserSettingsRepositoryInterface; |
||
10 | use Zend\EventManager\EventManagerAwareInterface; |
||
11 | use ZfcUser\Entity\UserInterface; |
||
12 | use Doctrine\Common\Persistence\ObjectManager; |
||
13 | use JhFlexiTime\DateTime\DateTime; |
||
14 | use Zend\EventManager\EventManagerAwareTrait; |
||
15 | |||
16 | /** |
||
17 | * Class RunningBalanceService |
||
18 | * @package JhFlexiTime\Service |
||
19 | * @author Aydin Hassan <[email protected]> |
||
20 | */ |
||
21 | class RunningBalanceService implements EventManagerAwareInterface |
||
22 | { |
||
23 | |||
24 | use EventManagerAwareTrait; |
||
25 | |||
26 | /** |
||
27 | * @var \DateTime |
||
28 | */ |
||
29 | protected $date; |
||
30 | |||
31 | /** |
||
32 | * @var \JhUser\Repository\UserRepositoryInterface |
||
33 | */ |
||
34 | protected $userRepository; |
||
35 | |||
36 | /** |
||
37 | * @var \JhFlexiTime\Repository\UserSettingRepositoryInterface |
||
38 | */ |
||
39 | protected $userSettingsRepository; |
||
40 | |||
41 | /** |
||
42 | * @var \JhFlexiTime\Repository\BalanceRepositoryInterface |
||
43 | */ |
||
44 | protected $balanceRepository; |
||
45 | |||
46 | /** |
||
47 | * @var \JhFlexiTime\Repository\BookingRepositoryInterface |
||
48 | */ |
||
49 | protected $bookingRepository; |
||
50 | |||
51 | /** |
||
52 | * @var PeriodServiceInterface |
||
53 | */ |
||
54 | protected $periodService; |
||
55 | |||
56 | /** |
||
57 | * @var \DateTime |
||
58 | */ |
||
59 | protected $lastMonth; |
||
60 | |||
61 | /** |
||
62 | * @param UserRepositoryInterface $userRepository |
||
63 | * @param UserSettingsRepositoryInterface $userSettingsRepository |
||
64 | * @param BookingRepositoryInterface $bookingRepository |
||
65 | * @param BalanceRepositoryInterface $balanceRepository |
||
66 | * @param PeriodServiceInterface $periodService |
||
67 | * @param ObjectManager $objectManager |
||
68 | * @param DateTime $date |
||
69 | */ |
||
70 | public function __construct( |
||
71 | UserRepositoryInterface $userRepository, |
||
72 | UserSettingsRepositoryInterface $userSettingsRepository, |
||
73 | BookingRepositoryInterface $bookingRepository, |
||
74 | BalanceRepositoryInterface $balanceRepository, |
||
75 | PeriodServiceInterface $periodService, |
||
76 | ObjectManager $objectManager, |
||
77 | DateTime $date |
||
78 | ) { |
||
79 | $this->userRepository = $userRepository; |
||
80 | $this->userSettingsRepository = $userSettingsRepository; |
||
0 ignored issues
–
show
|
|||
81 | $this->bookingRepository = $bookingRepository; |
||
82 | $this->balanceRepository = $balanceRepository; |
||
83 | $this->periodService = $periodService; |
||
84 | $this->objectManager = $objectManager; |
||
0 ignored issues
–
show
The property
objectManager does not exist. Did you maybe forget to declare it?
In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code: class MyClass { }
$x = new MyClass();
$x->foo = true;
Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion: class MyClass {
public $foo;
}
$x = new MyClass();
$x->foo = true;
![]() |
|||
85 | $this->date = $date; |
||
86 | |||
87 | $this->lastMonth = clone $this->date; |
||
88 | $this->lastMonth->modify('first day of previous month 00:00'); |
||
89 | } |
||
90 | |||
91 | /** |
||
92 | * Calculate the previous month balance for all users |
||
93 | * and add it to their running balance |
||
94 | */ |
||
95 | public function indexPreviousMonthBalance() |
||
96 | { |
||
97 | foreach ($this->userRepository->findAll(false) as $user) { |
||
98 | $runningBalance = $this->balanceRepository->findOneByUser($user); |
||
99 | $userSettings = $this->userSettingsRepository->findOneByUser($user); |
||
100 | |||
101 | $date = $this->lastMonth; |
||
102 | //if user started this month use that as from date instead |
||
103 | if ($userSettings->getFlexStartDate() > $date) { |
||
104 | $date = $userSettings->getFlexStartDate(); |
||
105 | } |
||
106 | |||
107 | $this->addMonthBalance( |
||
108 | $user, |
||
109 | $runningBalance, |
||
110 | [ |
||
111 | 'start' => $date, |
||
112 | 'end' => $this->lastMonth->endOfMonth() |
||
0 ignored issues
–
show
It seems like you code against a specific sub-type and not the parent class
DateTime as the method endOfMonth() does only exist in the following sub-classes of DateTime : JhFlexiTime\DateTime\DateTime . 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
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types
inside the if block in such a case.
![]() |
|||
113 | ] |
||
114 | ); |
||
115 | } |
||
116 | |||
117 | $this->objectManager->flush(); |
||
118 | } |
||
119 | |||
120 | /** |
||
121 | * Recalculate all user's running balance |
||
122 | */ |
||
123 | public function reIndexAllUsersRunningBalance() |
||
124 | { |
||
125 | foreach ($this->userRepository->findAll(false) as $user) { |
||
126 | $runningBalance = $this->balanceRepository->findOneByUser($user); |
||
127 | $userSettings = $this->userSettingsRepository->findOneByUser($user); |
||
128 | |||
129 | $monthRanges = $this->getMonthRange( |
||
130 | $userSettings->getFlexStartDate(), |
||
131 | $this->lastMonth->endOfMonth() |
||
0 ignored issues
–
show
It seems like you code against a specific sub-type and not the parent class
DateTime as the method endOfMonth() does only exist in the following sub-classes of DateTime : JhFlexiTime\DateTime\DateTime . 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
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types
inside the if block in such a case.
![]() |
|||
132 | ); |
||
133 | |||
134 | $this->reIndexRunningBalance( |
||
135 | $user, |
||
136 | $runningBalance, |
||
137 | $monthRanges, |
||
138 | $userSettings->getStartingBalance() |
||
139 | ); |
||
140 | } |
||
141 | |||
142 | $this->objectManager->flush(); |
||
143 | } |
||
144 | |||
145 | /** |
||
146 | * Recaulculate Individual user's running balance |
||
147 | * |
||
148 | * @param UserInterface $user |
||
149 | */ |
||
150 | public function reIndexIndividualUserRunningBalance(UserInterface $user) |
||
151 | { |
||
152 | $runningBalance = $this->balanceRepository->findOneByUser($user); |
||
153 | $userSettings = $this->userSettingsRepository->findOneByUser($user); |
||
154 | |||
155 | $monthRanges = $this->getMonthRange( |
||
156 | $userSettings->getFlexStartDate(), |
||
157 | $this->lastMonth->endOfMonth() |
||
0 ignored issues
–
show
It seems like you code against a specific sub-type and not the parent class
DateTime as the method endOfMonth() does only exist in the following sub-classes of DateTime : JhFlexiTime\DateTime\DateTime . 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
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types
inside the if block in such a case.
![]() |
|||
158 | ); |
||
159 | |||
160 | $this->reIndexRunningBalance( |
||
161 | $user, |
||
162 | $runningBalance, |
||
163 | $monthRanges, |
||
164 | $userSettings->getStartingBalance() |
||
165 | ); |
||
166 | |||
167 | $this->objectManager->flush(); |
||
168 | } |
||
169 | |||
170 | /** |
||
171 | * @param UserInterface $user |
||
172 | * @param float $balance |
||
173 | */ |
||
174 | public function setUserStartingBalance(UserInterface $user, $balance) |
||
175 | { |
||
176 | $settings = $this->userSettingsRepository->findOneByUser($user); |
||
177 | $settings->setStartingBalance($balance); |
||
178 | $this->objectManager->flush(); |
||
179 | } |
||
180 | |||
181 | /** |
||
182 | * @param UserInterface $user |
||
183 | * @param RunningBalance $runningBalance |
||
184 | * @param array $months |
||
185 | * @param int $initialBalance |
||
186 | */ |
||
187 | private function reIndexRunningBalance( |
||
188 | UserInterface $user, |
||
189 | RunningBalance $runningBalance, |
||
190 | array $months, |
||
191 | $initialBalance |
||
192 | ) { |
||
193 | $eventData = ['runningBalance' => $runningBalance]; |
||
194 | $this->getEventManager()->trigger('reIndexUserRunningBalance.pre', null, $eventData); |
||
195 | |||
196 | $runningBalance->setBalance($initialBalance); |
||
197 | foreach ($months as $month) { |
||
198 | $this->addMonthBalance($user, $runningBalance, $month); |
||
199 | } |
||
200 | |||
201 | $this->getEventManager()->trigger('reIndexUserRunningBalance.post', null, $eventData); |
||
202 | } |
||
203 | |||
204 | /** |
||
205 | * @param UserInterface $user |
||
206 | * @param RunningBalance $runningBalance |
||
207 | * @param $month |
||
208 | */ |
||
209 | private function addMonthBalance(UserInterface $user, RunningBalance $runningBalance, array $month) |
||
210 | { |
||
211 | $eventData = ['runningBalance' => $runningBalance, 'month' => $month['end']]; |
||
212 | $this->getEventManager()->trigger('addMonthBalance.pre', null, $eventData); |
||
213 | |||
214 | $runningBalance->addBalance($this->calculateBalance($user, $month['start'], $month['end'])); |
||
215 | |||
216 | $this->getEventManager()->trigger('addMonthBalance.post', null, $eventData); |
||
217 | } |
||
218 | |||
219 | /** |
||
220 | * Calculate the balance between the two dates |
||
221 | * |
||
222 | * @param UserInterface $user |
||
223 | * @param DateTime $start |
||
224 | * @param DateTime $end |
||
225 | * @return float |
||
226 | */ |
||
227 | private function calculateBalance(UserInterface $user, DateTime $start, DateTime $end) |
||
228 | { |
||
229 | $monthTotalHours = $this->periodService->getTotalHoursBetweenDates($start, $end); |
||
230 | $totalBookedHours = $this->bookingRepository->getTotalBookedBetweenByUser($user, $start, $end); |
||
231 | $balance = $totalBookedHours - $monthTotalHours; |
||
232 | return $balance; |
||
233 | } |
||
234 | |||
235 | /** |
||
236 | * @param DateTime $start |
||
237 | * @param DateTime $end |
||
238 | * @return array |
||
239 | */ |
||
240 | private function getMonthRange(DateTime $start, DateTime $end) |
||
241 | { |
||
242 | $months = $start->getMonthsBetween($end); |
||
243 | $monthRanges = []; |
||
244 | foreach ($months as $key => $month) { |
||
245 | $monthRanges[] = [ |
||
246 | 'start' => $month->startOfMonth(), |
||
247 | 'end' => $month->endOfMonth() |
||
248 | ]; |
||
249 | |||
250 | if ($key === 0) { |
||
251 | $monthRanges[$key]['start'] = $start; |
||
252 | } |
||
253 | } |
||
254 | return $monthRanges; |
||
255 | } |
||
256 | } |
||
257 |
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..