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 | * Reservation.php |
||
4 | * |
||
5 | * @author Bram de Leeuw |
||
6 | * Date: 09/03/17 |
||
7 | */ |
||
8 | |||
9 | namespace Broarm\EventTickets; |
||
10 | |||
11 | use BetterButtonCustomAction; |
||
12 | use CalendarEvent; |
||
13 | use CheckboxField; |
||
14 | use Config; |
||
15 | use DataObject; |
||
16 | use DropdownField; |
||
17 | use Email; |
||
18 | use FieldList; |
||
19 | use Folder; |
||
20 | use GridField; |
||
21 | use GridFieldConfig_RecordViewer; |
||
22 | use HasManyList; |
||
23 | use ManyManyList; |
||
24 | use ReadonlyField; |
||
25 | use SilverStripe\Omnipay\GatewayInfo; |
||
26 | use SiteConfig; |
||
27 | use Tab; |
||
28 | use TabSet; |
||
29 | |||
30 | /** |
||
31 | * Class Reservation |
||
32 | * |
||
33 | * @package Broarm\EventTickets |
||
34 | * |
||
35 | * @property string Status |
||
36 | * @property string Title |
||
37 | * @property float Subtotal |
||
38 | * @property float Total |
||
39 | * @property string Comments |
||
40 | * @property string ReservationCode |
||
41 | * @property string Gateway |
||
42 | * @property boolean SentTickets |
||
43 | * @property boolean SentReservation |
||
44 | * @property boolean SentNotification |
||
45 | * |
||
46 | * @property int EventID |
||
47 | * @property int MainContactID |
||
48 | * |
||
49 | * @method CalendarEvent|TicketExtension Event() |
||
50 | * @method Attendee MainContact() |
||
51 | * @method HasManyList Payments() |
||
52 | * @method HasManyList Attendees() |
||
53 | * @method ManyManyList PriceModifiers() |
||
54 | */ |
||
55 | class Reservation extends DataObject |
||
56 | { |
||
57 | const STATUS_CART = 'CART'; |
||
58 | const STATUS_PENDING = 'PENDING'; |
||
59 | const STATUS_PAID = 'PAID'; |
||
60 | const STATUS_CANCELED = 'CANCELED'; |
||
61 | |||
62 | /** |
||
63 | * Time to wait before deleting the discarded cart |
||
64 | * Give a string that is parsable by strtotime |
||
65 | * |
||
66 | * @var string |
||
67 | */ |
||
68 | private static $delete_after = '+1 hour'; |
||
69 | |||
70 | /** |
||
71 | * The address to whom the ticket notifications are sent |
||
72 | * By default the admin email is used |
||
73 | * |
||
74 | * @config |
||
75 | * @var string |
||
76 | */ |
||
77 | private static $mail_sender; |
||
78 | |||
79 | /** |
||
80 | * The address from where the ticket mails are sent |
||
81 | * By default the admin email is used |
||
82 | * |
||
83 | * @config |
||
84 | * @var string |
||
85 | */ |
||
86 | private static $mail_receiver; |
||
87 | |||
88 | /** |
||
89 | * Send the receipt mail |
||
90 | * For organisations that only do free events you can configure |
||
91 | * this to hold back the receipt and only send the tickets |
||
92 | * |
||
93 | * @config |
||
94 | * @var bool |
||
95 | */ |
||
96 | private static $send_receipt_mail = true; |
||
97 | |||
98 | /** |
||
99 | * Send the admin notification |
||
100 | * |
||
101 | * @config |
||
102 | * @var bool |
||
103 | */ |
||
104 | private static $send_admin_notification = true; |
||
105 | |||
106 | private static $db = array( |
||
107 | 'Status' => 'Enum("CART,PENDING,PAID,CANCELED","CART")', |
||
108 | 'Title' => 'Varchar(255)', |
||
109 | 'Subtotal' => 'Currency', |
||
110 | 'Total' => 'Currency', |
||
111 | 'Gateway' => 'Varchar(255)', |
||
112 | 'Comments' => 'Text', |
||
113 | 'AgreeToTermsAndConditions' => 'Boolean', |
||
114 | 'ReservationCode' => 'Varchar(255)', |
||
115 | 'SentTickets' => 'Boolean', |
||
116 | 'SentReservation' => 'Boolean', |
||
117 | 'SentNotification' => 'Boolean', |
||
118 | ); |
||
119 | |||
120 | private static $default_sort = 'Created DESC'; |
||
121 | |||
122 | private static $has_one = array( |
||
123 | 'Event' => 'CalendarEvent', |
||
124 | 'MainContact' => 'Broarm\EventTickets\Attendee' |
||
125 | ); |
||
126 | |||
127 | private static $has_many = array( |
||
128 | 'Payments' => 'Payment', |
||
129 | 'Attendees' => 'Broarm\EventTickets\Attendee.Reservation' |
||
130 | ); |
||
131 | |||
132 | private static $belongs_many_many = array( |
||
133 | 'PriceModifiers' => 'Broarm\EventTickets\PriceModifier' |
||
134 | ); |
||
135 | |||
136 | private static $indexes = array( |
||
137 | 'ReservationCode' => 'unique("ReservationCode")' |
||
138 | ); |
||
139 | |||
140 | private static $summary_fields = array( |
||
0 ignored issues
–
show
Comprehensibility
introduced
by
![]() |
|||
141 | 'ReservationCode' => 'Reservation', |
||
142 | 'Title' => 'Customer', |
||
143 | 'Total.Nice' => 'Total', |
||
144 | 'State' => 'Status', |
||
145 | 'GatewayNice' => 'Payment method', |
||
146 | 'Created.Nice' => 'Date' |
||
147 | ); |
||
148 | |||
149 | /** |
||
150 | * Actions usable on the cms detail view |
||
151 | * |
||
152 | * @var array |
||
153 | */ |
||
154 | private static $better_buttons_actions = array( |
||
155 | 'send' |
||
156 | ); |
||
157 | |||
158 | public function getCMSFields() |
||
159 | { |
||
160 | $fields = new FieldList(new TabSet('Root', $mainTab = new Tab('Main'))); |
||
161 | $gridFieldConfig = GridFieldConfig_RecordViewer::create(); |
||
162 | $fields->addFieldsToTab('Root.Main', array( |
||
163 | ReadonlyField::create('ReservationCode', _t('Reservation.Code', 'Code')), |
||
164 | ReadonlyField::create('Created', _t('Reservation.Created', 'Date')), |
||
165 | DropdownField::create('Status', _t('Reservation.Status', 'Status'), $this->getStates()), |
||
166 | ReadonlyField::create('Title', _t('Reservation.MainContact', 'Main contact')), |
||
167 | ReadonlyField::create('GateWayNice', _t('Reservation.Gateway', 'Gateway')), |
||
168 | ReadonlyField::create('Total', _t('Reservation.Total', 'Total')), |
||
169 | ReadonlyField::create('Comments', _t('Reservation.Comments', 'Comments')), |
||
170 | CheckboxField::create('AgreeToTermsAndConditions', _t('Reservation.AgreeToTermsAndConditions', 'Agreed to terms and conditions'))->performReadonlyTransformation(), |
||
171 | GridField::create('Attendees', 'Attendees', $this->Attendees(), $gridFieldConfig), |
||
172 | GridField::create('Payments', 'Payments', $this->Payments(), $gridFieldConfig), |
||
173 | GridField::create('PriceModifiers', 'PriceModifiers', $this->PriceModifiers(), $gridFieldConfig) |
||
174 | )); |
||
175 | $fields->addFieldsToTab('Root.Main', array()); |
||
176 | $this->extend('updateCMSFields', $fields); |
||
177 | return $fields; |
||
178 | } |
||
179 | |||
180 | /** |
||
181 | * Add utility actions to the reservation details view |
||
182 | * |
||
183 | * @return FieldList |
||
184 | */ |
||
185 | public function getBetterButtonsActions() |
||
186 | { |
||
187 | /** @var FieldList $fields */ |
||
188 | $fields = parent::getBetterButtonsActions(); |
||
0 ignored issues
–
show
It seems like you code against a specific sub-type and not the parent class
DataObject as the method getBetterButtonsActions() does only exist in the following sub-classes of DataObject : Broarm\EventTickets\Attendee , Broarm\EventTickets\Reservation . 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.
![]() |
|||
189 | $fields->push(BetterButtonCustomAction::create('send', _t('Reservation.RESEND', 'Resend the reservation'))); |
||
190 | |||
191 | return $fields; |
||
192 | } |
||
193 | |||
194 | /** |
||
195 | * Generate a reservation code if it does not yet exists |
||
196 | */ |
||
197 | public function onBeforeWrite() |
||
198 | { |
||
199 | // Set the title to the name of the reservation holder |
||
200 | $this->Title = $this->getName(); |
||
201 | |||
202 | // Create a validation code to be used for confirmation and in the barcode |
||
203 | if ($this->exists() && empty($this->ReservationCode)) { |
||
204 | $this->ReservationCode = $this->createReservationCode(); |
||
205 | } |
||
206 | |||
207 | parent::onBeforeWrite(); |
||
208 | } |
||
209 | |||
210 | /** |
||
211 | * After deleting a reservation, delete the attendees and files |
||
212 | */ |
||
213 | public function onBeforeDelete() |
||
214 | { |
||
215 | // If a reservation is deleted remove the names from the guest list |
||
216 | foreach ($this->Attendees() as $attendee) { |
||
217 | /** @var Attendee $attendee */ |
||
218 | if ($attendee->exists()) { |
||
219 | $attendee->delete(); |
||
220 | } |
||
221 | } |
||
222 | |||
223 | // Remove the folder |
||
224 | if (($folder = Folder::get()->find('Name', $this->ReservationCode)) && $folder->exists() && $folder->isEmpty()) { |
||
225 | $folder->delete(); |
||
226 | } |
||
227 | |||
228 | parent::onBeforeDelete(); |
||
229 | } |
||
230 | |||
231 | /** |
||
232 | * Gets a nice unnamespaced name |
||
233 | * |
||
234 | * @return string |
||
235 | */ |
||
236 | public function singular_name() |
||
237 | { |
||
238 | $name = explode('\\', parent::singular_name()); |
||
239 | return trim(end($name)); |
||
240 | } |
||
241 | |||
242 | /** |
||
243 | * Returns the nice gateway title |
||
244 | * |
||
245 | * @return string |
||
246 | */ |
||
247 | public function getGatewayNice() |
||
248 | { |
||
249 | return GatewayInfo::niceTitle($this->Gateway); |
||
250 | } |
||
251 | |||
252 | /** |
||
253 | * Check if the cart is still in cart state and the delete_after time period has been exceeded |
||
254 | * |
||
255 | * @return bool |
||
256 | */ |
||
257 | public function isDiscarded() |
||
258 | { |
||
259 | $deleteAfter = strtotime(self::config()->get('delete_after'), strtotime($this->Created)); |
||
260 | return ($this->Status === 'CART') && (time() > $deleteAfter); |
||
261 | } |
||
262 | |||
263 | /** |
||
264 | * Get the full name |
||
265 | * |
||
266 | * @return string |
||
267 | */ |
||
268 | public function getName() |
||
269 | { |
||
270 | /** @var Attendee $attendee */ |
||
271 | if (($mainContact = $this->MainContact()) && $mainContact->exists() && $name = $mainContact->getName()) { |
||
272 | return $name; |
||
273 | } else { |
||
274 | return 'new reservation'; |
||
275 | } |
||
276 | } |
||
277 | |||
278 | /** |
||
279 | * Return the translated state |
||
280 | * |
||
281 | * @return string |
||
282 | */ |
||
283 | public function getState() |
||
284 | { |
||
285 | return _t("Reservation.{$this->Status}", $this->Status); |
||
286 | } |
||
287 | |||
288 | /** |
||
289 | * Get a the translated map of available states |
||
290 | * |
||
291 | * @return array |
||
292 | */ |
||
293 | private function getStates() |
||
294 | { |
||
295 | return array_map(function ($state) { |
||
296 | return _t("Reservation.$state", $state); |
||
297 | }, $this->dbObject('Status')->enumValues()); |
||
298 | } |
||
299 | |||
300 | /** |
||
301 | * Get the total by querying the sum of attendee ticket prices |
||
302 | * |
||
303 | * @return float |
||
0 ignored issues
–
show
|
|||
304 | */ |
||
305 | public function calculateTotal() |
||
306 | { |
||
307 | $total = $this->Subtotal = $this->Attendees()->leftJoin( |
||
308 | 'Broarm\EventTickets\Ticket', |
||
309 | '`Broarm\EventTickets\Attendee`.`TicketID` = `Broarm\EventTickets\Ticket`.`ID`' |
||
310 | )->sum('Price'); |
||
311 | |||
312 | // Calculate any price modifications if added |
||
313 | if ($this->PriceModifiers()->exists()) { |
||
314 | foreach ($this->PriceModifiers() as $priceModifier) { |
||
315 | $priceModifier->updateTotal($total, $this); |
||
316 | } |
||
317 | } |
||
318 | |||
319 | return $this->Total = $total; |
||
320 | } |
||
321 | |||
322 | /** |
||
323 | * Safely change to a state |
||
324 | * todo check if state direction matches |
||
325 | * |
||
326 | * @param $state |
||
327 | * |
||
328 | * @return boolean |
||
329 | */ |
||
330 | public function changeState($state) |
||
331 | { |
||
332 | $availableStates = $this->dbObject('Status')->enumValues(); |
||
333 | if (in_array($state, $availableStates)) { |
||
334 | $this->Status = $state; |
||
335 | return true; |
||
336 | } else { |
||
337 | user_error(_t('Reservation.STATE_CHANGE_ERROR', 'Selected state is not available')); |
||
338 | return false; |
||
339 | } |
||
340 | } |
||
341 | |||
342 | /** |
||
343 | * Complete the reservation |
||
344 | * |
||
345 | * @throws \ValidationException |
||
346 | */ |
||
347 | public function complete() |
||
348 | { |
||
349 | $this->changeState('PAID'); |
||
350 | $this->send(); |
||
351 | $this->write(); |
||
352 | $this->extend('onAfterComplete'); |
||
353 | } |
||
354 | |||
355 | /** |
||
356 | * Set the main contact id |
||
357 | * @param $id |
||
358 | * |
||
359 | * @throws \ValidationException |
||
360 | */ |
||
361 | public function setMainContact($id) |
||
362 | { |
||
363 | $this->MainContactID = $id; |
||
364 | $this->write(); |
||
365 | } |
||
366 | |||
367 | /** |
||
368 | * Create a reservation code |
||
369 | * |
||
370 | * @return string |
||
371 | */ |
||
372 | public function createReservationCode() |
||
373 | { |
||
374 | return uniqid($this->ID); |
||
375 | } |
||
376 | |||
377 | /** |
||
378 | * Generate the qr codes and downloadable pdf |
||
379 | */ |
||
380 | public function createFiles() |
||
381 | { |
||
382 | /** @var Attendee $attendee */ |
||
383 | foreach ($this->Attendees() as $attendee) { |
||
384 | $attendee->createQRCode(); |
||
385 | $attendee->createTicketFile(); |
||
386 | } |
||
387 | } |
||
388 | |||
389 | /** |
||
390 | * Send the reservation mail |
||
391 | * |
||
392 | * @return mixed |
||
393 | */ |
||
394 | public function sendReservation() |
||
395 | { |
||
396 | if (!self::config()->get('send_receipt_mail')) { |
||
397 | return true; |
||
398 | } |
||
399 | |||
400 | // Get the mail sender or fallback to the admin email |
||
401 | View Code Duplication | if (($from = self::config()->get('mail_sender')) && empty($from)) { |
|
0 ignored issues
–
show
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. ![]() |
|||
402 | $from = Config::inst()->get('Email', 'admin_email'); |
||
403 | } |
||
404 | |||
405 | // Create the email with given template and reservation data |
||
406 | $email = new Email(); |
||
407 | $email->setSubject(_t( |
||
408 | 'ReservationMail.TITLE', |
||
409 | 'Your order at {sitename}', |
||
410 | null, |
||
411 | array( |
||
0 ignored issues
–
show
array('sitename' => \Sit...t_site_config()->Title) is of type array<string,string,{"sitename":"string"}> , but the function expects a string .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
![]() |
|||
412 | 'sitename' => SiteConfig::current_site_config()->Title |
||
413 | ) |
||
414 | )); |
||
415 | $email->setFrom($from); |
||
416 | $email->setTo($this->MainContact()->Email); |
||
0 ignored issues
–
show
The property
Email does not exist on object<Broarm\EventTickets\Attendee> . Since you implemented __get , maybe consider adding a @property annotation.
Since your code implements the magic getter <?php
/**
* @property int $x
* @property int $y
* @property string $text
*/
class MyLabel
{
private $properties;
private $allowedProperties = array('x', 'y', 'text');
public function __get($name)
{
if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
return $properties[$name];
} else {
return null;
}
}
public function __set($name, $value)
{
if (in_array($name, $this->allowedProperties)) {
$properties[$name] = $value;
} else {
throw new \LogicException("Property $name is not defined.");
}
}
}
If the property has read access only, you can use the @property-read annotation instead. Of course, you may also just have mistyped another name, in which case you should fix the error. See also the PhpDoc documentation for @property. ![]() |
|||
417 | $email->setTemplate('ReservationMail'); |
||
418 | $email->populateTemplate($this); |
||
419 | $this->extend('updateReservationMail', $email); |
||
420 | return $email->send(); |
||
421 | } |
||
422 | |||
423 | /** |
||
424 | * Send the reserved tickets |
||
425 | * |
||
426 | * @return mixed |
||
427 | */ |
||
428 | public function sendTickets() |
||
429 | { |
||
430 | // Get the mail sender or fallback to the admin email |
||
431 | View Code Duplication | if (($from = self::config()->get('mail_sender')) && empty($from)) { |
|
0 ignored issues
–
show
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. ![]() |
|||
432 | $from = Config::inst()->get('Email', 'admin_email'); |
||
433 | } |
||
434 | |||
435 | // Send the tickets to the main contact |
||
436 | $email = new Email(); |
||
437 | $email->setSubject(_t( |
||
438 | 'MainContactMail.TITLE', |
||
439 | 'Uw tickets voor {event}', |
||
440 | null, |
||
441 | array( |
||
0 ignored issues
–
show
array('event' => $this->Event()->Title) is of type array<string,?,{"event":"?"}> , but the function expects a string .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
![]() |
|||
442 | 'event' => $this->Event()->Title |
||
443 | ) |
||
444 | )); |
||
445 | $email->setFrom($from); |
||
446 | $email->setTo($this->MainContact()->Email); |
||
0 ignored issues
–
show
The property
Email does not exist on object<Broarm\EventTickets\Attendee> . Since you implemented __get , maybe consider adding a @property annotation.
Since your code implements the magic getter <?php
/**
* @property int $x
* @property int $y
* @property string $text
*/
class MyLabel
{
private $properties;
private $allowedProperties = array('x', 'y', 'text');
public function __get($name)
{
if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
return $properties[$name];
} else {
return null;
}
}
public function __set($name, $value)
{
if (in_array($name, $this->allowedProperties)) {
$properties[$name] = $value;
} else {
throw new \LogicException("Property $name is not defined.");
}
}
}
If the property has read access only, you can use the @property-read annotation instead. Of course, you may also just have mistyped another name, in which case you should fix the error. See also the PhpDoc documentation for @property. ![]() |
|||
447 | $email->setTemplate('MainContactMail'); |
||
448 | $email->populateTemplate($this); |
||
449 | $this->extend('updateMainContactMail', $email); |
||
450 | $sent = $email->send(); |
||
451 | |||
452 | |||
453 | // Get the attendees for this event that are checked as receiver |
||
454 | $ticketReceivers = $this->Attendees()->filter('TicketReceiver', 1)->exclude('ID', $this->MainContactID); |
||
455 | if ($ticketReceivers->exists()) { |
||
456 | /** @var Attendee $ticketReceiver */ |
||
457 | foreach ($ticketReceivers as $ticketReceiver) { |
||
458 | $sentAttendee = $ticketReceiver->sendTicket(); |
||
459 | if ($sent && !$sentAttendee) { |
||
460 | $sent = $sentAttendee; |
||
461 | } |
||
462 | } |
||
463 | } |
||
464 | |||
465 | return $sent; |
||
466 | } |
||
467 | |||
468 | |||
469 | /** |
||
470 | * Send a booking notification to the ticket mail sender or the site admin |
||
471 | * @return mixed |
||
472 | */ |
||
473 | public function sendNotification() |
||
474 | { |
||
475 | if (!self::config()->get('send_admin_notification')) { |
||
476 | return true; |
||
477 | } |
||
478 | |||
479 | View Code Duplication | if (($from = self::config()->get('mail_sender')) && empty($from)) { |
|
0 ignored issues
–
show
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. ![]() |
|||
480 | $from = Config::inst()->get('Email', 'admin_email'); |
||
481 | } |
||
482 | |||
483 | View Code Duplication | if (($to = self::config()->get('mail_receiver')) && empty($to)) { |
|
0 ignored issues
–
show
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. ![]() |
|||
484 | $to = Config::inst()->get('Email', 'admin_email'); |
||
485 | } |
||
486 | |||
487 | $email = new Email(); |
||
488 | $email->setSubject(_t( |
||
489 | 'NotificationMail.TITLE', |
||
490 | 'Nieuwe reservering voor {event}', |
||
491 | null, array('event' => $this->Event()->Title) |
||
0 ignored issues
–
show
array('event' => $this->Event()->Title) is of type array<string,?,{"event":"?"}> , but the function expects a string .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
![]() |
|||
492 | )); |
||
493 | |||
494 | $email->setFrom($from); |
||
495 | $email->setTo($to); |
||
496 | $email->setTemplate('NotificationMail'); |
||
497 | $email->populateTemplate($this); |
||
498 | $this->extend('updateNotificationMail', $email); |
||
499 | return $email->send(); |
||
500 | } |
||
501 | |||
502 | /** |
||
503 | * Create the files and send the reservation, notification and tickets |
||
504 | */ |
||
505 | public function send() |
||
506 | { |
||
507 | $this->extend('onBeforeSend'); |
||
508 | $this->createFiles(); |
||
509 | $this->SentReservation = (boolean)$this->sendReservation(); |
||
510 | $this->SentNotification = (boolean)$this->sendNotification(); |
||
511 | $this->SentTickets = (boolean)$this->sendTickets(); |
||
512 | } |
||
513 | |||
514 | /** |
||
515 | * Get the download link |
||
516 | * |
||
517 | * @return string|null |
||
518 | */ |
||
519 | public function getDownloadLink() |
||
520 | { |
||
521 | /** @var Attendee $attendee */ |
||
522 | if ( |
||
523 | ($attendee = $this->Attendees()->first()) |
||
524 | && ($file = $attendee->TicketFile()) |
||
525 | && $file->exists() |
||
526 | ) { |
||
527 | return $file->Link(); |
||
528 | } |
||
529 | |||
530 | return null; |
||
531 | } |
||
532 | |||
533 | public function canView($member = null) |
||
0 ignored issues
–
show
The return type could not be reliably inferred; please add a
@return annotation.
Our type inference engine in quite powerful, but sometimes the code does not
provide enough clues to go by. In these cases we request you to add a ![]() |
|||
534 | { |
||
535 | return $this->Event()->canView($member); |
||
536 | } |
||
537 | |||
538 | public function canEdit($member = null) |
||
0 ignored issues
–
show
The return type could not be reliably inferred; please add a
@return annotation.
Our type inference engine in quite powerful, but sometimes the code does not
provide enough clues to go by. In these cases we request you to add a ![]() |
|||
539 | { |
||
540 | return $this->Event()->canEdit($member); |
||
541 | } |
||
542 | |||
543 | public function canDelete($member = null) |
||
0 ignored issues
–
show
The return type could not be reliably inferred; please add a
@return annotation.
Our type inference engine in quite powerful, but sometimes the code does not
provide enough clues to go by. In these cases we request you to add a ![]() |
|||
544 | { |
||
545 | return $this->Event()->canDelete($member); |
||
546 | } |
||
547 | |||
548 | public function canCreate($member = null) |
||
0 ignored issues
–
show
The return type could not be reliably inferred; please add a
@return annotation.
Our type inference engine in quite powerful, but sometimes the code does not
provide enough clues to go by. In these cases we request you to add a ![]() |
|||
549 | { |
||
550 | return $this->Event()->canCreate($member); |
||
551 | } |
||
552 | } |
||
553 |