Add lat,long to subject

This commit is contained in:
myrmidex 2026-06-05 13:24:19 +00:00
parent c524592485
commit 8ad0280b86
7 changed files with 115 additions and 71 deletions

View file

@ -0,0 +1,33 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20260605123055 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE subject ADD latitude NUMERIC(10, 7) DEFAULT NULL');
$this->addSql('ALTER TABLE subject ADD longitude NUMERIC(10, 7) DEFAULT NULL');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE subject DROP latitude');
$this->addSql('ALTER TABLE subject DROP longitude');
}
}

View file

@ -30,10 +30,20 @@ class SubjectController extends AbstractController
#[CurrentUser]
User $user,
): JsonResponse {
$payload = $request->getPayload();
$subject = new Restaurant();
$subject->setName($request->getPayload()->get('name'));
$subject->setName($payload->get('name'));
$subject->setCreatedBy($user);
if ($payload->has('latitude')) {
$subject->setLatitude($payload->getString('latitude'));
}
if ($payload->has('longitude')) {
$subject->setLongitude($payload->getString('longitude'));
}
$em->persist($subject);
$em->flush();
@ -62,6 +72,14 @@ class SubjectController extends AbstractController
$subject->setName($payload->getString('name'));
}
if ($payload->has('latitude')) {
$subject->setLatitude($payload->getString('latitude'));
}
if ($payload->has('longitude')) {
$subject->setLongitude($payload->getString('longitude'));
}
$em->flush();
return $this->json(null, 202);

View file

@ -6,6 +6,7 @@ use App\Entity\Restaurant;
use App\Repository\SubjectRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity(repositoryClass: SubjectRepository::class)]
@ -26,6 +27,12 @@ abstract class Subject
#[ORM\JoinColumn(nullable: true)]
private ?User $createdBy = null;
#[ORM\Column(type: Types::DECIMAL, precision: 10, scale: 7, nullable: true)]
private ?string $latitude = '15';
#[ORM\Column(type: Types::DECIMAL, precision: 10, scale: 7, nullable: true)]
private ?string $longitude = null;
/**
* @var Collection<int, Rating>
*/
@ -66,6 +73,30 @@ abstract class Subject
return $this;
}
public function getLatitude(): ?string
{
return $this->latitude;
}
public function setLatitude(?string $latitude = null): static
{
$this->latitude = $latitude;
return $this;
}
public function getLongitude(): ?string
{
return $this->longitude;
}
public function setLongitude(?string $longitude = null): static
{
$this->longitude = $longitude;
return $this;
}
/**
* @return Collection<int, Rating>
*/

View file

@ -3,11 +3,7 @@
namespace App\Factory;
use App\Entity\Rating;
use App\Repository\RatingRepository;
use Doctrine\ORM\EntityRepository;
use Zenstruck\Foundry\Persistence\PersistentObjectFactory;
use Zenstruck\Foundry\Persistence\Proxy;
use Zenstruck\Foundry\Persistence\ProxyRepositoryDecorator;
/**
* @extends PersistentObjectFactory<Rating>
@ -36,7 +32,7 @@ final class RatingFactory extends PersistentObjectFactory
protected function defaults(): array|callable
{
return [
'subject' => SubjectFactory::new(),
'subject' => RestaurantFactory::new(),
];
}

View file

@ -1,54 +0,0 @@
<?php
namespace App\Factory;
use App\Entity\Restaurant;
use App\Entity\Subject;
use App\Repository\SubjectRepository;
use Doctrine\ORM\EntityRepository;
use Zenstruck\Foundry\Persistence\PersistentObjectFactory;
use Zenstruck\Foundry\Persistence\Proxy;
use Zenstruck\Foundry\Persistence\ProxyRepositoryDecorator;
/**
* @extends PersistentObjectFactory<Subject>
*/
final class SubjectFactory extends PersistentObjectFactory
{
/**
* @see https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html#factories-as-services
*
* @todo inject services if required
*/
public function __construct() {}
#[\Override]
public static function class(): string
{
return Restaurant::class;
}
/**
* @see https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html#model-factories
*
* @todo add your default values here
*/
#[\Override]
protected function defaults(): array|callable
{
return [
'name' => self::faker()->text(10),
];
}
/**
* @see https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html#initialization
*/
#[\Override]
protected function initialize(): static
{
return $this
// ->afterInstantiate(function(Subject $subject): void {})
;
}
}

View file

@ -7,7 +7,6 @@ use App\Factory\RatingFactory;
use App\Factory\RestaurantFactory;
use App\Factory\UserFactory;
use App\Repository\RatingRepository;
use App\Repository\SubjectRepository;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
@ -24,7 +23,7 @@ class RatingControllerTest extends WebTestCase
'createdBy' => $user,
]);
$ratings = RatingFactory::createMany(5, [
RatingFactory::createMany(5, [
'subject' => $subject,
]);

View file

@ -5,7 +5,6 @@ namespace App\Tests\Application\Controller\Api;
use App\Entity\Restaurant;
use App\Entity\Subject;
use App\Factory\RestaurantFactory;
use App\Factory\SubjectFactory;
use App\Factory\UserFactory;
use App\Repository\SubjectRepository;
use Doctrine\ORM\EntityManagerInterface;
@ -20,7 +19,7 @@ class SubjectControllerTest extends WebTestCase
$user = UserFactory::createOne();
$client->loginUser($user);
SubjectFactory::createMany(5, [
RestaurantFactory::createMany(5, [
'createdBy' => $user,
]);
@ -47,11 +46,20 @@ class SubjectControllerTest extends WebTestCase
$this->assertEmpty($repo->findAll());
$faker = \Zenstruck\Foundry\faker();
$name = $faker->company();
$latitude = $faker->latitude();
$longitude = $faker->longitude();
$client->request(
'POST',
'/api/subjects',
server: ['CONTENT_TYPE' => 'application/json'],
content: json_encode(['name' => 'Riviera']),
content: json_encode([
'name' => $name,
'latitude' => $latitude,
'longitude' => $longitude,
]),
);
$this->assertResponseIsSuccessful();
@ -60,12 +68,13 @@ class SubjectControllerTest extends WebTestCase
$subject = static::getContainer()
->get(SubjectRepository::class)
->findOneBy(['name' => 'Riviera']);
->findOneBy(['name' => $name]);
$this->assertNotNull($subject);
$this->assertInstanceOf(Restaurant::class, $subject);
$this->assertNotNull($subject->getCreatedBy());
$this->assertSame($user->getId(), $subject->getCreatedBy()->getId());
$this->assertEqualsWithDelta((float) $latitude, (float) $subject->getLatitude(), 0.0000001);
$this->assertEqualsWithDelta((float) $longitude, (float) $subject->getLongitude(), 0.0000001);
}
public function testUpdate(): void
@ -75,19 +84,29 @@ class SubjectControllerTest extends WebTestCase
$user = UserFactory::createOne();
$client->loginUser($user);
$nameOld = 'Old name';
$nameNew = 'New name';
$latitudeOld = '15.005';
$latitudeNew = '51.66';
$longitudeOld = '15.040';
$longitudeNew = '51.54';
$subject = RestaurantFactory::createOne([
'name' => 'Old name',
'name' => $nameOld,
'createdBy' => $user,
'latitude' => $latitudeOld,
'longitude' => $longitudeOld,
]);
$name = 'New name';
$client->request(
'PATCH',
'/api/subjects/' . $subject->getId(),
server: ['CONTENT_TYPE' => 'application/json'],
content: json_encode([
'name' => $name,
'name' => $nameNew,
'latitude' => $latitudeNew,
'longitude' => $longitudeNew,
]),
);
@ -98,7 +117,9 @@ class SubjectControllerTest extends WebTestCase
$em->clear();
$updated = $em->getRepository(Subject::class)->find($subject->getId());
$this->assertSame($name, $updated->getName());
$this->assertSame($nameNew, $updated->getName());
$this->assertEqualsWithDelta((float) $latitudeNew, (float) $subject->getLatitude(), 0.0000001);
$this->assertEqualsWithDelta((float) $longitudeNew, (float) $subject->getLongitude(), 0.0000001);
}
public function testDelete(): void