From 8a0529272b337777ad65ec91f799b5de2dda7d22 Mon Sep 17 00:00:00 2001 From: Nathan Boiron Date: Mon, 20 Jan 2025 00:10:32 +0100 Subject: [PATCH] Refactor de la liste des antennes en DTOs --- .../views/admin/members/user_list.html.twig | 9 +- .../site/company_public_profile.html.twig | 6 +- app/Resources/views/site/offices.html.twig | 82 +-- app/Resources/views/site/talks/list.html.twig | 12 +- app/config/services.yml | 2 +- sources/AppBundle/Antennes/Antenne.php | 52 ++ .../AppBundle/Antennes/AntennesCollection.php | 485 ++++++++++++++++++ sources/AppBundle/Antennes/City.php | 24 + sources/AppBundle/Antennes/Map.php | 29 ++ sources/AppBundle/Antennes/Meetup.php | 20 + sources/AppBundle/Antennes/Point.php | 20 + sources/AppBundle/Antennes/Position.php | 20 + sources/AppBundle/Antennes/Socials.php | 31 ++ .../Association/Form/CompanyPublicProfile.php | 14 +- .../Association/Form/ContactDetailsType.php | 8 +- .../Form/NearestOfficeChoiceType.php | 8 +- sources/AppBundle/Association/Model/User.php | 7 +- .../Admin/Members/UserListAction.php | 10 +- .../CompanyPublicProfileController.php | 38 +- .../Controller/Website/StaticController.php | 5 +- .../Controller/Website/TalksController.php | 18 +- sources/AppBundle/Event/Form/TicketType.php | 8 +- .../Indexation/Meetups/MeetupScraper.php | 121 ++--- .../AppBundle/Indexation/Meetups/Runner.php | 7 +- .../Indexation/Meetups/Transformer.php | 34 +- sources/AppBundle/Offices/OfficeFinder.php | 15 +- .../AppBundle/Offices/OfficesCollection.php | 438 ---------------- sources/AppBundle/Twig/OfficesExtension.php | 29 +- .../Indexation/Meetups/MeetupScrapper.php | 11 - .../Indexation/Meetups/Transformer.php | 4 +- 30 files changed, 876 insertions(+), 691 deletions(-) create mode 100644 sources/AppBundle/Antennes/Antenne.php create mode 100644 sources/AppBundle/Antennes/AntennesCollection.php create mode 100644 sources/AppBundle/Antennes/City.php create mode 100644 sources/AppBundle/Antennes/Map.php create mode 100644 sources/AppBundle/Antennes/Meetup.php create mode 100644 sources/AppBundle/Antennes/Point.php create mode 100644 sources/AppBundle/Antennes/Position.php create mode 100644 sources/AppBundle/Antennes/Socials.php delete mode 100644 sources/AppBundle/Offices/OfficesCollection.php diff --git a/app/Resources/views/admin/members/user_list.html.twig b/app/Resources/views/admin/members/user_list.html.twig index 497fd888d..3705d310e 100644 --- a/app/Resources/views/admin/members/user_list.html.twig +++ b/app/Resources/views/admin/members/user_list.html.twig @@ -85,6 +85,7 @@   + {% for user in users %} {% set isActive = user.status == constant('AppBundle\\Association\\Model\\User::STATUS_ACTIVE') %} {% set isPending = user.status == constant('AppBundle\\Association\\Model\\User::STATUS_PENDING') %} @@ -102,11 +103,11 @@ {% endif %} - {% if user.nearestOffice in offices|keys %} + {% if user.nearestOffice in antennes|keys %} - - {{ offices[user.nearestOffice].label }} - + + {{ antennes[user.nearestOffice].label }} + {% endif %} diff --git a/app/Resources/views/site/company_public_profile.html.twig b/app/Resources/views/site/company_public_profile.html.twig index 09d56c52c..f2dd77978 100644 --- a/app/Resources/views/site/company_public_profile.html.twig +++ b/app/Resources/views/site/company_public_profile.html.twig @@ -65,10 +65,10 @@

Présente dans les antennes

- {% for local_office in offices %} + {% for antenne in antennes %}
-
- {{ local_office.label }} +
+ {{ antenne.label }}
{% else %}
diff --git a/app/Resources/views/site/offices.html.twig b/app/Resources/views/site/offices.html.twig index 14bfc06c5..f870ee0e3 100644 --- a/app/Resources/views/site/offices.html.twig +++ b/app/Resources/views/site/offices.html.twig @@ -338,80 +338,82 @@

Liste des antennes

- {% for office_code, office in offices %} + {% for antenne in antennes %}
- +
-

{{ office.label }}

+

{{ antenne.label }}

- {% if office.blog_url is defined %} - + {% if antenne.socials.blog is not null %} +  Blog {% endif %} - {% if office.twitter is defined %} - + {% if antenne.socials.twitter is not null %} +  Twitter {% endif %} - {% if office.linkedin is defined %} - + {% if antenne.socials.linkedin is not null %} +  LinkedIn {% endif %} - {% if office.bluesky is defined %} - + {% if antenne.socials.bluesky is not null %} + Bluesky {% endif %} - {% if office.meetup_urlname is defined %} - + {% if antenne.meetup is not null %} +  Meetup {% endif %} - - {% if office.youtube is defined %} - + + {% if antenne.socials.youtube is not null %} +  Youtube {% endif %} diff --git a/app/Resources/views/site/talks/list.html.twig b/app/Resources/views/site/talks/list.html.twig index 3806ba0c3..356e7a7d8 100644 --- a/app/Resources/views/site/talks/list.html.twig +++ b/app/Resources/views/site/talks/list.html.twig @@ -72,19 +72,19 @@
- {% for office_code, office in offices %} - {% if office.youtube is defined %} + {% for antenne in antennes %} + {% if antenne.socials.youtube is not null %}
- +
-

{{ office.label }}

+

{{ antenne.label }}

diff --git a/app/config/services.yml b/app/config/services.yml index 903f83db5..56736008e 100644 --- a/app/config/services.yml +++ b/app/config/services.yml @@ -388,7 +388,7 @@ services: AppBundle\Association\Factory\UserFactory: autowire: true - AppBundle\Offices\OfficesCollection: + AppBundle\Antennes\AntennesCollection: autowire: true AppBundle\Mailchimp\EventEventSubscriber: diff --git a/sources/AppBundle/Antennes/Antenne.php b/sources/AppBundle/Antennes/Antenne.php new file mode 100644 index 000000000..3e3e3ebe8 --- /dev/null +++ b/sources/AppBundle/Antennes/Antenne.php @@ -0,0 +1,52 @@ +|null */ + public ?array $departments; + + /** @var array|null */ + public ?array $pays; + + public bool $hideOnOfficesPage; + + /** + * @param string[] $departments + * @param string[]|null $pays + */ + public function __construct( + string $code, + string $label, + ?Meetup $meetup, + string $logoUrl, + Socials $socials, + ?Map $map, + ?array $departments = null, + ?array $pays = null, + bool $hideOnOfficesPage = false + ) { + $this->code = $code; + $this->label = $label; + $this->meetup = $meetup; + $this->logoUrl = $logoUrl; + $this->socials = $socials; + $this->map = $map; + $this->hideOnOfficesPage = $hideOnOfficesPage; + $this->departments = $departments; + $this->pays = $pays; + } +} diff --git a/sources/AppBundle/Antennes/AntennesCollection.php b/sources/AppBundle/Antennes/AntennesCollection.php new file mode 100644 index 000000000..736998b3f --- /dev/null +++ b/sources/AppBundle/Antennes/AntennesCollection.php @@ -0,0 +1,485 @@ + */ + private array $antennes; + + public function __construct() + { + $this->makeAntennes(); + } + + private function add(Antenne $antenne): void + { + $this->antennes[$antenne->code] = $antenne; + } + + /** + * @return array + */ + public function getAll(): array + { + return $this->antennes; + } + + public function findByMeetupId(string $meetupId): ?Antenne + { + foreach ($this->getAll() as $antenne) { + if ($antenne->meetup !== null && $antenne->meetup->id === $meetupId) { + return $antenne; + } + } + + throw new \InvalidArgumentException("Antenne introuvable via l'id meetup $meetupId"); + } + + /** + * @return array + */ + public function getAllSortedByLabels(): array + { + $antennes = array_filter( + $this->getAll(), + fn (Antenne $antenne) => !$antenne->hideOnOfficesPage, + ); + + uasort( + $antennes, + fn (Antenne $a, Antenne $b) => strcmp($a->label, $b->label), + ); + + return $antennes; + } + + public function findByCode(string $code): Antenne + { + foreach ($this->getAll() as $antenne) { + if ($antenne->code === $code) { + return $antenne; + } + } + + throw new \InvalidArgumentException("Antenne introuvable via le code $code"); + } + + /** + * @return array + */ + public function getOrderedLabelsByKey(): array + { + $labels = []; + foreach ($this->getAllSortedByLabels() as $antenne) { + $labels[$antenne->code] = $antenne->label; + } + + return $labels; + } + + private function makeAntennes(): void + { + $this->add(new Antenne( + 'bordeaux', + 'Bordeaux', + new Meetup('bordeaux-php-meetup', '18197674'), + '/images/offices/bordeaux.svg', + new Socials( + null, + null, + 'AFUP_Bordeaux', + 'afup-bordeaux', + 'bordeaux.afup.org', + ), + new Map( + false, + 'right', + new City( + new Point('330', '440'), + new Point('270', '500'), + new Point('230', '500'), + new Position('44.837912', '-0.579541'), + ), + ), + ['33'], + )); + + $this->add(new Antenne( + 'limoges', + 'Limoges', + new Meetup('afup-limoges-php', '23162834'), + '/images/offices/limoges.svg', + new Socials( + 'https://www.youtube.com/channel/UCPYMUpcC3b5zd-hVNGEWHAA', + 'https://limoges.afup.org', + 'AFUP_Limoges', + 'afup-limoges', + null, + ), + new Map( + false, + 'right', + new City( + new Point('410', '380'), + new Point('320', '380'), + new Point('230', '430'), + new Position('45.85', '1.25'), + ), + ), + ['87'], + )); + + $this->add(new Antenne( + 'lille', + 'Hauts de France', + new Meetup('afup-hauts-de-france-php', '23840677'), + '/images/offices/hdf.svg', + new Socials( + 'https://www.youtube.com/channel/UCkMGtNcB-VeqMlQ9p2JMIKg', + null, + 'afup_hdf', + 'afup-hdf', + 'hdf.afup.org', + ), + new Map( + false, + 'left', + new City( + new Point('490', '55'), + new Point('530', '30'), + new Point('605', '20'), + new Position('50.637222', '3.063333'), + ), + new City( + new Point('490', '55'), + new Point('530', '30'), + new Point('460', '110'), + new Position('49.894054', '2.295847'), + ), + ), + ['59', '80'], + )); + + $this->add(new Antenne( + 'luxembourg', + 'Luxembourg', + new Meetup('afup-luxembourg-php', '19631843'), + '/images/offices/luxembourg.svg', + new Socials( + null, + 'https://luxembourg.afup.org', + 'afup_luxembourg', + null, + null, + ), + new Map( + false, + 'left', + new City( + new Point('630', '130'), + new Point('660', '140'), + new Point('717', '140'), + new Position('49.61', '6.13333'), + ), + ), + null, + ['lux'], + )); + + $this->add(new Antenne( + 'lyon', + 'Lyon', + new Meetup('afup-lyon-php', '19630036'), + '/images/offices/lyon.svg', + new Socials( + 'https://www.youtube.com/channel/UCSHpe_EYwK0ZhitIJPGSjlQ', + 'https://lyon.afup.org', + 'AFUP_Lyon', + 'afup-lyon', + 'lyon.afup.org', + ), + new Map( + false, + 'left', + new City( + new Point('570', '380'), + new Point('680', '320'), + new Point('710', '320'), + new Position('45.759723', '4.842223'), + ), + ), + ['69'], + )); + + $this->add(new Antenne( + 'marseille', + 'Aix-Marseille', + new Meetup('afup-aix-marseille-php', '18152912'), + '/images/offices/marseille.svg', + new Socials( + 'https://www.youtube.com/channel/UC77cQ1izl155u6Y8daMZYiA', + 'https://aix-marseille.afup.org', + 'AFUP_AixMrs', + null, + null, + ), + new Map( + false, + 'top', + new City( + new Point('600', '540'), + new Point('600', '600'), + new Point('600', '600'), + new Position('43.296346', '5.36988923'), + ), + ), + ['13'], + )); + + $this->add(new Antenne( + 'montpellier', + 'Montpellier', + new Meetup('montpellier-php-meetup', '18724486'), + '/images/offices/montpellier.svg', + new Socials( + 'https://www.youtube.com/channel/UCr9f4-DksVhdv45q2245HeQ', + null, + 'afup_mtp', + 'montpellier-afup', + 'montpellier.afup.org', + ), + new Map( + false, + 'top', + new City( + new Point('530', '520'), + new Point('470', '590'), + new Point('470', '670'), + new Position('43.611944', '3.877222'), + ), + ), + ['34'], + )); + + $this->add(new Antenne( + 'nantes', + 'Nantes', + new Meetup('afup-nantes-php', '23839991'), + '/images/offices/nantes.svg', + new Socials( + null, + 'https://nantes.afup.org', + 'afup_nantes', + 'afup-nantes', + null, + ), + new Map( + true, + 'right', + new City( + new Point('285', '290'), + new Point('180', '290'), + new Point('180', '290'), + new Position('47.21806', '-1.55278'), + ), + ), + ['44'], + )); + + $this->add(new Antenne( + 'paris', + 'Paris', + new Meetup('afup-paris-php', '19629965'), + '/images/offices/paris.svg', + new Socials( + null, + null, + 'afup_paris', + null, + 'paris.afup.org', + ), + new Map( + false, + 'right', + new City( + new Point('460', '180'), + new Point('400', '60'), + new Point('360', '60'), + new Position('48.856578', '2.351828'), + ), + ), + ['75', '77', '78', '91', '92', '93', '94', '95'], + )); + + $this->add(new Antenne( + 'poitiers', + 'Poitiers', + new Meetup('afup-poitiers-php', '23106095'), + '/images/offices/poitiers.svg', + new Socials( + null, + null, + 'afup_poitiers', + 'afup-poitiers', + 'poitiers.afup.org', + ), + new Map( + false, + 'right', + new City( + new Point('365', '330'), + new Point('285', '360'), + new Point('180', '360'), + new Position('46.581945', '0.336112'), + ), + ), + ['86'], + )); + + $this->add(new Antenne( + 'reims', + 'Reims', + new Meetup('afup-reims-php', '23255694'), + '/images/offices/reims.svg', + new Socials( + 'https://www.youtube.com/channel/UCmkMmVqrt7eI7YMZovew_xw', + null, + 'afup_reims', + null, + null, + ), + new Map( + false, + 'left', + new City( + new Point('540', '150'), + new Point('600', '70'), + new Point('650', '70'), + new Position('49.26278', '4.03472'), + ), + ), + ['51'], + )); + + $this->add(new Antenne( + 'rennes', + 'Rennes', + new Meetup('afup-rennes', '22364687'), + '/images/offices/rennes.svg', + new Socials( + 'https://www.youtube.com/channel/UCv1VGfqKhygjTOZkdVUWfpQ', + 'https://rennes.afup.org', + 'AFUP_Rennes', + 'afup-rennes', + null, + ), + new Map( + false, + 'bottom', + new City( + new Point('285', '220'), + new Point('150', '220'), + new Point('120', '170'), + new Position('48.114722', '-1.679444'), + ), + ), + ['35'], + )); + + $this->add(new Antenne( + 'toulouse', + 'Toulouse', + new Meetup('aperophp-toulouse', '19947513'), + '/images/offices/toulouse.svg', + new Socials( + null, + 'https://toulouse.afup.org', + 'afup_toulouse', + null, + null, + ), + new Map( + false, + 'top', + new City( + new Point('420', '520'), + new Point('290', '590'), + new Point('290', '600'), + new Position('43.604482', '1.443962'), + ), + ), + ['31'], + )); + + $this->add(new Antenne( + 'lorraine', + 'Lorraine', + new Meetup('afup-lorraine-php', '26854931'), + '/images/offices/lorraine.svg', + new Socials( + 'https://www.youtube.com/channel/UC08QRZncvlgWxUbVbmUs42Q', + null, + 'AFUP_Lorraine', + 'afup-lorraine', + 'lorraine.afup.org', + ), + new Map( + false, + 'left', + new City( + new Point('650', '160'), + new Point('700', '220'), + new Point('740', '220'), + new Position('49.0685', '6.6151'), + ), + ), + ['54', '55', '57', '88'], + )); + + $this->add(new Antenne( + 'clermont', + 'Clermont', + null, + '/images/offices/empty.svg', + new Socials( + null, + null, + null, + null, + null, + ), + null, + null, + null, + true, + )); + + $this->add(new Antenne( + 'tours', + 'Tours', + new Meetup('afup-tours-php', '28638984'), + '/images/offices/tours.svg', + new Socials( + 'https://www.youtube.com/channel/UCtKhGIofgKM9ecrdZNyn_pA', + 'https://tours.afup.org', + 'AFUP_Tours', + 'afup-tours', + null, + ), + new Map( + false, + 'right', + new City( + new Point('380', '270'), + new Point('240', '90'), + new Point('200', '90'), + new Position('47.380001068115234', '0.6899999976158142'), + ), + ), + [''], + )); + } +} diff --git a/sources/AppBundle/Antennes/City.php b/sources/AppBundle/Antennes/City.php new file mode 100644 index 000000000..7fd5b2857 --- /dev/null +++ b/sources/AppBundle/Antennes/City.php @@ -0,0 +1,24 @@ +firstPoint = $firstPoint; + $this->secondPoint = $secondPoint; + $this->thirdPoint = $thirdPoint; + $this->position = $point; + } +} diff --git a/sources/AppBundle/Antennes/Map.php b/sources/AppBundle/Antennes/Map.php new file mode 100644 index 000000000..7785ee51c --- /dev/null +++ b/sources/AppBundle/Antennes/Map.php @@ -0,0 +1,29 @@ +firstCity = $firstCity; + $this->secondCity = $secondCity; + $this->useSecondColor = $useSecondColor; + $this->legendAttachment = $legendAttachment; + } +} diff --git a/sources/AppBundle/Antennes/Meetup.php b/sources/AppBundle/Antennes/Meetup.php new file mode 100644 index 000000000..eb7d6ac97 --- /dev/null +++ b/sources/AppBundle/Antennes/Meetup.php @@ -0,0 +1,20 @@ +urlName = $urlName; + $this->id = $id; + } +} diff --git a/sources/AppBundle/Antennes/Point.php b/sources/AppBundle/Antennes/Point.php new file mode 100644 index 000000000..bbe4c658c --- /dev/null +++ b/sources/AppBundle/Antennes/Point.php @@ -0,0 +1,20 @@ +x = $x; + $this->y = $y; + } +} diff --git a/sources/AppBundle/Antennes/Position.php b/sources/AppBundle/Antennes/Position.php new file mode 100644 index 000000000..b1d7482ce --- /dev/null +++ b/sources/AppBundle/Antennes/Position.php @@ -0,0 +1,20 @@ +latitude = $latitude; + $this->longitude = $longitude; + } +} diff --git a/sources/AppBundle/Antennes/Socials.php b/sources/AppBundle/Antennes/Socials.php new file mode 100644 index 000000000..2bcee04a8 --- /dev/null +++ b/sources/AppBundle/Antennes/Socials.php @@ -0,0 +1,31 @@ +youtube = $youtube; + $this->blog = $blog; + $this->twitter = $twitter; + $this->linkedin = $linkedin; + $this->bluesky = $bluesky; + } +} diff --git a/sources/AppBundle/Association/Form/CompanyPublicProfile.php b/sources/AppBundle/Association/Form/CompanyPublicProfile.php index 60e7e0cc1..f28bd48b1 100644 --- a/sources/AppBundle/Association/Form/CompanyPublicProfile.php +++ b/sources/AppBundle/Association/Form/CompanyPublicProfile.php @@ -4,7 +4,7 @@ namespace AppBundle\Association\Form; -use AppBundle\Offices\OfficesCollection; +use AppBundle\Antennes\AntennesCollection; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\CheckboxType; use Symfony\Component\Form\Extension\Core\Type\ChoiceType; @@ -29,11 +29,11 @@ class CompanyPublicProfile extends AbstractType public function buildForm(FormBuilderInterface $builder, array $options): void { - $officesCollection = new OfficesCollection(); + $antennesCollection = new AntennesCollection(); - $officesInfos = []; - foreach ($officesCollection->getAll() as $code => $office) { - $officesInfos[$office['label']] = $code; + $antennesInfos = []; + foreach ($antennesCollection->getAll() as $antenne) { + $antennesInfos[$antenne->label] = $antenne->code; } $logoConstraints = [ @@ -134,13 +134,13 @@ public function buildForm(FormBuilderInterface $builder, array $options): void ->add('related_afup_offices', ChoiceType::class, [ - 'choices' => $officesInfos, + 'choices' => $antennesInfos, 'multiple' => true, 'required' => false, 'label' => "Présence dans ces antennes AFUP", 'constraints' => [ new Choice([ - 'choices' => array_values($officesInfos), + 'choices' => array_values($antennesInfos), 'multiple' => true, ]), ] diff --git a/sources/AppBundle/Association/Form/ContactDetailsType.php b/sources/AppBundle/Association/Form/ContactDetailsType.php index 1ebc941fb..38558fa5a 100644 --- a/sources/AppBundle/Association/Form/ContactDetailsType.php +++ b/sources/AppBundle/Association/Form/ContactDetailsType.php @@ -6,8 +6,8 @@ namespace AppBundle\Association\Form; use Afup\Site\Utils\Pays; +use AppBundle\Antennes\AntennesCollection; use AppBundle\Association\Model\User; -use AppBundle\Offices\OfficesCollection; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\Extension\Core\Type\EmailType; @@ -112,10 +112,10 @@ public function configureOptions(OptionsResolver $resolver): void */ private function getOfficesList(): array { - $officesCollection = new OfficesCollection(); + $antennesCollection = new AntennesCollection(); $offices = ['' => '-Aucune-']; - foreach ($officesCollection->getOrderedLabelsByKey() as $id => $city) { - $offices[$city] = $id; + foreach ($antennesCollection->getAllSortedByLabels() as $antenne) { + $offices[$antenne->label] = $antenne->code; } return $offices; } diff --git a/sources/AppBundle/Association/Form/NearestOfficeChoiceType.php b/sources/AppBundle/Association/Form/NearestOfficeChoiceType.php index 9919946d6..4a8e86973 100644 --- a/sources/AppBundle/Association/Form/NearestOfficeChoiceType.php +++ b/sources/AppBundle/Association/Form/NearestOfficeChoiceType.php @@ -4,7 +4,7 @@ namespace AppBundle\Association\Form; -use AppBundle\Offices\OfficesCollection; +use AppBundle\Antennes\AntennesCollection; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\OptionsResolver\OptionsResolver; @@ -15,10 +15,10 @@ public function configureOptions(OptionsResolver $resolver): void { parent::configureOptions($resolver); - $officesCollection = new OfficesCollection(); + $antennesCollection = new AntennesCollection(); $offices = ['-Aucune-' => '']; - foreach ($officesCollection->getOrderedLabelsByKey() as $key => $label) { - $offices[$label] = $key; + foreach ($antennesCollection->getAllSortedByLabels() as $antenne) { + $offices[$antenne->label] = $antenne->code; } $resolver->setDefaults(['choices' => $offices]); diff --git a/sources/AppBundle/Association/Model/User.php b/sources/AppBundle/Association/Model/User.php index 95d4890d9..8c704b958 100644 --- a/sources/AppBundle/Association/Model/User.php +++ b/sources/AppBundle/Association/Model/User.php @@ -4,8 +4,8 @@ namespace AppBundle\Association\Model; +use AppBundle\Antennes\AntennesCollection; use AppBundle\Association\NotifiableInterface; -use AppBundle\Offices\OfficesCollection; use AppBundle\Validator\Constraints as AppAssert; use CCMBenchmark\Ting\Entity\NotifyProperty; use CCMBenchmark\Ting\Entity\NotifyPropertyInterface; @@ -220,10 +220,7 @@ public function getNearestOfficeLabel() return null; } - $collection = new OfficesCollection(); - $office = $collection->findByCode($code); - - return $office['label']; + return (new AntennesCollection())->findByCode($code)->label; } /** diff --git a/sources/AppBundle/Controller/Admin/Members/UserListAction.php b/sources/AppBundle/Controller/Admin/Members/UserListAction.php index c257bc748..d959fd93a 100644 --- a/sources/AppBundle/Controller/Admin/Members/UserListAction.php +++ b/sources/AppBundle/Controller/Admin/Members/UserListAction.php @@ -4,8 +4,8 @@ namespace AppBundle\Controller\Admin\Members; +use AppBundle\Antennes\AntennesCollection; use AppBundle\Association\Model\Repository\UserRepository; -use AppBundle\Offices\OfficesCollection; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Twig\Environment; @@ -13,16 +13,16 @@ class UserListAction { private UserRepository $userRepository; - private OfficesCollection $officesCollection; + private AntennesCollection $antennesCollection; private Environment $twig; public function __construct( UserRepository $userRepository, - OfficesCollection $officesCollection, + AntennesCollection $antennesCollection, Environment $twig ) { $this->userRepository = $userRepository; - $this->officesCollection = $officesCollection; + $this->antennesCollection = $antennesCollection; $this->twig = $twig; } @@ -36,7 +36,7 @@ public function __invoke(Request $request): Response $onlyDisplayActive = !$request->query->getBoolean('alsoDisplayInactive'); return new Response($this->twig->render('admin/members/user_list.html.twig', [ - 'offices' => $this->officesCollection->getAll(), + 'antennes' => $this->antennesCollection->getAll(), 'users' => $this->userRepository->search( $sort, $direction, diff --git a/sources/AppBundle/Controller/Website/CompanyPublicProfileController.php b/sources/AppBundle/Controller/Website/CompanyPublicProfileController.php index 3c7009fc8..f78c576f0 100644 --- a/sources/AppBundle/Controller/Website/CompanyPublicProfileController.php +++ b/sources/AppBundle/Controller/Website/CompanyPublicProfileController.php @@ -4,10 +4,11 @@ namespace AppBundle\Controller\Website; +use AppBundle\Antennes\Antenne; +use AppBundle\Antennes\AntennesCollection; use AppBundle\Association\Model\CompanyMember; use AppBundle\Association\Model\Repository\CompanyMemberRepository; use AppBundle\Association\UserMembership\BadgesComputer; -use AppBundle\Offices\OfficesCollection; use AppBundle\Twig\ViewRenderer; use CCMBenchmark\TingBundle\Repository\RepositoryFactory; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; @@ -21,11 +22,12 @@ class CompanyPublicProfileController extends AbstractController private RepositoryFactory $repositoryFactory; private string $storageDir; - public function __construct(ViewRenderer $view, - BadgesComputer $badgesComputer, - RepositoryFactory $repositoryFactory, - string $storageDir) - { + public function __construct( + ViewRenderer $view, + BadgesComputer $badgesComputer, + RepositoryFactory $repositoryFactory, + string $storageDir + ) { $this->view = $view; $this->badgesComputer = $badgesComputer; $this->repositoryFactory = $repositoryFactory; @@ -38,7 +40,7 @@ public function index($id, $slug): Response return $this->view->render('site/company_public_profile.html.twig', [ 'company_member' => $companyMember, - 'offices' => $this->getRelatedAfupOffices($companyMember), + 'antennes' => $this->getRelatedAfupAntennes($companyMember), 'badges' => $this->badgesComputer->getCompanyBadges($companyMember), ]); } @@ -82,27 +84,23 @@ public function logo($id, $slug) } /** - * @return mixed[] + * @return list */ - private function getRelatedAfupOffices(CompanyMember $companyMember): array + private function getRelatedAfupAntennes(CompanyMember $companyMember): array { - $officesCollection = new OfficesCollection(); - $offices = []; + $antennesCollection = new AntennesCollection(); + $antennes = []; foreach ($companyMember->getFormattedRelatedAfupOffices() as $localOffice) { - $office = $officesCollection->findByCode($localOffice); - if (null === $office || isset($office['hide_on_offices_page'])) { + $antenne = $antennesCollection->findByCode($localOffice); + if ($antenne->hideOnOfficesPage) { continue; } - $offices[] = $office; + $antennes[] = $antenne; } - usort($offices, function (array $a, array $b): int { - $a = $a['label']; - $b = $b['label']; - return $a <=> $b; - }); + usort($antennes, fn (Antenne $a, Antenne $b) => $a->label <=> $b->label); - return $offices; + return $antennes; } } diff --git a/sources/AppBundle/Controller/Website/StaticController.php b/sources/AppBundle/Controller/Website/StaticController.php index 244d60674..d3d085e3c 100644 --- a/sources/AppBundle/Controller/Website/StaticController.php +++ b/sources/AppBundle/Controller/Website/StaticController.php @@ -5,7 +5,7 @@ namespace AppBundle\Controller\Website; -use AppBundle\Offices\OfficesCollection; +use AppBundle\Antennes\AntennesCollection; use AppBundle\Twig\ViewRenderer; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Request; @@ -24,9 +24,8 @@ public function __construct(ViewRenderer $view, string $superAperoCsvUrl) public function offices(): Response { - $officesCollection = new OfficesCollection(); return $this->view->render(':site:offices.html.twig', [ - 'offices' => $officesCollection->getAllSortedByLabels() + 'antennes' => (new AntennesCollection())->getAllSortedByLabels(), ]); } diff --git a/sources/AppBundle/Controller/Website/TalksController.php b/sources/AppBundle/Controller/Website/TalksController.php index 5d4b6979a..9f7217dc5 100644 --- a/sources/AppBundle/Controller/Website/TalksController.php +++ b/sources/AppBundle/Controller/Website/TalksController.php @@ -4,13 +4,13 @@ namespace AppBundle\Controller\Website; +use AppBundle\Antennes\AntennesCollection; use AppBundle\Event\Model\Repository\EventRepository; use AppBundle\Event\Model\Repository\PlanningRepository; use AppBundle\Event\Model\Repository\SpeakerRepository; use AppBundle\Event\Model\Repository\TalkRepository; use AppBundle\Joindin\JoindinComments; use AppBundle\Joindin\JoindinTalk; -use AppBundle\Offices\OfficesCollection; use AppBundle\Subtitles\Parser; use AppBundle\Twig\ViewRenderer; use CCMBenchmark\TingBundle\Repository\RepositoryFactory; @@ -27,12 +27,13 @@ class TalksController extends AbstractController private string $algoliaAppId; private string $algoliaFrontendApikey; - public function __construct(ViewRenderer $view, - RepositoryFactory $repositoryFactory, - JoindinComments $joindinComments, - JoindinTalk $joindinTalk, - string $algoliaAppId, - string $algoliaFrontendApikey + public function __construct( + ViewRenderer $view, + RepositoryFactory $repositoryFactory, + JoindinComments $joindinComments, + JoindinTalk $joindinTalk, + string $algoliaAppId, + string $algoliaFrontendApikey ) { $this->view = $view; $this->repositoryFactory = $repositoryFactory; @@ -44,9 +45,8 @@ public function __construct(ViewRenderer $view, public function list(): Response { - $officesCollection = new OfficesCollection(); return $this->view->render('site/talks/list.html.twig', [ - 'offices' => $officesCollection->getAllSortedByLabels(), + 'antennes' => (new AntennesCollection())->getAllSortedByLabels(), 'algolia_app_id' => $this->algoliaAppId, 'algolia_api_key' => $this->algoliaFrontendApikey, ]); diff --git a/sources/AppBundle/Event/Form/TicketType.php b/sources/AppBundle/Event/Form/TicketType.php index d6d7b252d..e42d87750 100644 --- a/sources/AppBundle/Event/Form/TicketType.php +++ b/sources/AppBundle/Event/Form/TicketType.php @@ -4,6 +4,7 @@ namespace AppBundle\Event\Form; +use AppBundle\Antennes\AntennesCollection; use AppBundle\Event\Model\Repository\EventRepository; use AppBundle\Event\Model\Repository\TicketEventTypeRepository; use AppBundle\Event\Model\Repository\TicketSpecialPriceRepository; @@ -11,7 +12,6 @@ use AppBundle\Event\Model\Ticket; use AppBundle\Event\Model\TicketEventType; use AppBundle\Event\Ticket\TicketTypeAvailability; -use AppBundle\Offices\OfficesCollection; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Exception\RuntimeException; use Symfony\Component\Form\Extension\Core\Type\ChoiceType; @@ -39,7 +39,7 @@ class TicketType extends AbstractType private TicketTypeRepository $ticketTypeRepository; - protected OfficesCollection $officesCollection; + private AntennesCollection $antennesCollection; public function __construct( EventRepository $eventRepository, @@ -53,7 +53,7 @@ public function __construct( $this->ticketTypeAvailability = $ticketTypeAvailability; $this->ticketSpecialPriceRepository = $ticketSpecialPriceRepository; $this->ticketTypeRepository = $ticketTypeRepository; - $this->officesCollection = new OfficesCollection(); + $this->antennesCollection = new AntennesCollection(); } public function buildForm(FormBuilderInterface $builder, array $options): void @@ -93,7 +93,7 @@ public function buildForm(FormBuilderInterface $builder, array $options): void ->add('nearestOffice', ChoiceType::class, [ 'label' => 'Antenne de prédilection', 'required' => false, - 'choices' => array_flip($this->officesCollection->getOrderedLabelsByKey()), + 'choices' => array_flip($this->antennesCollection->getOrderedLabelsByKey()), ]) ; diff --git a/sources/AppBundle/Indexation/Meetups/MeetupScraper.php b/sources/AppBundle/Indexation/Meetups/MeetupScraper.php index bf3f1165e..118802959 100644 --- a/sources/AppBundle/Indexation/Meetups/MeetupScraper.php +++ b/sources/AppBundle/Indexation/Meetups/MeetupScraper.php @@ -4,8 +4,9 @@ namespace AppBundle\Indexation\Meetups; +use AppBundle\Antennes\Antenne; +use AppBundle\Antennes\AntennesCollection; use AppBundle\Event\Model\Meetup; -use AppBundle\Offices\OfficesCollection; use DOMDocument; use DOMXPath; use Exception; @@ -29,49 +30,49 @@ public function getEvents() $eventsArray = []; foreach ($antennes as $antenneKey => $antenne) { - if (array_key_exists('meetup_urlname', $antenne)) { - //Si l'antenne a une meetup_urlname - $meetupUrl = $this->getMeetupUrlNameFromAntenneArray($antenne); - $meetupAntenneName = $antenneKey; - - $xpath = $this->getDomContent($meetupUrl); - - $events = $xpath->query("//*[contains(@id, 'event-card')]"); - foreach ($events as $event) { - try { - if (!$event instanceof \DOMElement) { - throw new \Exception('Élement DOM de type invalide'); - } - - $eventUrl = $event->getAttribute('href'); - - if (preg_match('/\/events\/(\d+)\//', $eventUrl, $matches)) { - $id = (int) $matches[1]; - } else { - throw new Exception(sprintf('Pas d\'id pour cet évent de l\'antenne %s', $antenne)); - } - - $dateString = $xpath->query(".//time", $event)->item(0)->nodeValue; - $dateTime = (new MeetupDateTimeConverter())->convertStringToDateTime($dateString); - - $title = $xpath->query(".//span[contains(@class, 'cardTitle')]", $event)->item(0)->nodeValue; - - $descriptionElements = $xpath->query("//div[contains(@class, 'utils_cardDescription__alO8K')]"); - - $description = ''; - foreach ($descriptionElements as $descriptionElement) { - $description .= ' ' . $descriptionElement->nodeValue; - } - - $eventsArray[$meetupAntenneName][] = (new Meetup()) - ->setId($id) - ->setDate($dateTime) - ->setTitle($title) - ->setDescription($description) - ->setAntenneName($meetupAntenneName); - } catch (Exception $e) { - throw new Exception('Problème à la construction d\'un évenement', $e->getCode(), $e); + if ($antenne->meetup === null) { + continue; + } + + $meetupAntenneName = $antenneKey; + + $xpath = $this->getDomContent($antenne->meetup->urlName); + + $events = $xpath->query("//*[contains(@id, 'event-card')]"); + foreach ($events as $event) { + try { + if (!$event instanceof \DOMElement) { + throw new \Exception('Élement DOM de type invalide'); + } + + $eventUrl = $event->getAttribute('href'); + + if (preg_match('/\/events\/(\d+)\//', $eventUrl, $matches)) { + $id = (int) $matches[1]; + } else { + throw new Exception(sprintf('Pas d\'id pour cet évent de l\'antenne %s', $antenne->code)); } + + $dateString = $xpath->query(".//time", $event)->item(0)->nodeValue; + $dateTime = (new MeetupDateTimeConverter())->convertStringToDateTime($dateString); + + $title = $xpath->query(".//span[contains(@class, 'cardTitle')]", $event)->item(0)->nodeValue; + + $descriptionElements = $xpath->query("//div[contains(@class, 'utils_cardDescription__alO8K')]"); + + $description = ''; + foreach ($descriptionElements as $descriptionElement) { + $description .= ' ' . $descriptionElement->nodeValue; + } + + $eventsArray[$meetupAntenneName][] = (new Meetup()) + ->setId($id) + ->setDate($dateTime) + ->setTitle($title) + ->setDescription($description) + ->setAntenneName($meetupAntenneName); + } catch (Exception $e) { + throw new Exception('Problème à la construction d\'un évenement', $e->getCode(), $e); } } } @@ -91,7 +92,7 @@ public function getEvents() * * @throws Exception */ - public function getDomContent(string $antenneUrl): \DOMXPath + public function getDomContent(string $antenneUrl): DOMXPath { $url = self::MEETUP_URL . $antenneUrl; $content = file_get_contents($url); @@ -110,40 +111,16 @@ public function getDomContent(string $antenneUrl): \DOMXPath } /** + * @return array * @throws Exception */ public function getAntennesFromOfficesCollection(): array { - $offices = (new OfficesCollection())->getAll(); - if ([] === $offices) { + $antennes = (new AntennesCollection())->getAll(); + if ([] === $antennes) { throw new Exception("The antennes array is invalid or is empty"); } - return $offices; - } - - /** - * @param OfficesCollection $array - * @return string - * @throws InvalidArgumentException - */ - private function getMeetupUrlNameFromAntenneArray($array) - { - return $this->getArrayValueByKey('meetup_urlname', $array); - } - - /** - * @param string $key - * @param array|OfficesCollection $array - * @return mixed - * @throws InvalidArgumentException - */ - public function getArrayValueByKey($key, $array) - { - if (!isset($array[$key])) { - throw new InvalidArgumentException("The '$key' does not exist in the given array."); - } - - return $array[$key]; + return $antennes; } } diff --git a/sources/AppBundle/Indexation/Meetups/Runner.php b/sources/AppBundle/Indexation/Meetups/Runner.php index 3d9340b0f..be342933e 100644 --- a/sources/AppBundle/Indexation/Meetups/Runner.php +++ b/sources/AppBundle/Indexation/Meetups/Runner.php @@ -7,9 +7,9 @@ use AlgoliaSearch\AlgoliaException; use AlgoliaSearch\Client; use AlgoliaSearch\Index; +use AppBundle\Antennes\AntennesCollection; use AppBundle\Event\Model\Meetup; use AppBundle\Event\Model\Repository\MeetupRepository; -use AppBundle\Offices\OfficesCollection; use CCMBenchmark\Ting\Repository\CollectionInterface; class Runner @@ -18,16 +18,13 @@ class Runner protected MeetupRepository $meetupRepository; - protected OfficesCollection $officiesCollection; - protected Transformer $transformer; public function __construct(Client $algoliaClient, MeetupRepository $meetupRepository) { $this->algoliaClient = $algoliaClient; $this->meetupRepository = $meetupRepository; - $this->officiesCollection = new OfficesCollection(); - $this->transformer = new Transformer($this->officiesCollection); + $this->transformer = new Transformer(new AntennesCollection()); } /** diff --git a/sources/AppBundle/Indexation/Meetups/Transformer.php b/sources/AppBundle/Indexation/Meetups/Transformer.php index cd5e0416d..3a9aa0a39 100644 --- a/sources/AppBundle/Indexation/Meetups/Transformer.php +++ b/sources/AppBundle/Indexation/Meetups/Transformer.php @@ -4,19 +4,20 @@ namespace AppBundle\Indexation\Meetups; +use AppBundle\Antennes\Antenne; +use AppBundle\Antennes\AntennesCollection; use AppBundle\Event\Model\Meetup; -use AppBundle\Offices\OfficesCollection; use Exception; class Transformer { const MEETUP_URL = 'https://www.meetup.com/fr-FR/'; - private OfficesCollection $officesCollection; + private AntennesCollection $antennesCollection; - public function __construct(OfficesCollection $officesCollection) + public function __construct(AntennesCollection $antennesCollection) { - $this->officesCollection = $officesCollection; + $this->antennesCollection = $antennesCollection; } /** @@ -27,21 +28,12 @@ public function __construct(OfficesCollection $officesCollection) public function transform(Meetup $meetup): ?array { $codeOffice = $meetup->getAntenneName(); - $office = $this->officesCollection->findByCode($codeOffice); + $antenne = $this->antennesCollection->findByCode($codeOffice); $datetime = $meetup->getDate(); $isUpcoming = new \DateTime() < $datetime; - if (isset($office['meetup_filter'])) { - $matches = []; - if (!preg_match($office['meetup_filter'], $meetup['name'], $matches)) { - return null; - } - - $meetup['name'] = $matches[1]; - } - - $eventUrl = $this->getEventUrl($office, $meetup); + $eventUrl = $this->getEventUrl($antenne, $meetup); $item = [ 'meetup_id' => $meetup->getId(), 'label' => $meetup->getTitle(), @@ -51,23 +43,23 @@ public function transform(Meetup $meetup): ?array 'datetime' => $datetime->format('Y-m-d H:i:s'), 'day_month' => $datetime->format('d M'), 'office' => [ - 'label' => $office['label'], - 'logo_url' => $office['logo_url'], + 'label' => $antenne->label, + 'logo_url' => $antenne->logoUrl, ], 'description' => $meetup->getDescription(), 'is_upcoming' => $isUpcoming, 'custom_sort' => $isUpcoming ? PHP_INT_MAX - $meetup->getDate()->getTimestamp() : $meetup->getDate()->getTimestamp(), ]; - if (isset($office['twitter'])) { - $item['twitter'] = $office['twitter']; + if ($antenne->socials->twitter !== null) { + $item['twitter'] = $antenne->socials->twitter; } return $item; } - public function getEventUrl(array $office, Meetup $meetup): string + private function getEventUrl(Antenne $antenne, Meetup $meetup): string { - return self::MEETUP_URL . $office['meetup_urlname'] . '/events/' . $meetup->getId(); + return self::MEETUP_URL . $antenne->meetup->urlName . '/events/' . $meetup->getId(); } } diff --git a/sources/AppBundle/Offices/OfficeFinder.php b/sources/AppBundle/Offices/OfficeFinder.php index 713420e8d..a785fd75b 100644 --- a/sources/AppBundle/Offices/OfficeFinder.php +++ b/sources/AppBundle/Offices/OfficeFinder.php @@ -4,6 +4,7 @@ namespace AppBundle\Offices; +use AppBundle\Antennes\AntennesCollection; use AppBundle\Association\Model\User; use AppBundle\Event\Model\Invoice; use Geocoder\Exception\NoResult; @@ -15,7 +16,7 @@ class OfficeFinder { public const MAX_DISTANCE_TO_OFFICE = 50000; - private OfficesCollection $officesCollection; + private AntennesCollection $antennesCollection; private Geocoder $geocoder; @@ -24,7 +25,7 @@ class OfficeFinder public function __construct(Geocoder $geocoder) { $this->geocoder = $geocoder; - $this->officesCollection = new OfficesCollection(); + $this->antennesCollection = new AntennesCollection(); } public function findOffice(Invoice $invoice, User $user = null): ?string @@ -119,9 +120,13 @@ protected function locateNearestLocalOffice(Coordinates $coordinates): array { $localOfficesDistance = []; - foreach ($this->officesCollection->getAll() as $office => $localOffice) { - $distance = $this->haversineGreatCircleDistance($coordinates->getLatitude(), $coordinates->getLongitude(), $localOffice['latitude'], $localOffice['longitude']); - $localOfficesDistance[$office] = $distance; + foreach ($this->antennesCollection->getAll() as $code => $antenne) { + $localOfficesDistance[$code] = $this->haversineGreatCircleDistance( + $coordinates->getLatitude(), + $coordinates->getLongitude(), + $antenne->map->firstCity->position->latitude, + $antenne->map->firstCity->position->longitude, + ); } asort($localOfficesDistance); diff --git a/sources/AppBundle/Offices/OfficesCollection.php b/sources/AppBundle/Offices/OfficesCollection.php deleted file mode 100644 index aaf56b238..000000000 --- a/sources/AppBundle/Offices/OfficesCollection.php +++ /dev/null @@ -1,438 +0,0 @@ - [ - 'label' => 'Bordeaux', - 'latitude' => '44.837912', - 'longitude' => '-0.579541', - 'meetup_urlname' => 'bordeaux-php-meetup', - 'meetup_id' => '18197674', - 'logo_url' => '/images/offices/bordeaux.svg', - 'twitter' => 'AFUP_Bordeaux', - 'linkedin' => 'afup-bordeaux', - 'bluesky' => 'bordeaux.afup.org', - 'map' => [ - "legend-first-point-x" => "330", - "legend-first-point-y" => "440", - "legend-second-point-x" => "270", - "legend-second-point-y" => "500", - "legend-third-point-x" => "230", - "legend-third-point-y" => "500", - "legend-attachment" => "right", - "point-latitude" => "44.837912", - "point-longitude" => "-0.579541", - ], - 'departements' => ['33'], - ], - 'limoges' => [ - 'label' => 'Limoges', - 'latitude' => '45.85', - 'longitude' => '1.25', - 'meetup_urlname' => 'afup-limoges-php', - 'meetup_id' => '23162834', - 'logo_url' => '/images/offices/limoges.svg', - 'twitter' => 'AFUP_Limoges', - 'youtube' => 'https://www.youtube.com/channel/UCPYMUpcC3b5zd-hVNGEWHAA', - 'blog_url' => 'http://limoges.afup.org/', - 'linkedin' => 'afup-limoges', - 'map' => [ - "legend-first-point-x" => "410", - "legend-first-point-y" => "380", - "legend-second-point-x" => "320", - "legend-second-point-y" => "380", - "legend-third-point-x" => "230", - "legend-third-point-y" => "430", - "legend-attachment" => "right", - "point-latitude" => "45.85", - "point-longitude" => "1.25", - ], - 'departements' => ['87'], - ], - 'lille' => [ - 'label' => 'Hauts de France', - 'latitude' => '50.637222', - 'longitude' => '3.063333', - 'meetup_urlname' => 'afup-hauts-de-france-php', - 'meetup_id' => '23840677', - 'logo_url' => '/images/offices/hdf.svg', - 'twitter' => 'afup_hdf', - 'youtube' => 'https://www.youtube.com/channel/UCkMGtNcB-VeqMlQ9p2JMIKg', - 'linkedin' => 'afup-hdf', - 'bluesky' => 'hdf.afup.org', - 'map' => [ - "legend-first-point-x" => "490", - "legend-first-point-y" => "55", - "legend-second-point-x" => "530", - "legend-second-point-y" => "30", - "legend-third-point-x" => "605", - "legend-third-point-y" => "20", - "legend-attachment" => "left", - "point-latitude" => "50.637222", - "point-longitude" => "3.063333", - "legend-second-city-first-point-x" => "490", - "legend-second-city-first-point-y" => "55", - "legend-second-city-second-point-x" => "530", - "legend-second-city-second-point-y" => "30", - "legend-second-city-third-point-x" => "460", - "legend-second-city-third-point-y" => "110", - "point-second-city-latitude" => "49.894054", - "point-second-city-longitude" => "2.295847", - ], - 'departements' => ['59', '80'], - ], - 'luxembourg' => [ - 'label' => 'Luxembourg', - 'latitude' => '49.61', - 'longitude' => '6.13333', - 'meetup_urlname' => 'afup-luxembourg-php', - 'meetup_id' => '19631843', - 'logo_url' => '/images/offices/luxembourg.svg', - 'twitter' => 'afup_luxembourg', - 'blog_url' => 'http://luxembourg.afup.org/', - 'map' => [ - "legend-first-point-x" => "630", - "legend-first-point-y" => "130", - "legend-second-point-x" => "660", - "legend-second-point-y" => "140", - "legend-third-point-x" => "717", - "legend-third-point-y" => "140", - "legend-attachment" => "left", - "point-latitude" => "49.61", - "point-longitude" => "6.13333", - ], - 'pays' => ['lux'], - ], - 'lyon' => [ - 'label' => 'Lyon', - 'latitude' => '45.759723', - 'longitude' => '4.842223', - 'meetup_urlname' => 'afup-lyon-php', - 'meetup_id' => '19630036', - 'logo_url' => '/images/offices/lyon.svg', - 'youtube' => 'https://www.youtube.com/channel/UCSHpe_EYwK0ZhitIJPGSjlQ', - 'twitter' => 'AFUP_Lyon', - 'blog_url' => 'http://lyon.afup.org', - 'linkedin' => 'afup-lyon', - 'bluesky' => 'lyon.afup.org', - 'map' => [ - "legend-first-point-x" => "570", - "legend-first-point-y" => "380", - "legend-second-point-x" => "680", - "legend-second-point-y" => "320", - "legend-third-point-x" => "710", - "legend-third-point-y" => "320", - "legend-attachment" => "left", - "point-latitude" => "45.759723", - "point-longitude" => "4.842223", - ], - 'departements' => ['69'], - ], - 'marseille' => [ - 'label' => 'Aix-Marseille', - 'latitude' => '43.296346', - 'longitude' => '5.36988923', - 'meetup_urlname' => 'afup-aix-marseille-php', - 'meetup_id' => '18152912', - 'logo_url' => '/images/offices/marseille.svg', - 'twitter' => 'AFUP_AixMrs', - 'youtube' => 'https://www.youtube.com/channel/UC77cQ1izl155u6Y8daMZYiA', - 'blog_url' => 'http://aix-marseille.afup.org/', - 'map' => [ - "legend-first-point-x" => "600", - "legend-first-point-y" => "540", - "legend-second-point-x" => "600", - "legend-second-point-y" => "600", - "legend-third-point-x" => "600", - "legend-third-point-y" => "600", - "legend-attachment" => "top", - "point-latitude" => "43.296346", - "point-longitude" => "5.36988923", - ], - 'departements' => ['13'], - ], - 'montpellier' => [ - 'label' => 'Montpellier', - 'latitude' => '43.611944', - 'longitude' => '3.877222', - 'meetup_urlname' => 'montpellier-php-meetup', - 'meetup_id' => '18724486', - 'logo_url' => '/images/offices/montpellier.svg', - 'twitter' => 'afup_mtp', - 'youtube' => 'https://www.youtube.com/channel/UCr9f4-DksVhdv45q2245HeQ', - 'bluesky' => 'montpellier.afup.org', - 'linkedin' => 'montpellier-afup', - 'map' => [ - "legend-first-point-x" => "530", - "legend-first-point-y" => "520", - "legend-second-point-x" => "470", - "legend-second-point-y" => "590", - "legend-third-point-x" => "470", - "legend-third-point-y" => "670", - "legend-attachment" => "top", - "point-latitude" => "43.611944", - "point-longitude" => "3.877222", - ], - 'departements' => ['34'], - ], - 'nantes' => [ - 'label' => 'Nantes', - 'latitude' => '47.21806', - 'longitude' => '-1.55278', - 'meetup_urlname' => 'afup-nantes-php', - 'meetup_id' => '23839991', - 'logo_url' => '/images/offices/nantes.svg', - 'twitter' => 'afup_nantes', - 'blog_url' => 'http://nantes.afup.org/', - 'linkedin' => 'afup-nantes', - 'bluesky' => 'nantes.afup.org', - 'map' => [ - "legend-first-point-x" => "285", - "legend-first-point-y" => "290", - "legend-second-point-x" => "180", - "legend-second-point-y" => "290", - "legend-third-point-x" => "180", - "legend-third-point-y" => "290", - "legend-attachment" => "right", - "point-latitude" => "47.21806", - "point-longitude" => "-1.55278", - ], - 'map_use_second_color' => true, - 'departements' => ['44'], - ], - 'paris' => [ - 'label' => 'Paris', - 'latitude' => '48.856578', - 'longitude' => '2.351828', - 'meetup_urlname' => 'afup-paris-php', - 'meetup_id' => '19629965', - 'logo_url' => '/images/offices/paris.svg', - 'twitter' => 'afup_paris', - 'bluesky' => 'paris.afup.org', - 'map' => [ - "legend-first-point-x" => "460", - "legend-first-point-y" => "180", - "legend-second-point-x" => "400", - "legend-second-point-y" => "60", - "legend-third-point-x" => "360", - "legend-third-point-y" => "60", - "legend-attachment" => "right", - "point-latitude" => "48.856578", - "point-longitude" => "2.351828", - ], - 'departements' => ['75', '77', '78', '91', '92', '93', '94', '95'], - ], - 'poitiers' => [ - 'label' => 'Poitiers', - 'latitude' => '46.581945', - 'longitude' => '0.336112', - 'meetup_urlname' => 'afup-poitiers-php', - 'meetup_id' => '23106095', - 'logo_url' => '/images/offices/poitiers.svg', - 'twitter' => 'afup_poitiers', - 'linkedin' => 'afup-poitiers', - 'bluesky' => 'poitiers.afup.org', - 'map' => [ - "legend-first-point-x" => "365", - "legend-first-point-y" => "330", - "legend-second-point-x" => "285", - "legend-second-point-y" => "360", - "legend-third-point-x" => "180", - "legend-third-point-y" => "360", - "legend-attachment" => "right", - "point-latitude" => "46.581945", - "point-longitude" => "0.336112", - ], - 'departements' => ['86'], - ], - 'reims' => [ - 'label' => 'Reims', - 'latitude' => '49.26278', - 'longitude' => '4.03472', - 'meetup_urlname' => 'afup-reims-php', - 'meetup_id' => '23255694', - 'logo_url' => '/images/offices/reims.svg', - 'twitter' => 'afup_reims', - 'youtube' => 'https://www.youtube.com/channel/UCmkMmVqrt7eI7YMZovew_xw', - 'map' => [ - "legend-first-point-x" => "540", - "legend-first-point-y" => "150", - "legend-second-point-x" => "600", - "legend-second-point-y" => "70", - "legend-third-point-x" => "650", - "legend-third-point-y" => "70", - "legend-attachment" => "left", - "point-latitude" => "49.26278", - "point-longitude" => "4.03472", - ], - 'departements' => ['51'], - ], - 'rennes' => [ - 'label' => 'Rennes', - 'latitude' => '48.114722', - 'longitude' => '-1.679444', - 'meetup_urlname' => 'afup-rennes', - 'meetup_id' => '22364687', - 'logo_url' => '/images/offices/rennes.svg', - 'twitter' => 'AFUP_Rennes', - 'blog_url' => 'https://rennes.afup.org/', - 'youtube' => 'https://www.youtube.com/channel/UCv1VGfqKhygjTOZkdVUWfpQ', - 'linkedin' => 'afup-rennes', - 'map' => [ - "legend-first-point-x" => "285", - "legend-first-point-y" => "220", - "legend-second-point-x" => "150", - "legend-second-point-y" => "220", - "legend-third-point-x" => "120", - "legend-third-point-y" => "170", - "legend-attachment" => "bottom", - "point-latitude" => "48.114722", - "point-longitude" => "-1.679444", - ], - 'departements' => ['35'], - ], - 'toulouse' => [ - 'label' => 'Toulouse', - 'latitude' => '43.604482', - 'longitude' => '1.443962', - 'meetup_urlname' => 'aperophp-toulouse', - 'meetup_id' => '19947513', - 'logo_url' => '/images/offices/toulouse.svg', - 'twitter' => 'afup_toulouse', - 'blog_url' => 'http://toulouse.afup.org/', - 'map' => [ - "legend-first-point-x" => "420", - "legend-first-point-y" => "520", - "legend-second-point-x" => "290", - "legend-second-point-y" => "590", - "legend-third-point-x" => "290", - "legend-third-point-y" => "600", - "legend-attachment" => "top", - "point-latitude" => "43.604482", - "point-longitude" => "1.443962", - ], - 'departements' => ['31'], - ], - 'lorraine' => [ - 'label' => 'Lorraine', - 'latitude' => '49.0685', - 'longitude' => '6.6151', - 'logo_url' => '/images/offices/lorraine.svg', - 'twitter' => 'AFUP_Lorraine', - 'youtube' => 'https://www.youtube.com/channel/UC08QRZncvlgWxUbVbmUs42Q', - 'departements' => ['54', '55', '57', '88'], - 'meetup_urlname' => 'afup-lorraine-php', - 'meetup_id' => '26854931', - 'bluesky' => 'lorraine.afup.org', - 'linkedin' => 'afup-lorraine', - 'map' => [ - "legend-first-point-x" => "650", - "legend-first-point-y" => "160", - "legend-second-point-x" => "700", - "legend-second-point-y" => "220", - "legend-third-point-x" => "740", - "legend-third-point-y" => "220", - "legend-attachment" => "left", - "point-latitude" => "49.0685", - "point-longitude" => "6.6151", - ] - ], - 'clermont' => [ - 'label' => 'Clermont', - 'latitude' => '45.786781', - 'longitude' => '3.115074', - 'logo_url' => '/images/offices/empty.svg', - 'hide_on_offices_page' => true, - ], - 'tours' => [ - 'label' => 'Tours', - 'latitude' => '47.380001068115234', - 'longitude' => '0.6899999976158142', - 'logo_url' => '/images/offices/tours.svg', - 'twitter' => 'AFUP_Tours', - 'blog_url' => 'http://tours.afup.org', - 'departements' => ['37'], - 'meetup_urlname' => 'afup-tours-php', - 'meetup_id' => '28638984', - 'youtube' => 'https://www.youtube.com/channel/UCtKhGIofgKM9ecrdZNyn_pA', - 'linkedin' => 'afup-tours', - 'map' => [ - "legend-first-point-x" => "380", - "legend-first-point-y" => "270", - "legend-second-point-x" => "240", - "legend-second-point-y" => "90", - "legend-third-point-x" => "200", - "legend-third-point-y" => "90", - "legend-attachment" => "right", - "point-latitude" => "47.380001068115234", - "point-longitude" => "0.6899999976158142", - ], - ] - ]; - } - - public function findByMeetupId($meetupId) - { - foreach ($this->getAll() as $office) { - if (!isset($office['meetup_id']) || $office['meetup_id'] != $meetupId) { - continue; - } - - return $office; - } - - throw new \InvalidArgumentException('Office nout found'); - } - - public function getAllSortedByLabels(): array - { - $offices = $this->getAll(); - - uasort( - $offices, - fn ($a, $b): int => strcmp($a['label'], $b['label']) - ); - - return array_filter( - $offices, - function ($value): bool { - if (!isset($value['hide_on_offices_page'])) { - return true; - } - - return !$value['hide_on_offices_page']; - } - ); - } - - public function findByCode($code) - { - $all = $this->getAll(); - - if (!isset($all[$code])) { - throw new \InvalidArgumentException('Office not found'); - } - - return $all[$code]; - } - - /** - * @return mixed[] - */ - public function getOrderedLabelsByKey(): array - { - $labels = []; - foreach ($this->getAllSortedByLabels() as $key => $office) { - $labels[$key] = $office['label']; - } - - return $labels; - } -} diff --git a/sources/AppBundle/Twig/OfficesExtension.php b/sources/AppBundle/Twig/OfficesExtension.php index b3e14808f..10f5c2834 100644 --- a/sources/AppBundle/Twig/OfficesExtension.php +++ b/sources/AppBundle/Twig/OfficesExtension.php @@ -4,33 +4,18 @@ namespace AppBundle\Twig; -use AppBundle\Offices\OfficesCollection; +use AppBundle\Antennes\AntennesCollection; +use Twig\Extension\AbstractExtension; +use Twig\TwigFunction; -class OfficesExtension extends \Twig_Extension +class OfficesExtension extends AbstractExtension { - /** - * {@inheritdoc} - */ public function getFunctions() { return [ - new \Twig_SimpleFunction('office_name', function ($code) { - $collection = new OfficesCollection(); - return $collection->findByCode($code)['label']; - }), - new \Twig_SimpleFunction('office_logo', function ($code) { - $collection = new OfficesCollection(); - return $collection->findByCode($code)['logo_url']; - }), - new \Twig_SimpleFunction('office_meetup_urlname', function ($code) { - $collection = new OfficesCollection(); - return $collection->findByCode($code)['meetup_urlname']; - }), + new TwigFunction('office_name', fn ($code) => (new AntennesCollection())->findByCode($code)->label), + new TwigFunction('office_logo', fn ($code) => (new AntennesCollection())->findByCode($code)->logoUrl), + new TwigFunction('office_meetup_urlname', fn ($code) => (new AntennesCollection())->findByCode($code)->meetup->urlName), ]; } - - public function getName(): string - { - return 'offices'; - } } diff --git a/tests/units/AppBundle/Indexation/Meetups/MeetupScrapper.php b/tests/units/AppBundle/Indexation/Meetups/MeetupScrapper.php index 9e99c5f0c..2a88b0135 100644 --- a/tests/units/AppBundle/Indexation/Meetups/MeetupScrapper.php +++ b/tests/units/AppBundle/Indexation/Meetups/MeetupScrapper.php @@ -82,17 +82,6 @@ public function testGetAntennesFromOfficesCollection(): void ->isNotEmpty(); } - public function testGetArrayValueByKey(): void - { - $meetupScraper = new TestedClass(); - $array = ['key' => 'value']; - $result = $meetupScraper->getArrayValueByKey('key', $array); - - $this - ->string($result) - ->isEqualTo('value'); - } - // Provide valid Meetup URLs for testing protected function validMeetupUrlProvider() { diff --git a/tests/units/AppBundle/Indexation/Meetups/Transformer.php b/tests/units/AppBundle/Indexation/Meetups/Transformer.php index 47ce11c14..ff6ab9930 100644 --- a/tests/units/AppBundle/Indexation/Meetups/Transformer.php +++ b/tests/units/AppBundle/Indexation/Meetups/Transformer.php @@ -4,9 +4,9 @@ namespace AppBundle\Indexation\Meetups\tests\units; +use AppBundle\Antennes\AntennesCollection; use AppBundle\Event\Model\Meetup; use AppBundle\Indexation\Meetups\Transformer as TestedClass; -use AppBundle\Offices\OfficesCollection; class Transformer extends \atoum { @@ -28,7 +28,7 @@ public function testTransform(): void ->setDescription($description) ->setAntenneName($meetupAntenneName) ) - ->when($transformer = new TestedClass(new OfficesCollection())) + ->when($transformer = new TestedClass(new AntennesCollection())) ->then ->array($transformer->transform($meetup)) ->isEqualTo([