Skip to content

Commit

Permalink
Fix an issue when creating events and sessions/ticket types in one go…
Browse files Browse the repository at this point in the history
… without saving
  • Loading branch information
engram-design committed Oct 27, 2024
1 parent a3a3daf commit 791b181
Show file tree
Hide file tree
Showing 5 changed files with 198 additions and 38 deletions.
10 changes: 5 additions & 5 deletions src/elements/Event.php
Original file line number Diff line number Diff line change
Expand Up @@ -641,7 +641,7 @@ public function getSessions(bool $includeDisabled = false): SessionCollection
$this->_sessions = self::createSessionQuery($this)->status(null)->collect();
}

return $this->_sessions->filter(fn(Session $session) => $includeDisabled || $session->enabled);
return $this->_sessions->filter(fn(Session $session) => $includeDisabled || ($session->getStatus() === self::STATUS_ENABLED));
}

public function setSessions(SessionCollection|SessionQuery|array $sessions): void
Expand Down Expand Up @@ -677,7 +677,7 @@ public function getTicketTypes(bool $includeDisabled = false): TicketTypeCollect
$this->_ticketTypes = self::createTicketTypeQuery($this)->status(null)->collect();
}

return $this->_ticketTypes->filter(fn(TicketType $ticketType) => $includeDisabled || $ticketType->enabled);
return $this->_ticketTypes->filter(fn(TicketType $ticketType) => $includeDisabled || ($ticketType->getStatus() === self::STATUS_ENABLED));
}

public function setTicketTypes(TicketTypeCollection|TicketTypeQuery|array $ticketTypes): void
Expand All @@ -696,7 +696,7 @@ public function getTicketTypeManager(): NestedElementManager
$this->_ticketTypeManager = new NestedElementManager(TicketType::class, fn(Event $event) => self::createTicketTypeQuery($event), [
'attribute' => 'ticketTypes',
'propagationMethod' => PropagationMethod::All,
'valueGetter' => fn() => $this->getTicketTypes(true),
'valueGetter' => fn(Event $event) => $event->getTicketTypes(true),
]);
}

Expand All @@ -713,7 +713,7 @@ public function getTickets(bool $includeDisabled = false): TicketCollection
$this->_tickets = self::createTicketQuery($this)->status(null)->collect();
}

return $this->_tickets->filter(fn(Ticket $ticket) => $includeDisabled || $ticket->enabled);
return $this->_tickets->filter(fn(Ticket $ticket) => $includeDisabled || ($ticket->getStatus() === self::STATUS_ENABLED));
}

public function setTickets(TicketCollection|TicketQuery|array $tickets): void
Expand All @@ -732,7 +732,7 @@ public function getTicketManager(): NestedElementManager
$this->_ticketManager = new NestedElementManager(Ticket::class, fn(Event $event) => self::createTicketQuery($event), [
'attribute' => 'tickets',
'propagationMethod' => PropagationMethod::All,
'valueGetter' => fn() => $this->getTickets(true),
'valueGetter' => fn(Event $event) => $event->getTickets(true),
'ownerIdParam' => 'eventId',
'primaryOwnerIdParam' => 'eventId',
]);
Expand Down
61 changes: 54 additions & 7 deletions src/elements/Session.php
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,34 @@ public static function gqlScopesByContext(mixed $context): array
return ['eventsEventTypes.' . $context->uid];
}

public static function eagerLoadingMap(array $sourceElements, string $handle): array|null|false
{
if ($handle == 'event') {
// Get the source element IDs
$sourceElementIds = [];

foreach ($sourceElements as $sourceElement) {
$sourceElementIds[] = $sourceElement->id;
}

$map = (new Query())
->select('id as source, primaryOwnerId as target')
->from('{{%events_sessions}}')
->where(['in', 'id', $sourceElementIds])
->all();

return [
'elementType' => Event::class,
'map' => $map,
'criteria' => [
'status' => null,
],
];
}

return self::traitEagerLoadingMap($sourceElements, $handle);
}

protected static function defineFieldLayouts(?string $source): array
{
// Being attached to an event element means we always have context, so improve performance
Expand Down Expand Up @@ -284,6 +312,22 @@ public function canDuplicate(User $user): bool
return $this->canSave($user);
}

public function safeAttributes()
{
$attributes = parent::safeAttributes();
$attributes[] = 'eventId';

return $attributes;
}

public function attributes(): array
{
$attributes = parent::attributes();
$attributes[] = 'event';

return $attributes;
}

public function setAttributesFromRequest(array $values): void
{
if (array_key_exists('frequencyData', $values)) {
Expand Down Expand Up @@ -370,6 +414,16 @@ public function setOwner(?ElementInterface $owner): void
$this->traitSetOwner($owner);
}

public function getEvent(): ?Event
{
return $this->getOwner();
}

public function setEvent(Event $event): void
{
$this->setOwner($event);
}

public function setEventSlug(?string $eventSlug): void
{
$this->_eventSlug = $eventSlug;
Expand Down Expand Up @@ -857,13 +911,6 @@ protected function destructiveActionMenuItems(): array
return $items;
}

protected function cacheTags(): array
{
return [
"event:$this->primaryOwnerId",
];
}

protected function cpEditUrl(): ?string
{
return UrlHelper::cpUrl('events/sessions/' . $this->id);
Expand Down
103 changes: 83 additions & 20 deletions src/elements/TicketType.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,34 @@ public static function gqlScopesByContext(mixed $context): array
return ['eventsEventTypes.' . $context->uid];
}

public static function eagerLoadingMap(array $sourceElements, string $handle): array|null|false
{
if ($handle == 'event') {
// Get the source element IDs
$sourceElementIds = [];

foreach ($sourceElements as $sourceElement) {
$sourceElementIds[] = $sourceElement->id;
}

$map = (new Query())
->select('id as source, primaryOwnerId as target')
->from('{{%events_ticket_types}}')
->where(['in', 'id', $sourceElementIds])
->all();

return [
'elementType' => Event::class,
'map' => $map,
'criteria' => [
'status' => null,
],
];
}

return self::traitEagerLoadingMap($sourceElements, $handle);
}

protected static function defineFieldLayouts(?string $source): array
{
// Being attached to an event element means we always have context, so improve performance
Expand Down Expand Up @@ -274,6 +302,22 @@ public function behaviors(): array
return $behaviors;
}

public function safeAttributes()
{
$attributes = parent::safeAttributes();
$attributes[] = 'eventId';

return $attributes;
}

public function attributes(): array
{
$attributes = parent::attributes();
$attributes[] = 'event';

return $attributes;
}

public function currencyAttributes(): array
{
return ['price'];
Expand Down Expand Up @@ -368,6 +412,16 @@ public function setOwner(?ElementInterface $owner): void
$this->traitSetOwner($owner);
}

public function getEvent(): ?Event
{
return $this->getOwner();
}

public function setEvent(Event $event): void
{
$this->setOwner($event);
}

public function setEventSlug(?string $eventSlug): void
{
$this->_eventSlug = $eventSlug;
Expand Down Expand Up @@ -435,6 +489,8 @@ public function beforeSave(bool $isNew): bool

public function afterSave(bool $isNew): void
{
$ownerId = $this->getOwnerId();

if (!$this->propagating) {
if (!$isNew) {
$record = TicketTypeRecord::findOne($this->id);
Expand Down Expand Up @@ -478,20 +534,34 @@ public function afterSave(bool $isNew): void

$this->id = $record->id;

$ownerId = $this->getOwnerId();

if ($ownerId && $this->saveOwnership) {
if (!isset($this->sortOrder) && !$isNew) {
// todo: update based on Entry::afterSave() if we add draft support
// (see https://github.com/craftcms/cms/pull/14497)
$this->sortOrder = (new Query())
->select('sortOrder')
->from(Table::ELEMENTS_OWNERS)
->where([
'elementId' => $this->id,
'ownerId' => $ownerId,
])
->scalar() ?: null;
if (!isset($this->sortOrder) && (!$isNew || $this->duplicateOf)) {
// figure out if we should proceed this way
// if we're dealing with an element that's being duplicated, and it has a draftId
// it means we're creating a draft of something
// if we're duplicating element via duplicate action - draftId would be empty
// Same as https://github.com/craftcms/cms/pull/14497/files
$elementId = null;

if ($this->duplicateOf) {
if ($this->draftId) {
$elementId = $this->duplicateOf->id;
}
} else {
// if we're not duplicating - use element's id
$elementId = $this->id;
}

if ($elementId) {
$this->sortOrder = (new Query())
->select('sortOrder')
->from(Table::ELEMENTS_OWNERS)
->where([
'elementId' => $elementId,
'ownerId' => $ownerId,
])
->scalar() ?: null;
}
}

if (!isset($this->sortOrder)) {
Expand Down Expand Up @@ -637,13 +707,6 @@ protected function inlineAttributeInputHtml(string $attribute): string
return parent::inlineAttributeInputHtml($attribute);
}

protected function cacheTags(): array
{
return [
"event:$this->primaryOwnerId",
];
}

protected function cpEditUrl(): ?string
{
return UrlHelper::cpUrl('events/ticket-types/' . $this->id);
Expand Down
33 changes: 29 additions & 4 deletions src/elements/db/SessionQuery.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ class SessionQuery extends ElementQuery

protected array $defaultOrderBy = ['events_sessions.dateCreated' => SORT_ASC];

private ?ElementInterface $_owner = null;


// Public Methods
// =========================================================================
Expand Down Expand Up @@ -71,6 +73,9 @@ public function owner(mixed $value): static
} else {
$this->ownerId = $value;
}

$this->_owner = $owner;

return $this;
}

Expand Down Expand Up @@ -99,6 +104,7 @@ public function primaryOwnerId(mixed $value): static
public function ownerId(mixed $value): static
{
$this->ownerId = $value;
$this->_owner = null;
return $this;
}

Expand Down Expand Up @@ -131,12 +137,25 @@ public function collect(?Connection $db = null): SessionCollection
return SessionCollection::make(parent::collect($db));
}

public function createElement(array $row): ElementInterface
{
if (isset($this->_owner)) {
$row['owner'] = $this->_owner;
}

return parent::createElement($row);
}

// // Protected Methods
// // =========================================================================

// Protected Methods
// =========================================================================

protected function beforePrepare(): bool
{
if (!parent::beforePrepare()) {
return false;
}

try {
$this->primaryOwnerId = $this->_normalizeOwnerId($this->primaryOwnerId);
} catch (InvalidArgumentException) {
Expand Down Expand Up @@ -215,16 +234,22 @@ protected function beforePrepare(): bool

$this->_applyHasEventParam();

return parent::beforePrepare();
return true;
}

protected function cacheTags(): array
{
$tags = [];

if ($this->primaryOwnerId) {
foreach ($this->primaryOwnerId as $ownerId) {
$tags[] = "element::$ownerId";
}
}

if ($this->ownerId) {
foreach ($this->ownerId as $ownerId) {
$tags[] = "event:$ownerId";
$tags[] = "element::$ownerId";
}
}

Expand Down
Loading

0 comments on commit 791b181

Please sign in to comment.