diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index e018841f..6f3fa74f 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -27,12 +27,12 @@ jobs: runs-on: ubuntu-latest steps: - - name: Install qemu dependency - run: | - sudo apt-get update - sudo apt-get install -y qemu-user-static + #- name: Install qemu dependency + # run: | + # sudo apt-get update + # sudo apt-get install -y qemu-user-static - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Build Container Image id: build-image @@ -41,7 +41,7 @@ jobs: layers: true oci: true image: php-ubi - archs: amd64, arm64 + archs: amd64 build-args: | GIT_HASH=${{ github.sha }} tags: ${{ inputs.envName}}-${{ github.sha }} latest @@ -64,12 +64,12 @@ jobs: runs-on: ubuntu-latest steps: - - name: Install qemu dependency - run: | - sudo apt-get update - sudo apt-get install -y qemu-user-static + #- name: Install qemu dependency + # run: | + # sudo apt-get update + # sudo apt-get install -y qemu-user-static - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Build Container Image id: build-image @@ -78,7 +78,7 @@ jobs: layers: true oci: true image: caddy-ubi - archs: amd64, arm64 + archs: amd64 tags: ${{ inputs.envName}}-${{ github.sha }} latest containerfiles: | ./deploy/container_images/caddy/Containerfile-ubi diff --git a/.github/workflows/deploy.yaml b/.github/workflows/deploy.yaml index d071f073..b5c3b269 100644 --- a/.github/workflows/deploy.yaml +++ b/.github/workflows/deploy.yaml @@ -44,13 +44,13 @@ jobs: steps: - name: split url - uses: bhowell2/github-substring-action@1.0.2 + uses: bhowell2/github-substring-action@v1 id: url with: value: ${{ inputs.envUrl }} index_of_str: 'https://' - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: 'Deploy' uses: 'vimeda/helm@v1.7.0' diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 370d51a0..ed9f5bc1 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -12,7 +12,7 @@ jobs: container: docker.io/composer/composer:2 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Validate composer.json and composer.lock id: composer-validation @@ -22,7 +22,7 @@ jobs: - name: Cache Composer packages id: composer-cache - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: vendor key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }} @@ -39,7 +39,7 @@ jobs: run: tar -czpf /tmp/workdir.tgz . - name: Upload workdir tarball - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: workdir path: /tmp/workdir.tgz @@ -53,7 +53,7 @@ jobs: steps: - name: Download workdir tarball - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: workdir path: . @@ -76,7 +76,7 @@ jobs: steps: - name: Download workdir tarball - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: workdir path: . @@ -112,7 +112,7 @@ jobs: # steps: # # - name: Download workdir tarball -# uses: actions/download-artifact@v3 +# uses: actions/download-artifact@v4 # with: # name: workdir # path: . diff --git a/deploy/container_images/caddy/Containerfile-ubi b/deploy/container_images/caddy/Containerfile-ubi index 049fc3a3..44b29d8a 100644 --- a/deploy/container_images/caddy/Containerfile-ubi +++ b/deploy/container_images/caddy/Containerfile-ubi @@ -1,20 +1,20 @@ -FROM registry.access.redhat.com/ubi9/ubi:latest - -LABEL maintainer "Michael Kaplan " +FROM quay.io/centos/centos:stream9 +LABEL maintainers="Kissj devs " WORKDIR /var/www/html +RUN dnf install 'dnf-command(copr)' -y RUN dnf copr enable @caddy/caddy epel-9-$(arch) -y RUN dnf install caddy -y +#cleanup dnf cache +RUN dnf clean all + #Caddy Config COPY ./deploy/container_images/caddy/Caddyfile /etc/caddy/Caddyfile # Copy public folder which is needed for routing and static files COPY ./public /var/www/html/public -#Create dummy .env -RUN touch /var/www/html/.env - RUN chown -R caddy:caddy /var/www/html diff --git a/deploy/container_images/php/10-opcache.ini b/deploy/container_images/php/10-opcache.ini new file mode 100644 index 00000000..cf330031 --- /dev/null +++ b/deploy/container_images/php/10-opcache.ini @@ -0,0 +1,29 @@ +; load the opcache extension +zend_extension=opcache +; Enable OPCache +opcache.enable=1 + +; Allocate 256MB of memory for OPCache +opcache.memory_consumption=256 + +; Cache up to 10,000 PHP files +opcache.max_accelerated_files=10000 + +; Disable file timestamp validation (may need manual cache clearing) +opcache.validate_timestamps=0 + +; Check file timestamps every 0 seconds +opcache.revalidate_freq=0 + +; Perform a fast shutdown sequence +opcache.fast_shutdown=1 + +; Enable OPCache for PHP command-line scripts +opcache.enable_cli=0 + +; Specify a file-based cache directory for OPCache +opcache.file_cache=/tmp/opcache + +; Enable OPCache optimization for PHP 8 +opcache.jit_buffer_size=100M +opcache.jit=tracing \ No newline at end of file diff --git a/deploy/container_images/php/Containerfile-ubi b/deploy/container_images/php/Containerfile-ubi index 5ab276ad..3b584129 100644 --- a/deploy/container_images/php/Containerfile-ubi +++ b/deploy/container_images/php/Containerfile-ubi @@ -1,5 +1,5 @@ -FROM registry.access.redhat.com/ubi9/ubi:latest -LABEL maintainers "Kissj devs " +FROM quay.io/centos/centos:stream9 +LABEL maintainers="Kissj devs " ARG GIT_HASH ENV GIT_HASH=${GIT_HASH} LABEL GIT_HASH=${GIT_HASH} @@ -8,10 +8,10 @@ WORKDIR /var/www/html #enable needed epel & remi repos RUN dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm https://rpms.remirepo.net/enterprise/remi-release-9.rpm -y - +RUN /usr/bin/crb enable #enable php83 module and install php RUN dnf module enable php:remi-8.3 -y -RUN dnf install php-fpm php-cli composer php-pgsql php-pdo php-gd php-soap php-redis unzip vim -y --nobest +RUN dnf install php-fpm php-cli composer php-pgsql php-pdo php-gd php-soap php-redis php-opcache unzip vim git -y #cleanup dnf cache RUN dnf clean all @@ -26,17 +26,15 @@ COPY ./public /var/www/html/public COPY ./deploy/container_images/php/php.ini /etc/php.ini COPY ./deploy/container_images/php/php-fpm.conf /etc/php-fpm.conf COPY ./deploy/container_images/php/www.conf /etc/php-fpm.d/www.conf +COPY ./deploy/container_images/php/10-opcache.ini /etc/php.d/10-opcache.ini #add user RUN groupadd -g 1001 www-data RUN useradd -u 1001 -g 1001 www-data -s /sbin/nologin -d /var/www/html -M RUN chown -R www-data:www-data /var/lib/php -#Create dummy .env -RUN touch /var/www/html/.env - #install deps -RUN composer install --working-dir=/var/www/html --no-dev --no-interaction --ignore-platform-req=ext-sqlite3 +RUN COMPOSER_ALLOW_SUPERUSER=1 composer install --working-dir=/var/www/html --no-dev --no-interaction --ignore-platform-req=ext-sqlite3 --optimize-autoloader RUN chown -R www-data:www-data /var/www/html diff --git a/deploy/container_images/php/php.ini b/deploy/container_images/php/php.ini index 564a7e35..5e14c5c9 100644 --- a/deploy/container_images/php/php.ini +++ b/deploy/container_images/php/php.ini @@ -432,7 +432,7 @@ max_input_time = 60 ; Maximum amount of memory a script may consume ; https://php.net/memory-limit -memory_limit = 256M +memory_limit = 64M ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Error handling and logging ; diff --git a/deploy/container_images/php/www.conf b/deploy/container_images/php/www.conf index e510d065..81dab3bd 100644 --- a/deploy/container_images/php/www.conf +++ b/deploy/container_images/php/www.conf @@ -100,7 +100,7 @@ listen.acl_users = apache,nginx ; pm.process_idle_timeout - The number of seconds after which ; an idle process will be killed. ; Note: This value is mandatory. -pm = static +pm = dynamic ;experimenting with static processes, if it's not great, change it back ; The number of child processes to be created when pm is set to 'static' and the @@ -112,22 +112,22 @@ pm = static ; forget to tweak pm.* to fit your needs. ; Note: Used when pm is set to 'static', 'dynamic' or 'ondemand' ; Note: This value is mandatory. -pm.max_children = 600 +pm.max_children = 100 ; The number of child processes created on startup. ; Note: Used only when pm is set to 'dynamic' ; Default Value: min_spare_servers + (max_spare_servers - min_spare_servers) / 2 -pm.start_servers = 5 +pm.start_servers = 40 ; The desired minimum number of idle server processes. ; Note: Used only when pm is set to 'dynamic' ; Note: Mandatory when pm is set to 'dynamic' -pm.min_spare_servers = 5 +pm.min_spare_servers = 20 ; The desired maximum number of idle server processes. ; Note: Used only when pm is set to 'dynamic' ; Note: Mandatory when pm is set to 'dynamic' -pm.max_spare_servers = 35 +pm.max_spare_servers = 60 ; The number of seconds after which an idle process will be killed. ; Note: Used only when pm is set to 'ondemand' @@ -138,7 +138,7 @@ pm.max_spare_servers = 35 ; This can be useful to work around memory leaks in 3rd party libraries. For ; endless request processing specify '0'. Equivalent to PHP_FCGI_MAX_REQUESTS. ; Default Value: 0 -pm.max_requests = 300 +pm.max_requests = 500 ; The URI to view the FPM status page. If this value is not set, no URI will be ; recognized as a status page. It shows the following informations: @@ -422,7 +422,7 @@ clear_env = no ;php_admin_value[sendmail_path] = /usr/sbin/sendmail -t -i -f www@my.domain.com ;php_flag[display_errors] = off php_admin_flag[log_errors] = on -php_admin_value[memory_limit] = 256M +php_admin_value[memory_limit] = 64M ; Set the following data paths to directories owned by the FPM process user. ; diff --git a/deploy/helm/charts/kissj/templates/php-fpm.yaml b/deploy/helm/charts/kissj/templates/php-fpm.yaml index ae27e2c0..c9ebc822 100644 --- a/deploy/helm/charts/kissj/templates/php-fpm.yaml +++ b/deploy/helm/charts/kissj/templates/php-fpm.yaml @@ -62,10 +62,10 @@ spec: protocol: TCP resources: requests: - memory: "1Gi" + memory: "500Mi" cpu: "500m" limits: - memory: "2Gi" + memory: "1Gi" cpu: "1000m" env: diff --git a/src/Event/EventType/Obrok/EventTypeObrok.php b/src/Event/EventType/Obrok/EventTypeObrok.php index 069867a6..bb5a9cb8 100755 --- a/src/Event/EventType/Obrok/EventTypeObrok.php +++ b/src/Event/EventType/Obrok/EventTypeObrok.php @@ -89,7 +89,6 @@ public function getContentArbiterGuest(): ContentArbiterGuest $ca->languages = true; return $ca; - } /** diff --git a/src/Import/ImportSrs.php b/src/Import/ImportSrs.php index e4d0854a..89555152 100644 --- a/src/Import/ImportSrs.php +++ b/src/Import/ImportSrs.php @@ -128,7 +128,6 @@ private function mapDataIntoNewIst(array $data, Event $event, ?User $existingUse $contingent = EventTypeObrok::CONTINGENT_ORG; } - $skautisUserId = $data['skautis_user_id']; if (is_numeric($skautisUserId) === false) { $this->flashMessages->warning('flash.warning.importSrs.skautisUserIdNotNumeric'); @@ -148,19 +147,19 @@ private function mapDataIntoNewIst(array $data, Event $event, ?User $existingUse 'Ano' => true, default => false, }; + $participant = null; - if ($existingUser == null) { + if ($existingUser === null) { $existingUser = $this->userService->createSkautisUser( $event, (int)$skautisUserId, $email, $userStatus, ); - } else { $participant = $this->participantRepository->findParticipantFromUser($existingUser); - } + return $this->istService->createIstPayment( $existingUser, $event, diff --git a/src/Participant/Ist/IstService.php b/src/Participant/Ist/IstService.php index e752aab2..e368b4dc 100644 --- a/src/Participant/Ist/IstService.php +++ b/src/Participant/Ist/IstService.php @@ -58,11 +58,11 @@ public function createIstPayment( string $swift, DateTimeImmutable $due, ): Participant { - if ($participant == null) { + if ($participant === null) { $participant = new Participant(); } $participant->user = $user; - $participant->role = ParticipantRole::Ist; + $participant->role = ParticipantRole::Ist; // TODO fix case with TL/PL having troop participants/patrol patrol participants $participant->contingent = $contingent; $participant->firstName = $firstName; $participant->lastName = $lastName; diff --git a/src/Participant/ParticipantRepository.php b/src/Participant/ParticipantRepository.php index 5e8b4359..99eeea02 100755 --- a/src/Participant/ParticipantRepository.php +++ b/src/Participant/ParticipantRepository.php @@ -44,6 +44,7 @@ public function getAllParticipantsWithStatus( $qb->join('user')->as('u')->on('u.id = participant.user_id'); $qb->where('participant.role IN %in', $roles); + $qb->where('u.role = %s', UserRole::Participant); $qb->where('u.status IN %in', $statuses); $qb->where('u.event_id = %i', $event->id); @@ -102,6 +103,7 @@ public function getParticipantsCount( $qb->join('user')->as('u')->on('u.id = participant.user_id'); $qb->where('participant.role IN %in', $roles); + $qb->where('u.role = %s', UserRole::Participant); $qb->where('u.status IN %in', $statuses); $qb->where('u.event_id = %i', $event->id); @@ -208,6 +210,7 @@ public function getParticipantsForEntry(Event $event): array $qb->join('user')->as('u')->on('u.id = participant.user_id'); $qb->leftJoin('deal')->as('d')->on('participant.id = d.participant_id')->and('d.slug = %s', 'sfh'); + $qb->where('u.role = %s', UserRole::Participant); $qb->where('u.status = %s', UserStatus::Paid); $qb->where('u.event_id = %i', $event->id); @@ -274,9 +277,10 @@ public function getIstArrivalStatistic( $qb = $this->connection->select('date(participant.arrival_date) as ad, COUNT(*)')->from($this->getTable()); $qb->join('user')->as('u')->on('u.id = participant.user_id'); - $qb->where('u.event_id = %i', $event->id); $qb->where('participant.role = %s', ParticipantRole::Ist); + $qb->where('u.role = %s', UserRole::Participant); $qb->where('u.status = %s', UserStatus::Paid); + $qb->where('u.event_id = %i', $event->id); $qb->groupBy('date(participant.arrival_date)'); $qb->orderBy('date(participant.arrival_date)'); @@ -296,8 +300,9 @@ public function getFoodStatistic( $qb = $this->connection->select('participant.food_preferences as f, COUNT(*)')->from($this->getTable()); $qb->join('user')->as('u')->on('u.id = participant.user_id'); - $qb->where('u.event_id = %i', $event->id); + $qb->where('u.role = %s', UserRole::Participant); $qb->where('u.status = %s', UserStatus::Paid); + $qb->where('u.event_id = %i', $event->id); $qb->groupBy('participant.food_preferences'); $qb->orderBy('participant.food_preferences'); @@ -322,6 +327,7 @@ public function getStatistic( $qb->where('participant.contingent = %s', $contingent); } + $qb->where('u.role = %s', UserRole::Participant); $qb->groupBy('u.status'); $rows = $qb->fetchPairs('status', 'count'); diff --git a/src/Settings/Settings.php b/src/Settings/Settings.php index 50476c2a..cf875344 100755 --- a/src/Settings/Settings.php +++ b/src/Settings/Settings.php @@ -100,6 +100,9 @@ use Symfony\Component\Translation\Loader\YamlFileLoader; use Symfony\Component\Translation\Translator; use Symfony\Contracts\Translation\TranslatorInterface; +use Symfony\Component\Cache\Adapter\FilesystemAdapter; +use Symfony\Component\Cache\Adapter\NullAdapter; +use Symfony\Contracts\Cache\ItemInterface; use Twig\Extension\DebugExtension; use function DI\autowire; @@ -283,9 +286,11 @@ public function getContainerDefinition(string $envPath, string $envFilename): ar ); $container[PdfGenerator::class] = get(mPdfGenerator::class); $container[Translator::class] = function () { + $defLocale = $_ENV['DEFAULT_LOCALE']; // https://symfony.com/doc/current/components/translation.html - $translator = new Translator($_ENV['DEFAULT_LOCALE']); - $translator->setFallbackLocales([$_ENV['DEFAULT_LOCALE']]); + $cacheDir = $_ENV['TEMPLATE_CACHE'] !== 'false' ? __DIR__ . '/../../temp/translations' : null; + $translator = new Translator($defLocale, null, $cacheDir); + $translator->setFallbackLocales([$defLocale]); $translator->addLoader('yaml', new YamlFileLoader()); $translator->addResource('yaml', __DIR__ . '/../Templates/cs.yaml', 'cs'); diff --git a/src/Settings/TwigExtension.php b/src/Settings/TwigExtension.php index 382b1a58..aa5d2884 100755 --- a/src/Settings/TwigExtension.php +++ b/src/Settings/TwigExtension.php @@ -52,6 +52,9 @@ public function getTests(): array 'eligibleForShowTieCode', fn ($participant): bool => ( $participant instanceof TroopLeader && $participant->getUserButNotNull()->status === UserStatus::Open + ) || ( + // TroopLeader TieCode is also used for pairing with some external services, so they have to be able to access it in paid status + $participant instanceof TroopLeader && $participant->getUserButNotNull()->status === UserStatus::Paid ) || ( $participant instanceof TroopParticipant && $participant->troopLeader === null ) diff --git a/src/Templates/cs.yaml b/src/Templates/cs.yaml index 38cea74a..322cdea1 100755 --- a/src/Templates/cs.yaml +++ b/src/Templates/cs.yaml @@ -30,6 +30,7 @@ dashboard: youHaveTroop: "Jsi ve skupině %troopName% s vedoucím skupiny %troopLeaderFullName%" details: "podrobnosti" tieCode: "Kód pro připnutí" + pairCode: "kód skupiny" listOfParticipants: "Seznam účastníků" addParticipant: "Přidej účastníka" tie: "Připni" @@ -363,7 +364,7 @@ dashboard-admin: emailFrom: "Email prodávajícího zaplaceného účastníka" emailTo: "Email kupujícího účastníka" editParticipant: "Editovat údaje" - cancelParticipant: "Účastník nedorazí :(" + cancelParticipant: "Označit účastníka že nedorazí" changeNotice: "Upravit" import-file: "Import SRS souboru pro IST" import-submit: "Start importu" diff --git a/src/Templates/en.yaml b/src/Templates/en.yaml index b2dbce8f..bb4d04f1 100755 --- a/src/Templates/en.yaml +++ b/src/Templates/en.yaml @@ -30,6 +30,7 @@ dashboard: youHaveTroop: "You are in troop %troopName% with troop leader %troopLeaderFullName%" details: "details" tieCode: "Code for join" + pairCode: "Troop Code" listOfParticipants: "List of participants" addParticipant: "Add participant" tie: "tie" @@ -363,7 +364,7 @@ dashboard-admin: emailFrom: "Selling paid participant email" emailTo: "Buying participant email" editParticipant: "Edit details" - cancelParticipant: "Participant is not going :(" + cancelParticipant: "Mark participant as not going" changeNotice: "Edit" import-file: "Import SRS for IST file" import-submit: "Start import" diff --git a/src/Templates/sk.yaml b/src/Templates/sk.yaml index e4905298..191ba701 100755 --- a/src/Templates/sk.yaml +++ b/src/Templates/sk.yaml @@ -30,6 +30,7 @@ dashboard: youHaveTroop: "Jsi ve skupině %troopName% s vedoucím skupiny %troopLeaderFullName%" details: "podrobnosti" tieCode: "Kód pro připnutí" + pairCode: "kód skupiny" listOfParticipants: "Zoznam účastníkov" addParticipant: "Pridať účastníka" tie: "Připni" @@ -363,7 +364,7 @@ dashboard-admin: emailFrom: "Email prodávajícího zaplaceného účastníka" emailTo: "Email kupujícího účastníka" editParticipant: "Editovat údaje" - cancelParticipant: "Účastník nedorazí :(" + cancelParticipant: "Označit účastníka že nedorazí" changeNotice: "Upravit" import-file: "Import SRS souboru pro IST" import-submit: "Start importu" diff --git a/src/Templates/translatable/participant/dashboard.twig b/src/Templates/translatable/participant/dashboard.twig index 578da590..65911ada 100755 --- a/src/Templates/translatable/participant/dashboard.twig +++ b/src/Templates/translatable/participant/dashboard.twig @@ -12,7 +12,11 @@ {% if person is eligibleForShowTieCode %}

- {% trans %}dashboard.tieCode{% endtrans %} - {{ person.tieCode }} + {% if userStatus == 'paid' and person.role.value == 'tl'%} + {% trans %}dashboard.pairCode{% endtrans %} - {{ person.tieCode }} + {% else %} + {% trans %}dashboard.tieCode{% endtrans %} - {{ person.tieCode }} + {% endif %}

{% endif %}