Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ See [keep a changelog] for information about writing changes to this log.

## [Unreleased]

- Updated fixtures. Made event organizer required.

## [1.1.6] - 2025-03-27

- Fix special char handling in event excerpt field, fix wrong chars in existing excerpt fields
Expand Down
12 changes: 10 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,10 @@ The application is built around Symfony and event messages for more information
[docs](docs/README.md) folder in this repository.

```shell
docker compose up -d
docker compose pull
docker compose up --detach --remove-orphans
docker compose exec phpfpm composer install
docker compose exec phpfpm bin/console doctrine:migrations:migrate
docker compose exec phpfpm bin/console doctrine:migrations:migrate --no-interaction
docker compose exec phpfpm bin/console app:index:create
docker compose exec phpfpm bin/console messenger:setup-transports
```
Expand Down Expand Up @@ -82,6 +83,13 @@ doctrine fixture load command:
docker compose exec phpfpm bin/console doctrine:fixtures:load
```

After loading fixtures, you can sign (on `/admin/login`) in as one of these users:

| Username | Password | Roles |
|--------------------|--------------|--------------|
| `[email protected]` | `admin` | `ROLE_ADMIN` |
| `[email protected]` | `1233456789` | `ROLE_ADMIN` |

### Production

When installing composer and Symfony based application in production, you should not install development packages,
Expand Down
4 changes: 2 additions & 2 deletions config/packages/security.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ security:
# Easy way to control access for large sections of your site
# Note: Only the *first* access control that matches will be used
access_control:
- { path: '^/admin/login', , roles: PUBLIC_ACCESS }
- { path: '^/admin/register', , roles: PUBLIC_ACCESS }
- { path: '^/admin/login', roles: PUBLIC_ACCESS }
- { path: '^/admin/register', roles: PUBLIC_ACCESS }
- { path: '^/admin', roles: !php/enum App\Types\UserRoles::ROLE_USER->value }
# - { path: ^/profile, roles: ROLE_USER }

Expand Down
84 changes: 0 additions & 84 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -30,90 +30,6 @@ parameters:
count: 1
path: src/Command/Migrate/MigrateTagsCommand.php

-
message: '#^Method Doctrine\\Common\\DataFixtures\\AbstractFixture\:\:getReference\(\) invoked with 1 parameter, 2 required\.$#'
identifier: arguments.count
count: 2
path: src/DataFixtures/DailyOccurrenceFixture.php

-
message: '#^Unable to resolve the template type T in call to method Doctrine\\Common\\DataFixtures\\AbstractFixture\:\:getReference\(\)$#'
identifier: argument.templateType
count: 2
path: src/DataFixtures/DailyOccurrenceFixture.php

-
message: '#^Method Doctrine\\Common\\DataFixtures\\AbstractFixture\:\:getReference\(\) invoked with 1 parameter, 2 required\.$#'
identifier: arguments.count
count: 13
path: src/DataFixtures/EventFixture.php

-
message: '#^Unable to resolve the template type T in call to method Doctrine\\Common\\DataFixtures\\AbstractFixture\:\:getReference\(\)$#'
identifier: argument.templateType
count: 13
path: src/DataFixtures/EventFixture.php

-
message: '#^Method Doctrine\\Common\\DataFixtures\\AbstractFixture\:\:getReference\(\) invoked with 1 parameter, 2 required\.$#'
identifier: arguments.count
count: 9
path: src/DataFixtures/FeedFixtures.php

-
message: '#^Unable to resolve the template type T in call to method Doctrine\\Common\\DataFixtures\\AbstractFixture\:\:getReference\(\)$#'
identifier: argument.templateType
count: 9
path: src/DataFixtures/FeedFixtures.php

-
message: '#^Method Doctrine\\Common\\DataFixtures\\AbstractFixture\:\:getReference\(\) invoked with 1 parameter, 2 required\.$#'
identifier: arguments.count
count: 1
path: src/DataFixtures/LocationFixture.php

-
message: '#^Unable to resolve the template type T in call to method Doctrine\\Common\\DataFixtures\\AbstractFixture\:\:getReference\(\)$#'
identifier: argument.templateType
count: 1
path: src/DataFixtures/LocationFixture.php

-
message: '#^Method Doctrine\\Common\\DataFixtures\\AbstractFixture\:\:getReference\(\) invoked with 1 parameter, 2 required\.$#'
identifier: arguments.count
count: 1
path: src/DataFixtures/OccurrenceFixture.php

-
message: '#^Unable to resolve the template type T in call to method Doctrine\\Common\\DataFixtures\\AbstractFixture\:\:getReference\(\)$#'
identifier: argument.templateType
count: 1
path: src/DataFixtures/OccurrenceFixture.php

-
message: '#^Method Doctrine\\Common\\DataFixtures\\AbstractFixture\:\:getReference\(\) invoked with 1 parameter, 2 required\.$#'
identifier: arguments.count
count: 1
path: src/DataFixtures/OrganizationFixtures.php

-
message: '#^Unable to resolve the template type T in call to method Doctrine\\Common\\DataFixtures\\AbstractFixture\:\:getReference\(\)$#'
identifier: argument.templateType
count: 1
path: src/DataFixtures/OrganizationFixtures.php

-
message: '#^Method Doctrine\\Common\\DataFixtures\\AbstractFixture\:\:getReference\(\) invoked with 1 parameter, 2 required\.$#'
identifier: arguments.count
count: 1
path: src/DataFixtures/TagsFixtures.php

-
message: '#^Unable to resolve the template type T in call to method Doctrine\\Common\\DataFixtures\\AbstractFixture\:\:getReference\(\)$#'
identifier: argument.templateType
count: 1
path: src/DataFixtures/TagsFixtures.php

-
message: '#^Call to method DateTimeImmutable\:\:setTimezone\(\) on a separate line has no effect\.$#'
identifier: method.resultUnused
Expand Down
30 changes: 15 additions & 15 deletions src/Controller/Admin/EventCrudController.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,10 @@
use App\Service\ImageServiceInterface;
use App\Types\UserRoles;
use Doctrine\Common\Collections\Order;
use Doctrine\ORM\QueryBuilder;
use EasyCorp\Bundle\EasyAdminBundle\Collection\FieldCollection;
use EasyCorp\Bundle\EasyAdminBundle\Config\Action;
use EasyCorp\Bundle\EasyAdminBundle\Config\Actions;
use EasyCorp\Bundle\EasyAdminBundle\Config\Asset;
use EasyCorp\Bundle\EasyAdminBundle\Config\Assets;
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
use EasyCorp\Bundle\EasyAdminBundle\Config\Filters;
use EasyCorp\Bundle\EasyAdminBundle\Config\KeyValueStore;
Expand Down Expand Up @@ -134,20 +132,22 @@ public function configureFields(string $pageName): iterable
yield FormField::addFieldset('Organizer information')
->setLabel(new TranslatableMessage('admin.event.organizer.headline'));

if ($this->isGranted(UserRoles::ROLE_EDITOR->value)) {
yield AssociationField::new('organization')
->setLabel(new TranslatableMessage('admin.event.edited.organization'));
} else {
yield AssociationField::new('organization')
->setLabel(new TranslatableMessage('admin.event.edited.organization'))
->setQueryBuilder(
fn (QueryBuilder $queryBuilder) => $queryBuilder
->select('o')
->from(Organization::class, 'o')
->where(':user MEMBER OF o.users')
->setParameter('user', $this->getUser())
);
$organization = AssociationField::new('organization')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few notes:

  • I think the original if/else construct has better readability but that is highly subjective
  • $organizationField would better signal what is assigned to the vaiable

As for the actual business logic, the intent was:

  • organizer is ALWAYS required
  • editor and admin users can set organizer from all available organizers.
  • organization-editor/admin can only select form organizations they belong to (they should ALWAYS belong to at least one organization, but I don't think this is enforced)

One further possible improvement (as stated in the linked ticket) would be for organization-editor/admin users that only belong to one organization. If we could set that organization as default value, and disable the field.

->setLabel(new TranslatableMessage('admin.event.edited.organization'))
// We assume at least one organization exist for non-editor users
// (cf. editor stuff below).
->setRequired(true)
->setFormTypeOption('placeholder', new TranslatableMessage('admin.event.organizer.placeholder'));
// Limit organization choices for non-editors to the organizations the user is a member of.
if (!$this->isGranted(UserRoles::ROLE_EDITOR->value)) {
$userOrganizations = $this->getUser()->getOrganizations();
$organization
->setFormTypeOption('choices', $userOrganizations)
// Make sure that the user is not forced to make a choice if none exists.
->setRequired($userOrganizations->count() > 0);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choice should exist, so better to throw an exception.

}
yield $organization;

yield AssociationField::new('partners')
->setLabel(new TranslatableMessage('admin.event.edited.partners'))
->hideOnDetail();
Expand Down
5 changes: 3 additions & 2 deletions src/DataFixtures/DailyOccurrenceFixture.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace App\DataFixtures;

use App\Entity\Event;
use App\Factory\DailyOccurrencesFactory;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Common\DataFixtures\DependentFixtureInterface;
Expand All @@ -16,10 +17,10 @@ public function __construct(

public function load(ObjectManager $manager): void
{
$event = $this->getReference(EventFixture::EVENT1);
$event = $this->getReference(EventFixture::EVENT1, Event::class);
$this->dailyOccurrencesFactory->createOrUpdate($event);

$event = $this->getReference(EventFixture::EVENT2);
$event = $this->getReference(EventFixture::EVENT2, Event::class);
$this->dailyOccurrencesFactory->createOrUpdate($event);
}

Expand Down
30 changes: 17 additions & 13 deletions src/DataFixtures/EventFixture.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@

use App\Entity\Event;
use App\Entity\Feed;
use App\Entity\Image;
use App\Entity\Location;
use App\Entity\Organization;
use App\Entity\Tag;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Common\DataFixtures\DependentFixtureInterface;
use Doctrine\Persistence\ObjectManager;
Expand All @@ -20,37 +24,37 @@ final class EventFixture extends Fixture implements DependentFixtureInterface
public function load(ObjectManager $manager): void
{
$event = new Event();
$event->setOrganization($this->getReference(OrganizationFixtures::ITK))
->addPartner($this->getReference(OrganizationFixtures::AAKB))
->addPartner($this->getReference(OrganizationFixtures::DOKK1))
$event->setOrganization($this->getReference(OrganizationFixtures::ITK, Organization::class))
->addPartner($this->getReference(OrganizationFixtures::AAKB, Organization::class))
->addPartner($this->getReference(OrganizationFixtures::DOKK1, Organization::class))
->setTitle('ITKDev test event 1')
->setExcerpt('Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.')
->setDescription('<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Quis blandit turpis cursus in. Nisl suscipit adipiscing bibendum est ultricies integer quis auctor. Diam donec adipiscing tristique risus nec feugiat. Tincidunt eget nullam non nisi est. Consectetur a erat nam at lectus urna. Vulputate sapien nec sagittis aliquam. Luctus venenatis lectus magna fringilla. Sit amet consectetur adipiscing elit duis tristique. Bibendum enim facilisis gravida neque convallis a.</p><p>Cursus eget nunc scelerisque viverra mauris in aliquam sem. Euismod elementum nisi quis eleifend quam adipiscing vitae proin sagittis.<br />Sodales ut eu sem integer vitae justo eget. Lacus sed viverra tellus in.</p>')
->setUrl('https://itk.aarhus.dk/nyheder/projektnyheder/robotternes-bidrag-til-den-groenne-omstilling/')
->setTicketUrl('https://www.aakb.dk/arrangementer/boern/skak-nu-eller-aldrig-18')
->setPublicAccess(true)
->setLocation($this->getReference(LocationFixture::ITKDEV))
->addTag($this->getReference(TagsFixtures::AROS))
->addTag($this->getReference(TagsFixtures::RACE))
->addTag($this->getReference(TagsFixtures::ITKDEV))
->setImage($this->getReference(ImagesFixtures::ITK))
->setLocation($this->getReference(LocationFixture::ITKDEV, Location::class))
->addTag($this->getReference(TagsFixtures::AROS, Tag::class))
->addTag($this->getReference(TagsFixtures::RACE, Tag::class))
->addTag($this->getReference(TagsFixtures::ITKDEV, Tag::class))
->setImage($this->getReference(ImagesFixtures::ITK, Image::class))
->setEditable(true);
$manager->persist($event);
$this->addReference(self::EVENT2, $event);

$event = new Event();
$event->setOrganization($this->getReference(OrganizationFixtures::ITK))
$event->setOrganization($this->getReference(OrganizationFixtures::ITK, Organization::class))
->setTitle('ITKDev test event 2')
->setExcerpt('Quis vel eros donec ac odio tempor orci dapibus ultrices. Velit dignissim sodales ut eu sem integer. Massa tincidunt dui ut ornare lectus sit amet est placerat.')
->setDescription('<p>Quam vulputate dignissim suspendisse in est ante. Libero enim sed faucibus turpis in eu mi bibendum. Gravida rutrum quisque non tellus orci. Eget nunc lobortis mattis aliquam faucibus purus in massa. Tortor posuere ac ut consequat semper viverra nam. Sapien et ligula ullamcorper malesuada. Et molestie ac feugiat sed lectus vestibulum mattis ullamcorper. At consectetur lorem donec massa sapien faucibus et. Ut consequat semper viverra nam libero. Hendrerit gravida rutrum quisque non tellus orci ac.</p>')
->setUrl('https://itk.aarhus.dk/nyheder/')
->setTicketUrl('https://www.aakb.dk/arrangementer/born/kreavaerksted-monsterboger-0')
->setPublicAccess(true)
->setLocation($this->getReference(LocationFixture::ITKDEV))
->addTag($this->getReference(TagsFixtures::CONCERT))
->addTag($this->getReference(TagsFixtures::AROS))
->setLocation($this->getReference(LocationFixture::ITKDEV, Location::class))
->addTag($this->getReference(TagsFixtures::CONCERT, Tag::class))
->addTag($this->getReference(TagsFixtures::AROS, Tag::class))
->setEditable(true)
->setImage($this->getReference(ImagesFixtures::AAK));
->setImage($this->getReference(ImagesFixtures::AAK, Image::class));
$manager->persist($event);
$this->addReference(self::EVENT1, $event);

Expand Down
20 changes: 11 additions & 9 deletions src/DataFixtures/FeedFixtures.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
namespace App\DataFixtures;

use App\Entity\Feed;
use App\Entity\Organization;
use App\Entity\User;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Common\DataFixtures\DependentFixtureInterface;
use Doctrine\Persistence\ObjectManager;
Expand Down Expand Up @@ -60,8 +62,8 @@ public function load(ObjectManager $manager): void
$feed->setName('Test feed - Aros')
->setEnabled(true)
->setConfiguration($config)
->setUser($this->getReference(UserFixtures::USER))
->setOrganization($this->getReference(OrganizationFixtures::ITK));
->setUser($this->getReference(UserFixtures::USER, User::class))
->setOrganization($this->getReference(OrganizationFixtures::ITK, Organization::class));
$manager->persist($feed);

$feed = new Feed();
Expand Down Expand Up @@ -103,8 +105,8 @@ public function load(ObjectManager $manager): void
$feed->setName('Test feed - Aakb')
->setEnabled(true)
->setConfiguration($config)
->setUser($this->getReference(UserFixtures::USER))
->setOrganization($this->getReference(OrganizationFixtures::AAKB));
->setUser($this->getReference(UserFixtures::USER, User::class))
->setOrganization($this->getReference(OrganizationFixtures::AAKB, Organization::class));
$manager->persist($feed);

$feed = new Feed();
Expand Down Expand Up @@ -149,8 +151,8 @@ public function load(ObjectManager $manager): void
$feed->setName('Test feed - Bora-bora')
->setEnabled(true)
->setConfiguration($config)
->setUser($this->getReference(UserFixtures::USER))
->setOrganization($this->getReference(OrganizationFixtures::ITK));
->setUser($this->getReference(UserFixtures::USER, User::class))
->setOrganization($this->getReference(OrganizationFixtures::ITK, Organization::class));
$manager->persist($feed);

$feed = new Feed();
Expand Down Expand Up @@ -189,7 +191,7 @@ public function load(ObjectManager $manager): void
$feed->setName('Test feed - Train')
->setEnabled(true)
->setConfiguration($config)
->setUser($this->getReference(UserFixtures::USER));
->setUser($this->getReference(UserFixtures::USER, User::class));
$manager->persist($feed);

$feed = new Feed();
Expand All @@ -216,8 +218,8 @@ public function load(ObjectManager $manager): void
$feed->setName('Test feed - HeadQuarters')
->setEnabled(false)
->setConfiguration($config)
->setUser($this->getReference(UserFixtures::USER))
->setOrganization($this->getReference(OrganizationFixtures::ITK));
->setUser($this->getReference(UserFixtures::USER, User::class))
->setOrganization($this->getReference(OrganizationFixtures::ITK, Organization::class));
$manager->persist($feed);

// Make it stick.
Expand Down
3 changes: 2 additions & 1 deletion src/DataFixtures/LocationFixture.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace App\DataFixtures;

use App\Entity\Address;
use App\Entity\Location;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Common\DataFixtures\DependentFixtureInterface;
Expand All @@ -17,7 +18,7 @@ public function load(ObjectManager $manager): void
$location->setName('ITK Development')
->setMail('[email protected]')
->setUrl('https://itk.aarhus.dk/om-itk/afdelinger/development/')
->setAddress($this->getReference(AddressFixture::ITKDEV))
->setAddress($this->getReference(AddressFixture::ITKDEV, Address::class))
->setDisabilityAccess(true)
->setEditable(true);
$manager->persist($location);
Expand Down
3 changes: 2 additions & 1 deletion src/DataFixtures/OccurrenceFixture.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace App\DataFixtures;

use App\Entity\Event;
use App\Entity\Occurrence;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Common\DataFixtures\DependentFixtureInterface;
Expand Down Expand Up @@ -86,7 +87,7 @@ private function createOccurrence(ObjectManager $manager, string $start, string
->setTicketPriceRange($price)
->setRoom($room)
->setEditable($editable)
->setEvent($this->getReference($event));
->setEvent($this->getReference($event, Event::class));

$manager->persist($occurrence);
$this->addReference($reference, $occurrence);
Expand Down
3 changes: 2 additions & 1 deletion src/DataFixtures/OrganizationFixtures.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace App\DataFixtures;

use App\Entity\Organization;
use App\Entity\User;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Common\DataFixtures\DependentFixtureInterface;
use Doctrine\Persistence\ObjectManager;
Expand Down Expand Up @@ -68,7 +69,7 @@ private function createOrganization(ObjectManager $manager, string $name, string
$org->setName($name)
->setMail($mail)
->setUrl($url)
->addUser($this->getReference(UserFixtures::USER));
->addUser($this->getReference(UserFixtures::USER, User::class));
$manager->persist($org);
$this->addReference($reference, $org);
}
Expand Down
3 changes: 2 additions & 1 deletion src/DataFixtures/TagsFixtures.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace App\DataFixtures;

use App\Entity\Tag;
use App\Entity\Vocabulary;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Common\DataFixtures\DependentFixtureInterface;
use Doctrine\Persistence\ObjectManager;
Expand Down Expand Up @@ -49,7 +50,7 @@ private function createTag(ObjectManager $manager, string $name, string $referen
{
$tag = new Tag();
$tag->setName($name)
->addVocabulary($this->getReference(VocabularyFixtures::MANAGED))
->addVocabulary($this->getReference(VocabularyFixtures::MANAGED, Vocabulary::class))
->setEditable($editable);

$manager->persist($tag);
Expand Down
Loading