Daniel 2 лет назад
Родитель
Сommit
151bac8c3b
25 измененных файлов: 1531 добавлений и 333 удалений
  1. +6
    -0
      .env
  2. +4
    -1
      .gitignore
  3. +1
    -0
      composer.json
  4. +656
    -266
      composer.lock
  5. +1
    -0
      config/bundles.php
  6. +6
    -0
      config/packages/api_platform.yaml
  7. +5
    -0
      config/packages/lexik_jwt_authentication.yaml
  8. +34
    -18
      config/packages/nelmio_cors.yaml
  9. +9
    -10
      config/packages/security.yaml
  10. +6
    -1
      config/routes.yaml
  11. +0
    -35
      migrations/Version20231214140601.php
  12. +45
    -0
      migrations/Version20231221143009.php
  13. +1
    -1
      src/ApiResource/PostingApi.php
  14. +0
    -1
      src/Controller/SecurityController.php
  15. +28
    -0
      src/Controller/TesController.php
  16. +3
    -0
      src/DataFixtures/AppFixtures.php
  17. +93
    -0
      src/Entity/ApiToken.php
  18. +206
    -0
      src/Entity/Partner.php
  19. +162
    -0
      src/Entity/PartnerContact.php
  20. +15
    -0
      src/Enum/PartnerType.php
  21. +76
    -0
      src/Factory/PartnerFactory.php
  22. +66
    -0
      src/Repository/ApiTokenRepository.php
  23. +48
    -0
      src/Repository/PartnerContactRepository.php
  24. +48
    -0
      src/Repository/PartnerRepository.php
  25. +12
    -0
      symfony.lock

+ 6
- 0
.env Просмотреть файл

@@ -43,3 +43,9 @@ MESSENGER_TRANSPORT_DSN=doctrine://default?auto_setup=0
###> nelmio/cors-bundle ###
CORS_ALLOW_ORIGIN='^https?://(localhost|127\.0\.0\.1)(:[0-9]+)?$'
###< nelmio/cors-bundle ###

###> lexik/jwt-authentication-bundle ###
JWT_SECRET_KEY=%kernel.project_dir%/config/jwt/private.pem
JWT_PUBLIC_KEY=%kernel.project_dir%/config/jwt/public.pem
JWT_PASSPHRASE=dd92770a0c99773cc99cf1bdc4bd425986dacbcde1bc753e9934614aa6f364b6
###< lexik/jwt-authentication-bundle ###

+ 4
- 1
.gitignore Просмотреть файл

@@ -18,4 +18,7 @@
.phpunit.result.cache
/phpunit.xml
###< symfony/phpunit-bridge ###
/.idea
/.idea
###> lexik/jwt-authentication-bundle ###
/config/jwt/*.pem
###< lexik/jwt-authentication-bundle ###

+ 1
- 0
composer.json Просмотреть файл

@@ -11,6 +11,7 @@
"doctrine/doctrine-bundle": "^2.11",
"doctrine/doctrine-migrations-bundle": "^3.3",
"doctrine/orm": "^2.17",
"lexik/jwt-authentication-bundle": "^2.20",
"nelmio/cors-bundle": "^2.4",
"phpdocumentor/reflection-docblock": "^5.3",
"phpstan/phpdoc-parser": "^1.24",


+ 656
- 266
composer.lock
Разница между файлами не показана из-за своего большого размера
Просмотреть файл


+ 1
- 0
config/bundles.php Просмотреть файл

@@ -16,4 +16,5 @@ return [
Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle::class => ['dev' => true, 'test' => true],
Zenstruck\Foundry\ZenstruckFoundryBundle::class => ['dev' => true, 'test' => true],
Symfonycasts\MicroMapper\SymfonycastsMicroMapperBundle::class => ['all' => true],
Lexik\Bundle\JWTAuthenticationBundle\LexikJWTAuthenticationBundle::class => ['all' => true],
];

+ 6
- 0
config/packages/api_platform.yaml Просмотреть файл

@@ -19,3 +19,9 @@ api_platform:
rfc_7807_compliant_errors: true
event_listeners_backward_compatibility_layer: false
keep_legacy_inflector: false

swagger:
api_keys:
JWT:
name: Authorization
type: header

+ 5
- 0
config/packages/lexik_jwt_authentication.yaml Просмотреть файл

@@ -0,0 +1,5 @@
lexik_jwt_authentication:
secret_key: '%env(resolve:JWT_SECRET_KEY)%'
public_key: '%env(resolve:JWT_PUBLIC_KEY)%'
pass_phrase: '%env(JWT_PASSPHRASE)%'
token_ttl: 3600

+ 34
- 18
config/packages/nelmio_cors.yaml Просмотреть файл

@@ -1,19 +1,35 @@
nelmio_cors:
defaults:
origin_regex: true
# allow_origin: ['%env(CORS_ALLOW_ORIGIN)%']
# allow_methods: ['GET', 'OPTIONS', 'POST', 'PUT', 'PATCH', 'DELETE']
# allow_headers: ['Content-Type', 'Authorization']
# expose_headers: ['Link']
expose_headers: ['*']
allow_origin: [ '*' ]
allow_headers: [ '*' ]
allow_methods: ['GET', 'OPTIONS', 'POST', 'PATCH', 'DELETE']
max_age: 3600
paths:
'^/': null
# '^/api/':
# allow_origin: [ '*' ]
# allow_headers: [ '*' ]
# allow_methods: [ '*' ]
# max_age: 3600
defaults:
allow_credentials: true
allow_origin: ['*']
allow_headers: ['*']
allow_methods: ['POST', 'PATCH', 'GET', 'DELETE', 'OPTIONS']
expose_headers: []
max_age: 3600
hosts: []
origin_regex: true
paths:
# Important api settings :
# Access-Control-Request-Method
'^/': ~

#nelmio_cors:
# defaults:
# allow_credentials: true
# origin_regex: false
## allow_origin: ['%env(CORS_ALLOW_ORIGIN)%']
## allow_methods: ['GET', 'OPTIONS', 'POST', 'PUT', 'PATCH', 'DELETE']
## allow_headers: ['Content-Type', 'Authorization']
## expose_headers: ['Link']
# allow_origin: [ '*' ]
# allow_methods: ['*']
## expose_headers: ['*']
# allow_headers: [ '*' ]
# max_age: 3600
# paths:
# '^/': null
## '^/api/':
## allow_origin: [ '*' ]
## allow_headers: [ '*' ]
## allow_methods: [ '*' ]
## max_age: 3600

+ 9
- 10
config/packages/security.yaml Просмотреть файл

@@ -13,19 +13,18 @@ security:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
lazy: true
api:
pattern: ^/api/
stateless: true
provider: app_user_provider
jwt: ~
main:
json_login:
check_path: app_login
username_path: username
check_path: auth # The name in routes.yaml is enough for mapping
username_path: email
password_path: password

# activate different ways to authenticate
# https://symfony.com/doc/current/security.html#the-firewall

# https://symfony.com/doc/current/security/impersonating_user.html
# switch_user: true
success_handler: lexik_jwt_authentication.handler.authentication_success
failure_handler: lexik_jwt_authentication.handler.authentication_failure

# Easy way to control access for large sections of your site
# Note: Only the *first* access control that matches will be used


+ 6
- 1
config/routes.yaml Просмотреть файл

@@ -3,4 +3,9 @@ controllers:
path: ../src/Controller/
namespace: App\Controller
type: attribute
stateless: false
stateless: true

# api/config/routes.yaml
auth:
path: /auth
methods: ['POST']

+ 0
- 35
migrations/Version20231214140601.php Просмотреть файл

@@ -1,35 +0,0 @@
<?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 Version20231214140601 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('CREATE TABLE posting (id INT AUTO_INCREMENT NOT NULL, owner_id INT NOT NULL, message LONGTEXT NOT NULL, created_at DATETIME NOT NULL COMMENT \'(DC2Type:datetime_immutable)\', INDEX IDX_BD275D737E3C61F9 (owner_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB');
$this->addSql('CREATE TABLE `user` (id INT AUTO_INCREMENT NOT NULL, email VARCHAR(180) NOT NULL, first_name VARCHAR(255) NOT NULL, last_name VARCHAR(255) NOT NULL, roles JSON NOT NULL COMMENT \'(DC2Type:json)\', password VARCHAR(255) NOT NULL, active TINYINT(1) NOT NULL, created_at DATETIME NOT NULL COMMENT \'(DC2Type:datetime_immutable)\', UNIQUE INDEX UNIQ_8D93D649E7927C74 (email), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB');
$this->addSql('ALTER TABLE posting ADD CONSTRAINT FK_BD275D737E3C61F9 FOREIGN KEY (owner_id) REFERENCES `user` (id)');
}

public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE posting DROP FOREIGN KEY FK_BD275D737E3C61F9');
$this->addSql('DROP TABLE posting');
$this->addSql('DROP TABLE `user`');
}
}

+ 45
- 0
migrations/Version20231221143009.php Просмотреть файл

@@ -0,0 +1,45 @@
<?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 Version20231221143009 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('CREATE TABLE api_token (id INT AUTO_INCREMENT NOT NULL, owned_by_id INT NOT NULL, expires_at DATETIME DEFAULT NULL COMMENT \'(DC2Type:datetime_immutable)\', token VARCHAR(68) NOT NULL, scopes JSON NOT NULL COMMENT \'(DC2Type:json)\', INDEX IDX_7BA2F5EB5E70BCD7 (owned_by_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB');
$this->addSql('CREATE TABLE partner (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(255) NOT NULL, type VARCHAR(255) NOT NULL, street VARCHAR(255) DEFAULT NULL, street_no VARCHAR(255) DEFAULT NULL, zip VARCHAR(255) DEFAULT NULL, city VARCHAR(255) DEFAULT NULL, country VARCHAR(255) DEFAULT NULL, website VARCHAR(255) DEFAULT NULL, created_at DATETIME NOT NULL COMMENT \'(DC2Type:datetime_immutable)\', logo VARCHAR(255) DEFAULT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB');
$this->addSql('CREATE TABLE partner_contact (id INT AUTO_INCREMENT NOT NULL, partner_id INT NOT NULL, first_name VARCHAR(255) NOT NULL, last_name VARCHAR(255) NOT NULL, birthday DATE DEFAULT NULL, picture VARCHAR(255) DEFAULT NULL, position VARCHAR(255) DEFAULT NULL, phone VARCHAR(255) DEFAULT NULL, email VARCHAR(255) DEFAULT NULL, created_at DATETIME NOT NULL COMMENT \'(DC2Type:datetime_immutable)\', INDEX IDX_8B8885259393F8FE (partner_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB');
$this->addSql('CREATE TABLE posting (id INT AUTO_INCREMENT NOT NULL, owner_id INT NOT NULL, message LONGTEXT NOT NULL, created_at DATETIME NOT NULL COMMENT \'(DC2Type:datetime_immutable)\', INDEX IDX_BD275D737E3C61F9 (owner_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB');
$this->addSql('CREATE TABLE `user` (id INT AUTO_INCREMENT NOT NULL, email VARCHAR(180) NOT NULL, first_name VARCHAR(255) NOT NULL, last_name VARCHAR(255) NOT NULL, roles JSON NOT NULL COMMENT \'(DC2Type:json)\', password VARCHAR(255) NOT NULL, active TINYINT(1) NOT NULL, created_at DATETIME NOT NULL COMMENT \'(DC2Type:datetime_immutable)\', UNIQUE INDEX UNIQ_8D93D649E7927C74 (email), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB');
$this->addSql('ALTER TABLE api_token ADD CONSTRAINT FK_7BA2F5EB5E70BCD7 FOREIGN KEY (owned_by_id) REFERENCES `user` (id)');
$this->addSql('ALTER TABLE partner_contact ADD CONSTRAINT FK_8B8885259393F8FE FOREIGN KEY (partner_id) REFERENCES partner (id)');
$this->addSql('ALTER TABLE posting ADD CONSTRAINT FK_BD275D737E3C61F9 FOREIGN KEY (owner_id) REFERENCES `user` (id)');
}

public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE api_token DROP FOREIGN KEY FK_7BA2F5EB5E70BCD7');
$this->addSql('ALTER TABLE partner_contact DROP FOREIGN KEY FK_8B8885259393F8FE');
$this->addSql('ALTER TABLE posting DROP FOREIGN KEY FK_BD275D737E3C61F9');
$this->addSql('DROP TABLE api_token');
$this->addSql('DROP TABLE partner');
$this->addSql('DROP TABLE partner_contact');
$this->addSql('DROP TABLE posting');
$this->addSql('DROP TABLE `user`');
}
}

+ 1
- 1
src/ApiResource/PostingApi.php Просмотреть файл

@@ -39,7 +39,7 @@ use Symfony\Component\Validator\Constraints\NotBlank;
)
],
paginationItemsPerPage: 10,
// security: 'is_granted("ROLE_USER")',
security: 'is_granted("ROLE_USER")',
provider: EntityToDtoStateProvider::class,
processor: EntityClassDtoStateProcessor::class,
stateOptions: new Options(entityClass: Posting::class),


+ 0
- 1
src/Controller/SecurityController.php Просмотреть файл

@@ -13,7 +13,6 @@ use Symfony\Component\Security\Http\Attribute\CurrentUser;
class SecurityController extends AbstractController
{
#[Route('/login', name: 'app_login', methods: ['POST'])]
#[Api]
public function login(IriConverterInterface $iriConverter, #[CurrentUser] $user = null): Response
{
if (!$user) {


+ 28
- 0
src/Controller/TesController.php Просмотреть файл

@@ -0,0 +1,28 @@
<?php
/**
* @author Daniel Knudsen <d.knudsen@spawntree.de>
* @date 22.12.23
*/


namespace App\Controller;


use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;

class TesController extends AbstractController
{
#[Route('/test')]
#[IsGranted('ROLE_USER')]
public function test() {
return new JsonResponse('jo');
}

#[Route('/foo')]
public function test2() {
return new JsonResponse('nenene');
}
}

+ 3
- 0
src/DataFixtures/AppFixtures.php Просмотреть файл

@@ -2,6 +2,7 @@

namespace App\DataFixtures;

use App\Factory\PartnerFactory;
use App\Factory\PostingFactory;
use App\Factory\UserFactory;
use Doctrine\Bundle\FixturesBundle\Fixture;
@@ -37,5 +38,7 @@ class AppFixtures extends Fixture
'owner' => UserFactory::random()
];
});

//PartnerFactory::createMany(50);
}
}

+ 93
- 0
src/Entity/ApiToken.php Просмотреть файл

@@ -0,0 +1,93 @@
<?php

namespace App\Entity;

use App\Repository\ApiTokenRepository;
use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity(repositoryClass: ApiTokenRepository::class)]
class ApiToken
{
private const PERSONAL_ACCESS_TOKEN_PREFIX = 'spt_';

#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;

#[ORM\ManyToOne(inversedBy: 'apiTokens')]
#[ORM\JoinColumn(nullable: false)]
private ?User $ownedBy = null;

#[ORM\Column(nullable: true)]
private ?\DateTimeImmutable $expiresAt = null;

#[ORM\Column(length: 68)]
private string $token;

#[ORM\Column]
private array $scopes = [];

public function __construct(string $tokenType = self::PERSONAL_ACCESS_TOKEN_PREFIX)
{
$this->token = $tokenType.bin2hex(random_bytes(32));
}

public function getId(): ?int
{
return $this->id;
}

public function getOwnedBy(): ?User
{
return $this->ownedBy;
}

public function setOwnedBy(?User $ownedBy): self
{
$this->ownedBy = $ownedBy;

return $this;
}

public function getExpiresAt(): ?\DateTimeImmutable
{
return $this->expiresAt;
}

public function setExpiresAt(?\DateTimeImmutable $expiresAt): self
{
$this->expiresAt = $expiresAt;

return $this;
}

public function getToken(): ?string
{
return $this->token;
}

public function setToken(string $token): self
{
$this->token = $token;

return $this;
}

public function getScopes(): array
{
return $this->scopes;
}

public function setScopes(array $scopes): self
{
$this->scopes = $scopes;

return $this;
}

public function isValid(): bool
{
return $this->expiresAt === null || $this->expiresAt > new \DateTimeImmutable();
}
}

+ 206
- 0
src/Entity/Partner.php Просмотреть файл

@@ -0,0 +1,206 @@
<?php

namespace App\Entity;

use App\Enum\PartnerType;
use App\Repository\PartnerRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity(repositoryClass: PartnerRepository::class)]
class Partner
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;

#[ORM\Column(length: 255)]
private ?string $name = null;

#[ORM\Column(type: 'string', enumType: PartnerType::class)]
private ?string $type = null;

#[ORM\Column(length: 255, nullable: true)]
private ?string $street = null;

#[ORM\Column(length: 255, nullable: true)]
private ?string $streetNo = null;

#[ORM\Column(length: 255, nullable: true)]
private ?string $zip = null;

#[ORM\Column(length: 255, nullable: true)]
private ?string $city = null;

#[ORM\Column(length: 255, nullable: true)]
private ?string $country = null;

#[ORM\Column(length: 255, nullable: true)]
private ?string $website = null;

#[ORM\Column]
private ?\DateTimeImmutable $createdAt = null;

#[ORM\OneToMany(mappedBy: 'partner', targetEntity: PartnerContact::class, orphanRemoval: true)]
private Collection $partnerContacts;

#[ORM\Column(length: 255, nullable: true)]
private ?string $logo = null;

public function __construct()
{
$this->createdAt = new \DateTimeImmutable();
$this->partnerContacts = new ArrayCollection();
}

public function getId(): ?int
{
return $this->id;
}

public function getName(): ?string
{
return $this->name;
}

public function setName(string $name): static
{
$this->name = $name;

return $this;
}

public function getType(): ?string
{
return $this->type;
}

public function setType(string $type): static
{
$this->type = $type;

return $this;
}

public function getStreet(): ?string
{
return $this->street;
}

public function setStreet(?string $street): static
{
$this->street = $street;

return $this;
}

public function getStreetNo(): ?string
{
return $this->streetNo;
}

public function setStreetNo(?string $streetNo): static
{
$this->streetNo = $streetNo;

return $this;
}

public function getZip(): ?string
{
return $this->zip;
}

public function setZip(?string $zip): static
{
$this->zip = $zip;

return $this;
}

public function getCity(): ?string
{
return $this->city;
}

public function setCity(?string $city): static
{
$this->city = $city;

return $this;
}

public function getCountry(): ?string
{
return $this->country;
}

public function setCountry(?string $country): static
{
$this->country = $country;

return $this;
}

public function getWebsite(): ?string
{
return $this->website;
}

public function setWebsite(?string $website): static
{
$this->website = $website;

return $this;
}

public function getCreatedAt(): ?\DateTimeImmutable
{
return $this->createdAt;
}

/**
* @return Collection<int, PartnerContact>
*/
public function getPartnerContacts(): Collection
{
return $this->partnerContacts;
}

public function addPartnerContact(PartnerContact $partnerContact): static
{
if (!$this->partnerContacts->contains($partnerContact)) {
$this->partnerContacts->add($partnerContact);
$partnerContact->setPartner($this);
}

return $this;
}

public function removePartnerContact(PartnerContact $partnerContact): static
{
if ($this->partnerContacts->removeElement($partnerContact)) {
// set the owning side to null (unless already changed)
if ($partnerContact->getPartner() === $this) {
$partnerContact->setPartner(null);
}
}

return $this;
}

public function getLogo(): ?string
{
return $this->logo;
}

public function setLogo(?string $logo): static
{
$this->logo = $logo;

return $this;
}

}

+ 162
- 0
src/Entity/PartnerContact.php Просмотреть файл

@@ -0,0 +1,162 @@
<?php

namespace App\Entity;

use App\Repository\PartnerContactRepository;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity(repositoryClass: PartnerContactRepository::class)]
class PartnerContact
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;

#[ORM\Column(length: 255)]
private ?string $firstName = null;

#[ORM\Column(length: 255)]
private ?string $lastName = null;

#[ORM\ManyToOne(inversedBy: 'partnerContacts')]
#[ORM\JoinColumn(nullable: false)]
private ?Partner $partner = null;

#[ORM\Column(type: Types::DATE_MUTABLE, nullable: true)]
private ?\DateTimeInterface $birthday = null;

#[ORM\Column(length: 255, nullable: true)]
private ?string $picture = null;

#[ORM\Column(length: 255, nullable: true)]
private ?string $position = null;

#[ORM\Column(length: 255, nullable: true)]
private ?string $phone = null;

#[ORM\Column(length: 255, nullable: true)]
private ?string $email = null;

#[ORM\Column]
private ?\DateTimeImmutable $createdAt = null;

public function __construct()
{
$this->createdAt = new \DateTimeImmutable();
}

public function getId(): ?int
{
return $this->id;
}

public function getFirstName(): ?string
{
return $this->firstName;
}

public function setFirstName(string $firstName): static
{
$this->firstName = $firstName;

return $this;
}

public function getLastName(): ?string
{
return $this->lastName;
}

public function setLastName(string $lastName): static
{
$this->lastName = $lastName;

return $this;
}

public function getPartner(): ?Partner
{
return $this->partner;
}

public function setPartner(?Partner $partner): static
{
$this->partner = $partner;

return $this;
}

public function getBirthday(): ?\DateTimeInterface
{
return $this->birthday;
}

public function setBirthday(?\DateTimeInterface $birthday): static
{
$this->birthday = $birthday;

return $this;
}

public function getPicture(): ?string
{
return $this->picture;
}

public function setPicture(?string $picture): static
{
$this->picture = $picture;

return $this;
}

public function getPosition(): ?string
{
return $this->position;
}

public function setPosition(?string $position): static
{
$this->position = $position;

return $this;
}

public function getPhone(): ?string
{
return $this->phone;
}

public function setPhone(?string $phone): static
{
$this->phone = $phone;

return $this;
}

public function getEmail(): ?string
{
return $this->email;
}

public function setEmail(?string $email): static
{
$this->email = $email;

return $this;
}

public function getCreatedAt(): ?\DateTimeImmutable
{
return $this->createdAt;
}

public function setCreatedAt(\DateTimeImmutable $createdAt): static
{
$this->createdAt = $createdAt;

return $this;
}
}

+ 15
- 0
src/Enum/PartnerType.php Просмотреть файл

@@ -0,0 +1,15 @@
<?php
/**
* @author Daniel Knudsen <d.knudsen@spawntree.de>
* @date 20.12.23
*/


namespace App\Enum;


enum PartnerType: string {
case Customer = 'customer';
case Supplier = 'supplier';
case Service = 'service';
}

+ 76
- 0
src/Factory/PartnerFactory.php Просмотреть файл

@@ -0,0 +1,76 @@
<?php

namespace App\Factory;

use App\Entity\Partner;
use App\Enum\PartnerType;
use App\Repository\PartnerRepository;
use Zenstruck\Foundry\ModelFactory;
use Zenstruck\Foundry\Proxy;
use Zenstruck\Foundry\RepositoryProxy;

/**
* @extends ModelFactory<Partner>
*
* @method Partner|Proxy create(array|callable $attributes = [])
* @method static Partner|Proxy createOne(array $attributes = [])
* @method static Partner|Proxy find(object|array|mixed $criteria)
* @method static Partner|Proxy findOrCreate(array $attributes)
* @method static Partner|Proxy first(string $sortedField = 'id')
* @method static Partner|Proxy last(string $sortedField = 'id')
* @method static Partner|Proxy random(array $attributes = [])
* @method static Partner|Proxy randomOrCreate(array $attributes = [])
* @method static PartnerRepository|RepositoryProxy repository()
* @method static Partner[]|Proxy[] all()
* @method static Partner[]|Proxy[] createMany(int $number, array|callable $attributes = [])
* @method static Partner[]|Proxy[] createSequence(iterable|callable $sequence)
* @method static Partner[]|Proxy[] findBy(array $attributes)
* @method static Partner[]|Proxy[] randomRange(int $min, int $max, array $attributes = [])
* @method static Partner[]|Proxy[] randomSet(int $number, array $attributes = [])
*/
final class PartnerFactory extends ModelFactory
{
/**
* @see https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html#factories-as-services
*
* @todo inject services if required
*/
public function __construct()
{
parent::__construct();
}

/**
* @see https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html#model-factories
*
* @todo add your default values here
*/
protected function getDefaults(): array
{
return [
'name' => self::faker()->text(255),
'type' => self::faker()->randomElement(PartnerType::cases()),
'street' => self::faker()->text(255),
'streetNo' => self::faker()->text(255),
'zip' => self::faker()->text(255),
'city' => self::faker()->text(255),
'country' => self::faker()->text(255),
'website' => self::faker()->text(255),
];
}

/**
* @see https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html#initialization
*/
protected function initialize(): self
{
return $this
// ->afterInstantiate(function(Partner $partner): void {})
;
}

protected static function getClass(): string
{
return Partner::class;
}
}

+ 66
- 0
src/Repository/ApiTokenRepository.php Просмотреть файл

@@ -0,0 +1,66 @@
<?php

namespace App\Repository;

use App\Entity\ApiToken;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;

/**
* @extends ServiceEntityRepository<ApiToken>
*
* @method ApiToken|null find($id, $lockMode = null, $lockVersion = null)
* @method ApiToken|null findOneBy(array $criteria, array $orderBy = null)
* @method ApiToken[] findAll()
* @method ApiToken[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
class ApiTokenRepository extends ServiceEntityRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, ApiToken::class);
}

public function save(ApiToken $entity, bool $flush = false): void
{
$this->getEntityManager()->persist($entity);

if ($flush) {
$this->getEntityManager()->flush();
}
}

public function remove(ApiToken $entity, bool $flush = false): void
{
$this->getEntityManager()->remove($entity);

if ($flush) {
$this->getEntityManager()->flush();
}
}

// /**
// * @return ApiToken[] Returns an array of ApiToken objects
// */
// public function findByExampleField($value): array
// {
// return $this->createQueryBuilder('a')
// ->andWhere('a.exampleField = :val')
// ->setParameter('val', $value)
// ->orderBy('a.id', 'ASC')
// ->setMaxResults(10)
// ->getQuery()
// ->getResult()
// ;
// }

// public function findOneBySomeField($value): ?ApiToken
// {
// return $this->createQueryBuilder('a')
// ->andWhere('a.exampleField = :val')
// ->setParameter('val', $value)
// ->getQuery()
// ->getOneOrNullResult()
// ;
// }
}

+ 48
- 0
src/Repository/PartnerContactRepository.php Просмотреть файл

@@ -0,0 +1,48 @@
<?php

namespace App\Repository;

use App\Entity\PartnerContact;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;

/**
* @extends ServiceEntityRepository<PartnerContact>
*
* @method PartnerContact|null find($id, $lockMode = null, $lockVersion = null)
* @method PartnerContact|null findOneBy(array $criteria, array $orderBy = null)
* @method PartnerContact[] findAll()
* @method PartnerContact[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
class PartnerContactRepository extends ServiceEntityRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, PartnerContact::class);
}

// /**
// * @return PartnerContact[] Returns an array of PartnerContact objects
// */
// public function findByExampleField($value): array
// {
// return $this->createQueryBuilder('p')
// ->andWhere('p.exampleField = :val')
// ->setParameter('val', $value)
// ->orderBy('p.id', 'ASC')
// ->setMaxResults(10)
// ->getQuery()
// ->getResult()
// ;
// }

// public function findOneBySomeField($value): ?PartnerContact
// {
// return $this->createQueryBuilder('p')
// ->andWhere('p.exampleField = :val')
// ->setParameter('val', $value)
// ->getQuery()
// ->getOneOrNullResult()
// ;
// }
}

+ 48
- 0
src/Repository/PartnerRepository.php Просмотреть файл

@@ -0,0 +1,48 @@
<?php

namespace App\Repository;

use App\Entity\Partner;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;

/**
* @extends ServiceEntityRepository<Partner>
*
* @method Partner|null find($id, $lockMode = null, $lockVersion = null)
* @method Partner|null findOneBy(array $criteria, array $orderBy = null)
* @method Partner[] findAll()
* @method Partner[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
class PartnerRepository extends ServiceEntityRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, Partner::class);
}

// /**
// * @return Partner[] Returns an array of Partner objects
// */
// public function findByExampleField($value): array
// {
// return $this->createQueryBuilder('p')
// ->andWhere('p.exampleField = :val')
// ->setParameter('val', $value)
// ->orderBy('p.id', 'ASC')
// ->setMaxResults(10)
// ->getQuery()
// ->getResult()
// ;
// }

// public function findOneBySomeField($value): ?Partner
// {
// return $this->createQueryBuilder('p')
// ->andWhere('p.exampleField = :val')
// ->setParameter('val', $value)
// ->getQuery()
// ->getOneOrNullResult()
// ;
// }
}

+ 12
- 0
symfony.lock Просмотреть файл

@@ -52,6 +52,18 @@
"migrations/.gitignore"
]
},
"lexik/jwt-authentication-bundle": {
"version": "2.20",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "main",
"version": "2.5",
"ref": "e9481b233a11ef7e15fe055a2b21fd3ac1aa2bb7"
},
"files": [
"config/packages/lexik_jwt_authentication.yaml"
]
},
"nelmio/cors-bundle": {
"version": "2.4",
"recipe": {


Загрузка…
Отмена
Сохранить