|
|
<?php |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace Eluceo\iCal\Component; |
|
|
|
|
|
use Eluceo\iCal\Component; |
|
|
use Eluceo\iCal\Property; |
|
|
use Eluceo\iCal\Property\DateTimeProperty; |
|
|
use Eluceo\iCal\Property\DateTimesProperty; |
|
|
use Eluceo\iCal\Property\Event\Attachment; |
|
|
use Eluceo\iCal\Property\Event\Attendees; |
|
|
use Eluceo\iCal\Property\Event\Geo; |
|
|
use Eluceo\iCal\Property\Event\Organizer; |
|
|
use Eluceo\iCal\Property\Event\RecurrenceId; |
|
|
use Eluceo\iCal\Property\Event\RecurrenceRule; |
|
|
use Eluceo\iCal\Property\RawStringValue; |
|
|
use Eluceo\iCal\PropertyBag; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Event extends Component |
|
|
{ |
|
|
const TIME_TRANSPARENCY_OPAQUE = 'OPAQUE'; |
|
|
const TIME_TRANSPARENCY_TRANSPARENT = 'TRANSPARENT'; |
|
|
|
|
|
const STATUS_TENTATIVE = 'TENTATIVE'; |
|
|
const STATUS_CONFIRMED = 'CONFIRMED'; |
|
|
const STATUS_CANCELLED = 'CANCELLED'; |
|
|
|
|
|
const MS_BUSYSTATUS_FREE = 'FREE'; |
|
|
const MS_BUSYSTATUS_TENTATIVE = 'TENTATIVE'; |
|
|
const MS_BUSYSTATUS_BUSY = 'BUSY'; |
|
|
const MS_BUSYSTATUS_OOF = 'OOF'; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected $uniqueId; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected $dtStamp; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected $dtStart; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected $dtEnd; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected $duration; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected $noTime = false; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected $msBusyStatus = null; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected $url; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected $location; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected $locationTitle; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected $locationGeo; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected $summary; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected $organizer; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected $transparency = self::TIME_TRANSPARENCY_OPAQUE; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected $useTimezone = false; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected $timezoneString = ''; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected $sequence = 0; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected $attendees; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected $description; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected $descriptionHTML; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected $status; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected $recurrenceRule; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected $recurrenceRules = []; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected $created; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected $modified; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected $useUtc = true; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected $cancelled; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected $categories; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected $isPrivate = false; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected $exDates = []; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected $recurrenceId; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected $attachments = []; |
|
|
|
|
|
public function __construct(string $uniqueId = null) |
|
|
{ |
|
|
if (null == $uniqueId) { |
|
|
$uniqueId = uniqid(); |
|
|
} |
|
|
|
|
|
$this->uniqueId = $uniqueId; |
|
|
$this->attendees = new Attendees(); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function getType() |
|
|
{ |
|
|
return 'VEVENT'; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function buildPropertyBag() |
|
|
{ |
|
|
$propertyBag = new PropertyBag(); |
|
|
|
|
|
|
|
|
$propertyBag->set('UID', $this->uniqueId); |
|
|
|
|
|
$propertyBag->add(new DateTimeProperty('DTSTART', $this->dtStart, $this->noTime, $this->useTimezone, $this->useUtc, $this->timezoneString)); |
|
|
$propertyBag->set('SEQUENCE', $this->sequence); |
|
|
$propertyBag->set('TRANSP', $this->transparency); |
|
|
|
|
|
if ($this->status) { |
|
|
$propertyBag->set('STATUS', $this->status); |
|
|
} |
|
|
|
|
|
|
|
|
if ($this->dtEnd !== null) { |
|
|
$dtEnd = clone $this->dtEnd; |
|
|
if ($this->noTime === true) { |
|
|
$dtEnd = $dtEnd->add(new \DateInterval('P1D')); |
|
|
} |
|
|
$propertyBag->add(new DateTimeProperty('DTEND', $dtEnd, $this->noTime, $this->useTimezone, $this->useUtc, $this->timezoneString)); |
|
|
} elseif ($this->duration !== null) { |
|
|
$propertyBag->set('DURATION', $this->duration->format('P%dDT%hH%iM%sS')); |
|
|
} |
|
|
|
|
|
|
|
|
if (null != $this->url) { |
|
|
$propertyBag->set('URL', $this->url); |
|
|
} |
|
|
|
|
|
if (null != $this->location) { |
|
|
$propertyBag->set('LOCATION', $this->location); |
|
|
|
|
|
if (null != $this->locationGeo) { |
|
|
$propertyBag->add( |
|
|
new Property( |
|
|
'X-APPLE-STRUCTURED-LOCATION', |
|
|
new RawStringValue('geo:' . $this->locationGeo->getGeoLocationAsString(',')), |
|
|
[ |
|
|
'VALUE' => 'URI', |
|
|
'X-ADDRESS' => $this->location, |
|
|
'X-APPLE-RADIUS' => 49, |
|
|
'X-TITLE' => $this->locationTitle, |
|
|
] |
|
|
) |
|
|
); |
|
|
} |
|
|
} |
|
|
|
|
|
if (null != $this->locationGeo) { |
|
|
$propertyBag->add($this->locationGeo); |
|
|
} |
|
|
|
|
|
if (null != $this->summary) { |
|
|
$propertyBag->set('SUMMARY', $this->summary); |
|
|
} |
|
|
|
|
|
if (null != $this->attendees) { |
|
|
$propertyBag->add($this->attendees); |
|
|
} |
|
|
|
|
|
$propertyBag->set('CLASS', $this->isPrivate ? 'PRIVATE' : 'PUBLIC'); |
|
|
|
|
|
if (null != $this->description) { |
|
|
$propertyBag->set('DESCRIPTION', $this->description); |
|
|
} |
|
|
|
|
|
if (null != $this->descriptionHTML) { |
|
|
$propertyBag->add( |
|
|
new Property( |
|
|
'X-ALT-DESC', |
|
|
$this->descriptionHTML, |
|
|
[ |
|
|
'FMTTYPE' => 'text/html', |
|
|
] |
|
|
) |
|
|
); |
|
|
} |
|
|
|
|
|
if (null != $this->recurrenceRule) { |
|
|
$propertyBag->set('RRULE', $this->recurrenceRule); |
|
|
} |
|
|
|
|
|
foreach ($this->recurrenceRules as $recurrenceRule) { |
|
|
$propertyBag->set('RRULE', $recurrenceRule); |
|
|
} |
|
|
|
|
|
if (null != $this->recurrenceId) { |
|
|
$this->recurrenceId->applyTimeSettings($this->noTime, $this->useTimezone, $this->useUtc, $this->timezoneString); |
|
|
$propertyBag->add($this->recurrenceId); |
|
|
} |
|
|
|
|
|
if (!empty($this->exDates)) { |
|
|
$propertyBag->add(new DateTimesProperty('EXDATE', $this->exDates, $this->noTime, $this->useTimezone, $this->useUtc, $this->timezoneString)); |
|
|
} |
|
|
|
|
|
if ($this->cancelled) { |
|
|
$propertyBag->set('STATUS', 'CANCELLED'); |
|
|
} |
|
|
|
|
|
if (null != $this->organizer) { |
|
|
$propertyBag->add($this->organizer); |
|
|
} |
|
|
|
|
|
if ($this->noTime) { |
|
|
$propertyBag->set('X-MICROSOFT-CDO-ALLDAYEVENT', 'TRUE'); |
|
|
} |
|
|
|
|
|
if (null != $this->msBusyStatus) { |
|
|
$propertyBag->set('X-MICROSOFT-CDO-BUSYSTATUS', $this->msBusyStatus); |
|
|
$propertyBag->set('X-MICROSOFT-CDO-INTENDEDSTATUS', $this->msBusyStatus); |
|
|
} |
|
|
|
|
|
if (null != $this->categories) { |
|
|
$propertyBag->set('CATEGORIES', $this->categories); |
|
|
} |
|
|
|
|
|
$propertyBag->add( |
|
|
new DateTimeProperty('DTSTAMP', $this->dtStamp ?: new \DateTimeImmutable(), false, false, true) |
|
|
); |
|
|
|
|
|
if ($this->created) { |
|
|
$propertyBag->add(new DateTimeProperty('CREATED', $this->created, false, false, true)); |
|
|
} |
|
|
|
|
|
if ($this->modified) { |
|
|
$propertyBag->add(new DateTimeProperty('LAST-MODIFIED', $this->modified, false, false, true)); |
|
|
} |
|
|
|
|
|
foreach ($this->attachments as $attachment) { |
|
|
$propertyBag->add($attachment); |
|
|
} |
|
|
|
|
|
return $propertyBag; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function setDtEnd($dtEnd) |
|
|
{ |
|
|
$this->dtEnd = $dtEnd; |
|
|
|
|
|
return $this; |
|
|
} |
|
|
|
|
|
public function getDtEnd() |
|
|
{ |
|
|
return $this->dtEnd; |
|
|
} |
|
|
|
|
|
public function setDtStart($dtStart) |
|
|
{ |
|
|
$this->dtStart = $dtStart; |
|
|
|
|
|
return $this; |
|
|
} |
|
|
|
|
|
public function getDtStart() |
|
|
{ |
|
|
return $this->dtStart; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function setDtStamp($dtStamp) |
|
|
{ |
|
|
$this->dtStamp = $dtStamp; |
|
|
|
|
|
return $this; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function setDuration($duration) |
|
|
{ |
|
|
$this->duration = $duration; |
|
|
|
|
|
return $this; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function setLocation($location, $title = '', $geo = null) |
|
|
{ |
|
|
if (is_scalar($geo)) { |
|
|
$geo = Geo::fromString($geo); |
|
|
} elseif (!is_null($geo) && !$geo instanceof Geo) { |
|
|
$className = get_class($geo); |
|
|
throw new \InvalidArgumentException("The parameter 'geo' must be a string or an instance of " . Geo::class . " but an instance of {$className} was given."); |
|
|
} |
|
|
|
|
|
$this->location = $location; |
|
|
$this->locationTitle = $title; |
|
|
$this->locationGeo = $geo; |
|
|
|
|
|
return $this; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function setGeoLocation(Geo $geoProperty) |
|
|
{ |
|
|
$this->locationGeo = $geoProperty; |
|
|
|
|
|
return $this; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function setNoTime($noTime) |
|
|
{ |
|
|
$this->noTime = $noTime; |
|
|
|
|
|
return $this; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function setMsBusyStatus($msBusyStatus) |
|
|
{ |
|
|
$msBusyStatus = strtoupper($msBusyStatus); |
|
|
if ($msBusyStatus == self::MS_BUSYSTATUS_FREE |
|
|
|| $msBusyStatus == self::MS_BUSYSTATUS_TENTATIVE |
|
|
|| $msBusyStatus == self::MS_BUSYSTATUS_BUSY |
|
|
|| $msBusyStatus == self::MS_BUSYSTATUS_OOF |
|
|
) { |
|
|
$this->msBusyStatus = $msBusyStatus; |
|
|
} else { |
|
|
throw new \InvalidArgumentException('Invalid value for status'); |
|
|
} |
|
|
|
|
|
return $this; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function getMsBusyStatus() |
|
|
{ |
|
|
return $this->msBusyStatus; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function setSequence($sequence) |
|
|
{ |
|
|
$this->sequence = $sequence; |
|
|
|
|
|
return $this; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function getSequence() |
|
|
{ |
|
|
return $this->sequence; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function setOrganizer(Organizer $organizer) |
|
|
{ |
|
|
$this->organizer = $organizer; |
|
|
|
|
|
return $this; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function setSummary($summary) |
|
|
{ |
|
|
$this->summary = $summary; |
|
|
|
|
|
return $this; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function setUniqueId($uniqueId) |
|
|
{ |
|
|
$this->uniqueId = $uniqueId; |
|
|
|
|
|
return $this; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function getUniqueId() |
|
|
{ |
|
|
return $this->uniqueId; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function setUrl($url) |
|
|
{ |
|
|
$this->url = $url; |
|
|
|
|
|
return $this; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function setUseTimezone($useTimezone) |
|
|
{ |
|
|
$this->useTimezone = $useTimezone; |
|
|
|
|
|
return $this; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function getUseTimezone() |
|
|
{ |
|
|
return $this->useTimezone; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function setTimezoneString($timezoneString) |
|
|
{ |
|
|
$this->timezoneString = $timezoneString; |
|
|
|
|
|
return $this; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function getTimezoneString() |
|
|
{ |
|
|
return $this->timezoneString; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function setAttendees(Attendees $attendees) |
|
|
{ |
|
|
$this->attendees = $attendees; |
|
|
|
|
|
return $this; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function addAttendee($attendee, $params = []) |
|
|
{ |
|
|
$this->attendees->add($attendee, $params); |
|
|
|
|
|
return $this; |
|
|
} |
|
|
|
|
|
public function getAttendees(): Attendees |
|
|
{ |
|
|
return $this->attendees; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function setDescription($description) |
|
|
{ |
|
|
$this->description = $description; |
|
|
|
|
|
return $this; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function setDescriptionHTML($descriptionHTML) |
|
|
{ |
|
|
$this->descriptionHTML = $descriptionHTML; |
|
|
|
|
|
return $this; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function setUseUtc($useUtc = true) |
|
|
{ |
|
|
$this->useUtc = $useUtc; |
|
|
|
|
|
return $this; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function getDescription() |
|
|
{ |
|
|
return $this->description; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function getDescriptionHTML() |
|
|
{ |
|
|
return $this->descriptionHTML; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function setCancelled($status) |
|
|
{ |
|
|
$this->cancelled = (bool) $status; |
|
|
|
|
|
return $this; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function setTimeTransparency($transparency) |
|
|
{ |
|
|
$transparency = strtoupper($transparency); |
|
|
if ($transparency === self::TIME_TRANSPARENCY_OPAQUE |
|
|
|| $transparency === self::TIME_TRANSPARENCY_TRANSPARENT |
|
|
) { |
|
|
$this->transparency = $transparency; |
|
|
} else { |
|
|
throw new \InvalidArgumentException('Invalid value for transparancy'); |
|
|
} |
|
|
|
|
|
return $this; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function setStatus($status) |
|
|
{ |
|
|
$status = strtoupper($status); |
|
|
if ($status == self::STATUS_CANCELLED |
|
|
|| $status == self::STATUS_CONFIRMED |
|
|
|| $status == self::STATUS_TENTATIVE |
|
|
) { |
|
|
$this->status = $status; |
|
|
} else { |
|
|
throw new \InvalidArgumentException('Invalid value for status'); |
|
|
} |
|
|
|
|
|
return $this; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function setRecurrenceRule(RecurrenceRule $recurrenceRule) |
|
|
{ |
|
|
@trigger_error('setRecurrenceRule() is deprecated since version 0.11.0 and will be removed in 1.0. Use addRecurrenceRule instead.', E_USER_DEPRECATED); |
|
|
|
|
|
$this->recurrenceRule = $recurrenceRule; |
|
|
|
|
|
return $this; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function getRecurrenceRule() |
|
|
{ |
|
|
@trigger_error('getRecurrenceRule() is deprecated since version 0.11.0 and will be removed in 1.0. Use getRecurrenceRules instead.', E_USER_DEPRECATED); |
|
|
|
|
|
return $this->recurrenceRule; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function addRecurrenceRule(RecurrenceRule $recurrenceRule) |
|
|
{ |
|
|
$this->recurrenceRules[] = $recurrenceRule; |
|
|
|
|
|
return $this; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function getRecurrenceRules() |
|
|
{ |
|
|
return $this->recurrenceRules; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function setCreated($dtStamp) |
|
|
{ |
|
|
$this->created = $dtStamp; |
|
|
|
|
|
return $this; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function setModified($dtStamp) |
|
|
{ |
|
|
$this->modified = $dtStamp; |
|
|
|
|
|
return $this; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function setCategories($categories) |
|
|
{ |
|
|
$this->categories = $categories; |
|
|
|
|
|
return $this; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function setIsPrivate($flag) |
|
|
{ |
|
|
$this->isPrivate = (bool) $flag; |
|
|
|
|
|
return $this; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function addExDate(\DateTimeInterface $dateTime) |
|
|
{ |
|
|
$this->exDates[] = $dateTime; |
|
|
|
|
|
return $this; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function getExDates() |
|
|
{ |
|
|
return $this->exDates; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function setExDates(array $exDates) |
|
|
{ |
|
|
$this->exDates = $exDates; |
|
|
|
|
|
return $this; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function getRecurrenceId() |
|
|
{ |
|
|
return $this->recurrenceId; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function setRecurrenceId(RecurrenceId $recurrenceId) |
|
|
{ |
|
|
$this->recurrenceId = $recurrenceId; |
|
|
|
|
|
return $this; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function addAttachment(Attachment $attachment) |
|
|
{ |
|
|
$this->attachments[] = $attachment; |
|
|
|
|
|
return $this; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function getAttachments() |
|
|
{ |
|
|
return $this->attachments; |
|
|
} |
|
|
|
|
|
public function addUrlAttachment(string $url) |
|
|
{ |
|
|
$this->addAttachment(new Attachment($url)); |
|
|
} |
|
|
} |
|
|
|