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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitattributes
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
docs export-ignore
docs export-ignore
development export-ignore
Taskfile export-ignore
28 changes: 28 additions & 0 deletions .github/workflows/workflow.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: Build Docker Image and run Codestyle tests

on:
push:
branches:
- main
pull_request:
branches:
- main

jobs:
build:
runs-on: ubuntu-latest

steps:
- name: Checkout Repository
uses: actions/checkout@v3

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2

- name: Build Docker image
run: |
docker build -f development/Dockerfile -t php-ci .

- name: Run codestyle tests
run: |
docker run --rm php-ci vendor/bin/ecs --config=development/ecs.php
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
vendor
composer.lock
88 changes: 88 additions & 0 deletions Taskfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#!/bin/bash
# =========================================================
# Taskfile gives you a set of quick tasks for your project
# More info: https://github.com/Enrise/Taskfile
# =========================================================

function banner {
echo -e "${BLUE}\n"\
"██╗ ██╗███████╗███████╗██████╗ █████╗ ██████╗ ██████╗ ███████╗███████╗███╗ ███╗███████╗███╗ ██╗████████╗███████╗\n"\
"██║ ██║██╔════╝██╔════╝██╔══██╗██╔══██╗██╔════╝ ██╔══██╗██╔════╝██╔════╝████╗ ████║██╔════╝████╗ ██║╚══██╔══╝██╔════╝\n"\
"██║ ██║███████╗█████╗ ██████╔╝███████║██║ ███╗██████╔╝█████╗ █████╗ ██╔████╔██║█████╗ ██╔██╗ ██║ ██║ ███████╗\n"\
"██║ ██║╚════██║██╔══╝ ██╔══██╗██╔══██║██║ ██║██╔══██╗██╔══╝ ██╔══╝ ██║╚██╔╝██║██╔══╝ ██║╚██╗██║ ██║ ╚════██║\n"\
"╚██████╔╝███████║███████╗██║ ██║██║ ██║╚██████╔╝██║ ██║███████╗███████╗██║ ╚═╝ ██║███████╗██║ ╚████║ ██║ ███████║\n"\
" ╚═════╝ ╚══════╝╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═══╝ ╚═╝ ╚══════╝${RESET}"
}

# =========================================================
## Project
# =========================================================

function task:start { ## Start the project in development mode
title "Run development environment"
dockercompose up -d
}

function task:build { ## Build docker compose file
title "Build docker compose"
dockercompose build
}

function task:shell { ## Shell into PHP container
dockercompose exec php bash
}

# =========================================================
## Tests
# =========================================================
function task:codestyle { ## Run codestyle test
dockercompose-exec vendor/bin/ecs --config=development/ecs.php
}

# =========================================================
## Internal functions
# =========================================================

function dockercompose {
docker compose --file ./development/compose.yaml "$@"
}

function dockercompose-exec {
dockercompose exec php "$@"
}

# =========================================================
## Taskfile
# =========================================================

set -eo pipefail

BLUE=$(printf '\033[36m')
YELLOW=$(printf '\033[33m')
RED=$(printf '\033[31m')
GREEN=$(printf '\033[32m')
RESET=$(printf '\033[0m')

# Define global variables here

function title {
echo -e "\n${BLUE}=>${RESET} $1\n"
}

function task:help { ## Show all available tasks
title "Available tasks"
awk 'BEGIN {FS = " { [#][#][ ]?"} /^([a-zA-Z_-]*:?.*)(\{ )?[#][#][ ]?/ \
{printf "\033[33m%-34s\033[0m %s\n", $1, $2}' $0 |\
sed -E "s/[#]{2,}[ ]*/${RESET}/g" |\
sed -E "s/function task:*/ /g"
echo -e "\n${BLUE}Usage:${RESET} $0 ${YELLOW}<task>${RESET} <args>"
}

banner
if [[ ! "$(declare -F task:${@-help})" ]]; then
title "Task not found"
echo -e "Task ${YELLOW}$1${RESET} doesn't exist."
task:help
exit 1
fi
task:${@-help}
4 changes: 4 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,12 @@
"description": "User agreements made simple",
"type": "symfony-bundle",
"require": {
"php": "^8.1",
"symfony/framework-bundle": "^6.4 || ^7.1"
},
"require-dev": {
"symplify/easy-coding-standard": "^12.5"
},
"license": "MIT",
"autoload": {
"psr-4": {
Expand Down
18 changes: 18 additions & 0 deletions development/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
FROM php:8.2-alpine3.21

COPY --from=composer:2 /usr/bin/composer /usr/local/bin/composer
COPY --chown=php:nginx ./ /www

RUN apk add --no-cache \
bash \
git \
zip \
unzip

WORKDIR /www

RUN set -eux; \
COMPOSER_MEMORY_LIMIT=2G composer install --prefer-dist --no-autoloader --no-scripts --no-progress; \
composer clear-cache

CMD ["sleep", "infinity"]
7 changes: 7 additions & 0 deletions development/compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
services:
php:
build:
context: ../.
dockerfile: development/Dockerfile
volumes:
- ../.:/www
27 changes: 27 additions & 0 deletions development/ecs.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

declare(strict_types=1);

use PhpCsFixer\Fixer\Import\NoUnusedImportsFixer;
use PhpCsFixer\RuleSet\Sets\SymfonySet;
use Symplify\EasyCodingStandard\Config\ECSConfig;

return ECSConfig::configure()
->withPaths([
__DIR__ . '/../src',
])

// add a single rule
->withRules([
NoUnusedImportsFixer::class,
])

// add sets - group of rules
->withPreparedSets(
arrays: true,
namespaces: true,
spaces: true,
docblocks: true,
comments: true,
psr12: true
);
6 changes: 3 additions & 3 deletions src/Entity/Traits/UserAgreementTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

namespace RobertvanLienden\UserAgreements\Entity\Traits;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use RobertvanLienden\UserAgreements\Entity\UserAgreement;

trait UserAgreementTrait
Expand All @@ -24,7 +24,7 @@ public function getUserAgreements(): Collection

public function addUserAgreement(UserAgreement $userAgreement): self
{
if (!$this->userAgreements->contains($userAgreement)) {
if (! $this->userAgreements->contains($userAgreement)) {
$this->userAgreements[] = $userAgreement;
$userAgreement->setUser($this);
}
Expand All @@ -40,4 +40,4 @@ public function removeUserAgreement(UserAgreement $userAgreement): self

return $this;
}
}
}
6 changes: 3 additions & 3 deletions src/Entity/UserAgreement.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
use Symfony\Component\Security\Core\User\UserInterface;

#[ORM\Entity(repositoryClass: UserAgreementRepository::class)]
class UserAgreement {
class UserAgreement
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
Expand All @@ -26,7 +27,6 @@ class UserAgreement {
#[ORM\JoinColumn(name: 'user_id', nullable: true)]
private ?UserInterface $user = null;


public function getId(): ?int
{
return $this->id;
Expand Down Expand Up @@ -77,4 +77,4 @@ public function setUser(?UserInterface $user): self
$this->user = $user;
return $this;
}
}
}
5 changes: 3 additions & 2 deletions src/EventListener/DoctrineMetadataListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@

class DoctrineMetadataListener implements EventSubscriber
{
public function __construct(private string $userEntityClass)
{
public function __construct(
private string $userEntityClass
) {
}

public function getSubscribedEvents()
Expand Down
8 changes: 5 additions & 3 deletions src/Form/AgreementFormType.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,17 @@

use RobertvanLienden\UserAgreements\Service\AgreementService;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;

class AgreementFormType extends AbstractType
{
public function __construct(private AgreementService $agreementService, private UrlGeneratorInterface $urlGenerator)
{
public function __construct(
private AgreementService $agreementService,
private UrlGeneratorInterface $urlGenerator
) {
}

public function buildForm(FormBuilderInterface $builder, array $options)
Expand Down
2 changes: 1 addition & 1 deletion src/Repository/UserAgreementRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@ public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, UserAgreement::class);
}
}
}
18 changes: 11 additions & 7 deletions src/Service/AgreementHandlingService.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,23 @@

class AgreementHandlingService
{
public function __construct(private EntityManagerInterface $entityManager, private AgreementService $agreementService)
{
public function __construct(
private EntityManagerInterface $entityManager,
private AgreementService $agreementService
) {
}

/**
* @throws \InvalidArgumentException
*/
public function handleAgreementsFromFormType(array $agreements, UserInterface $user, bool $flushEntities = false): void
{
if (!in_array(UserAgreementTrait::class, class_uses(get_class($user)))) {
if (! in_array(UserAgreementTrait::class, class_uses(get_class($user)))) {
throw new \InvalidArgumentException(
sprintf('User does not have the %s. This is needed to handle agreements',
UserAgreementTrait::class)
sprintf(
'User does not have the %s. This is needed to handle agreements',
UserAgreementTrait::class
)
);
}

Expand Down Expand Up @@ -51,7 +55,7 @@ private function normalizeAgreementsLabels(array $agreements): array
private function createUserAgreements(array $agreements, UserInterface $user): void
{
foreach ($agreements as $key => $value) {
if (!$value) {
if (! $value) {
continue;
}

Expand All @@ -70,4 +74,4 @@ private function createUserAgreements(array $agreements, UserInterface $user): v
$this->entityManager->persist($agreement);
}
}
}
}
8 changes: 5 additions & 3 deletions src/Service/AgreementService.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@

class AgreementService
{
public function __construct(ContainerBagInterface $containerBag, private array $agreements = [])
{
public function __construct(
ContainerBagInterface $containerBag,
private array $agreements = []
) {
$this->agreements = $containerBag->get('user_agreements')['agreements'];
}

Expand All @@ -22,4 +24,4 @@ public function findAgreement(string $label): ?array

return $this->agreements[$arrayKey] ?? null;
}
}
}
Loading
Loading