Szybkie posty

Jeżeli coś jest wartego uwagi a nie jest to materiał na pełnoprawnwgo posta na blogu to będę starać się to umieszczać w tym miejscu.

#ajax #apache #behat #bitbacket #bootstrap #composer #cookies #cqrs #css #css flex #ct8 #curl #docker #doctrine #edukacja #enet #enp sla #filmy #firma #funkcje php #git #google #htaccess #html #inne #javascript #jedzenie #jquery #js/jquery #kawały #krypto #laravel #linux #oop #pdo #php #php wzorce narzędzia #phpmyadmin #phpspec #phpstan #phpstorm #phpunit #podcast #rabbit #redis #seo #soap #sql #symfony #szukanie po stringach w php #twig #virtual host #visual studio code #vue #wamp #windows #wino-nalewki #wyrazenia regularne #wzorce projektowe #xml #xxx #zdjecia #złote myśli
  • Szukasz po tagu: symfony
  • Ilość rekordów w bazie: 77

option opcje jako tablica w comandzie symfony

        ->addOption(
                self::OPTION_STATUS_TYPES,
                'st',
                InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY,
                'Allowed status types separated by comma i.e. <info>--statusTypes=1,2,3</info> 1 - initial, 2 - normal, 3 - final',
                ''
            )
php symfony test:myTask --typical-days=7 --typical-days=5 --typical-days=8

LUB

          ->addOption(
                self::OPTION_STATUS_TYPES,
                'st',
                InputOption::VALUE_OPTIONAL,
                'Allowed status types separated by comma i.e. <info>--statusTypes=1,2,3</info> 1 - initial, 2 - normal, 3 - final',
                ''
            )
$statusTypes = array_filter(array_map('intval', explode(',', $input->getOption(self::OPTION_STATUS_TYPES))));

walidacja warunkowa w formie

    public function onSubmit(FormEvent $event): void
    {
        $form = $event->getForm();

        $requiredFormData[] = $form['code'];
        $requiredFormData[] = $form['address']['street'];
        $requiredFormData[] = $form['address']['houseNumber'];
        $requiredFormData[] = $form['address']['lat'];
        $requiredFormData[] = $form['address']['lng'];

        foreach ($requiredFormData as $single) {
            if (empty($single->getData())) {
                $single->addError(
                    new FormError($this->translator->trans('xxxx', [], 'XXXBundle'))
                );
            }
        }
    }

phpunit błedy testów przez rzeczy deprcated

Trzeba dodać paramter w tene sposób

SYMFONY_DEPRECATIONS_HELPER
    <php>
        <ini name="display_errors" value="1" />
        <ini name="error_reporting" value="-1" />
        <server name="APP_ENV" value="test" force="true" />
        <env name="KERNEL_CLASS" value="Shared\Framework\Infrastructure\Kernel" force="true" />
        <server name="SHELL_VERBOSITY" value="-1" />
        <server name="SYMFONY_PHPUNIT_REMOVE" value="" />
        <server name="SYMFONY_PHPUNIT_VERSION" value="9.5" />
        <env name="SYMFONY_DEPRECATIONS_HELPER" value="weak" />
    </php>

w tym pliku

phpunit.xml.dist

lub do pliku env.test dodać

SYMFONY_DEPRECATIONS_HELPER=disabled

debugowanie wartości paramteru

dphp app/api_ENP0026A01/console debug:container --parameter='xxxx' --env=loc
php bin/console -k admin_ENP0026  debug:container --parameter enp_gift_card_akart.api_url --env=prod

dodanie customowego pliku do walidacji

class ValidatorPass implements CompilerPassInterface
{
    public function process(ContainerBuilder $container)
    {
        $validatorBuilder = $container->getDefinition('validator.builder');

        $validationYmlPath = $container->getParameter('enp_address.validation_yml_path');
        $appDir = $container->getParameter('kernel.root_dir');

        $file = new SplFileInfo($appDir.'/../../'.$validationYmlPath);

        $validatorFiles = [$file->getRealpath()];
        $validatorBuilder->addMethodCall('addYamlMappings', [$validatorFiles]);
    }
}

walidacja obiektu w symofny

use Symfony\Component\Validator\Validator\ValidatorInterface;
$errors = $this->validator->validate(
    $object,
    null,
    $this->addressValidationGroups
);

if ($errors->count() > 0) {
            
}

add select if

  public function getPosTypeNameByActive(): array
    {
        $query = $this->connection->createQueryBuilder();
        $query->select($this->getAlias() . '.name')
            ->addSelect(
                'IF (cf.id IS NOT NULL AND (:dateNow >= cf.date_from AND :dateNow <= cf.date_to), 1, 0) as active'
            )
            ->leftJoin(
                $this->getAlias(),
                'cycle',
                'c',
                sprintf('c.id = %s.cycle_id', $this->getAlias())
            )
            ->leftJoin(
                $this->getAlias(),
                'cycle_flat',
                'cf',
                sprintf('cf.cycle_id = %s.cycle_id', $this->getAlias())
            )
            ->setParameter('dateNow', ActualDate::get()->format('Y-m-d H:i:s'), PDO::PARAM_STR)
            ->resetQueryPart('from')->from($this->getTableName(), $this->getAlias())
            ->having('active = 1');

        return $query->execute()->fetchAll(PDO::FETCH_COLUMN);
    }

symfony fetch na tablice intów

    private function getPaymentConfigurationPaymentsIdsToUpdate(int $aliorPaymentIntegrationId): array
    {
        $query = $this->connection->executeQuery(
            'SELECT id FROM payment WHERE integration_id = :integration_id',
            [
                'integration_id' => $aliorPaymentIntegrationId,
            ],
            [
                'integration_id' => Types::INTEGER,
            ]
        );

        return array_map('intval', $query->fetchAll(PDO::FETCH_COLUMN));
    }

konigurajca serwisów

    Enp\Bundle\PaymentApi\AliorBundle\Controller\Front\NotificationController:
        arguments:
            $logger: "@enp_payment_api.alior.logger_file"
        calls:
            - [ setContainer, [ '@service_container' ] ]
    Enp\Bundle\Api\CartBundle\Controller\:
        autowire: true
        resource: '../../../../CartBundle/Controller'
        tags: ['controller.service_arguments']
services:
    _defaults:
        autowire: true
        autoconfigure: true

    Enp\Bundle\CartBundle\Controller\:
        resource: '../../../Controller/'

    Enp\Bundle\CartBundle\Controller\CartMiniController:
        arguments:
            $groupItemsManager: '@enp_order.manager.group_items'
services:
    _defaults:
        autoconfigure: true
        autowire: true

    _instanceof:
        Module\ServiceDebug\Model\Service\CartSimulatorBuilder\CartSimulatorBuilderInterface:
            tags: [ 'service_debug.cart_simulator_builder' ]

    Module\ServiceDebug\Model\Service\:
        resource: '../../../Model/Service/'

    Module\ServiceDebug\Model\Service\CartSimulatorBuilder\CartSimulatorBuilderChain:
        arguments:
            $builders: !tagged_iterator { tag: service_debug.cart_simulator_builder }
    Enp\Bundle\ENP0026\OrderBundle\Service\OrderFastReturn\OrderFastReturnService:
        arguments: [!tagged enp.order.order_fast_return.guard]

    Enp\Bundle\ENP0026\OrderBundle\Service\OrderFastReturn\Guard\OrderCanceledGuard:
        tags:
            - { name: 'enp.order.order_fast_return.guard' }

    Enp\Bundle\ENP0026\OrderBundle\Service\OrderFastReturn\Guard\InvoiceAndWayBillGuard:
        autowire: true
        tags:
            - { name: 'enp.order.order_fast_return.guard' }

zapytanie na obiekt w symfony

   public function getDataToRefundByOrderUniqueHash(string $orderUniqueHash): RefundDataDTOCollection
    {
        $queryBuilder = $this->connection->createQueryBuilder();
        $queryBuilder
            ->select(
                'o.id as orderId,
                o.customer_id as customerId,
                o.unique_hash as uniqueHash,
                o.website_id as websiteId,
                oi.id as orderItemId'
            )
            ->from('order_related', 'orr')
            ->innerJoin('orr', '`order`', 'o', 'orr.order_id = o.id')
            ->innerJoin('orr', '`order_item`', 'oi', 'orr.order_id = oi.order_id')
            ->where('orr.order_related_id IN (SELECT id FROM `order` WHERE unique_hash = :uniqueHash)')
            ->andWhere('o.deleted_at IS NULL AND o.archival = 0')
            ->groupBy('orderItemId')
            ->setParameter('uniqueHash', $orderUniqueHash, PDO::PARAM_STR);

        $stmt = $queryBuilder->execute();

        return new RefundDataDTOCollection($stmt->fetchAll(PDO::FETCH_CLASS, RefundDataDTO::class));
    }

idk z kolekcji doctrine

$ordersIds = $orders->map(fn($order) => $order->getId())->getValues();

read model doctrine symfony

class StatusFinder extends FinderAbstract
{
    public function getTableName(): string
    {
        return 'payment_mokka_status';
    }

    public function getAlias(): string
    {
        return 'pmos';
    }

    /**
     * @param string $orderNumber
     *
     * @return StatusReadModel[]
     */
    public function getStatusCollection(string $orderNumber): array
    {
        return array_map(
            static fn($order) => StatusReadModel::create($order),
            $this->getQueryBuilder()
                ->andWhere(sprintf('%s.order_number = :order_id', $this->getAlias()))
                ->setParameter('order_id', $orderNumber, PDO::PARAM_STR)
                ->execute()
                ->fetchAll()
        );
    }

    public function getLatestStatus(string $orderNumber): ?StatusReadModel
    {
        $qb = $this->getQueryBuilder()
            ->andWhere(sprintf('%s.order_number = :order_id', $this->getAlias()))
            ->orderBy(sprintf('%s.id', $this->getAlias()), 'desc')
            ->setMaxResults(1)
            ->setParameter('order_id', $orderNumber, PDO::PARAM_STR)
            ->execute();
        $data = $qb->fetch();

        if ($data) {
            return StatusReadModel::create($data);
        }

        return null;
    }
}
class StatusReadModel
{
    private int $id;

    private string $orderNumber;

    private array $response;

    private DateTimeInterface $createdAt;

    private function __construct(int $id, string $orderNumber, array $response, DateTimeInterface $createdAt)
    {
        $this->id = $id;
        $this->orderNumber = $orderNumber;
        $this->response = $response;
        $this->createdAt = $createdAt;
    }

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

    public function getOrderNumber(): string
    {
        return $this->orderNumber;
    }

    public function getResponse(): array
    {
        return $this->response;
    }

    public function getCreatedAt(): DateTimeInterface
    {
        return $this->createdAt;
    }

    public static function create(array $data): self
    {
        return new self(
            (int)($data['id'] ?? 0),
            $data['order_number'],
            json_decode($data['response'], true),
            new DateTime($data['created_at'])
        );
    }

    public function getOrderData(): array
    {
        return $this->response[ApiParameterEnum::CURRENT_ORDER] ?? [];
    }

    public function getOrderStatus(): ?string
    {
        return $this->response[ApiParameterEnum::CURRENT_ORDER][ApiParameterEnum::STATUS] ?? null;
    }

    public function paymentHasBeenApproved(): bool
    {
        return ($this->getOrderData()[ApiParameterEnum::DECISION] ?? null) === PaymentDecisionEnum::APPROVED
            && !empty($this->getPaymentId());
    }

    public function getPaymentId(): ?string
    {
        return $this->getOrderData()[ApiParameterEnum::PAYMENT_ID] ?? null;
    }
}

symfony fetch unique

    public function getWarehouseDataByCode(string $code, array $fields)
    {
        $queryBuilder = $this->getEntityManager()->getConnection()->createQueryBuilder()
            ->select(...$fields)
            ->from($this->getClassMetadata()->getTableName(), 'w')
            ->andWhere('w.code = :code')
            ->andWhere('w.deleted_at IS NULL')
            ->setParameter('code', $code, PDO::PARAM_STR);

        return $queryBuilder->execute()->fetchAll(PDO::FETCH_UNIQUE);
    }
$test = getWarehouseDataByCode('xxxx', ['id']));
//zwróci
array:1 [▼
  5539 => array:1 [▼
    "code" => "virtual_sum_ec_pl"
  ]
]

symfony text type długość

You need to set the length:
To TINYTEXT => length = 255
To TEXT => length = 65535
To MEDIUMTEXT = 16777215
Default: LONGTEXT

Then, for example if you need an type text, it's necessary:

/** * @ORM\Column(name="description", type="text", length=65535)

parsowanie na tablice dtosów

    public function getTransportsPrice(int $posId, int $websiteId): array
    {
        try {
            $results = $this->getAll(['pos_id' => $posId, 'website_id' => $websiteId]);

            return array_map(static fn (array $row) => TransportPriceDTO::fromArray($row), $results);
        } catch (Throwable $exception) {
            return [];
        }
    }

nadpisanie serwisu

class OverrideServiceCompilerPass implements CompilerPassInterface
{
    public function process(ContainerBuilder $container): void
    {
        $this->overrideECodeItemsInOrder($container);
    }

    private function overrideECodeItemsInOrder(ContainerBuilder $container): void
    {
        if ($container->hasDefinition(ECodeItemsInOrder::class)) {
            $definition = $container->getDefinition(ECodeItemsInOrder::class);
            $definition->setClass(MshECodeItemsInOrder::class);
        }
    }
}

symfony mapowanie na inty w zapytaniu

    public function gettt(int $serviceId): array
    {
        $query = $this->connection->prepare(
            'SELECT s_id FROM somefing_has shcs WHERE xxxx =:xxxx'
        );
        $query->bindParam('xxxx', $xxxx, PDO::PARAM_INT);
        $query->execute();

        return array_map('intval', $query->fetchAll(PDO::FETCH_COLUMN));
    }

lub

return array_column($qb->getQuery()->getResult(Query::HYDRATE_ARRAY), 'nazwa_col');

lub

        $queryBuilder = $this->connection->createQueryBuilder();
        /** @var PDOConnection $pdo */
        $pdo = $this->connection->getWrappedConnection();
        $oldAttributeValue = $pdo->getAttribute(PDO::ATTR_EMULATE_PREPARES);
        $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

        $queryBuilder
            ->select('DISTINCT(orr.order_id)')
            ->from('order_related', 'orr')
            ->innerJoin('orr', '`order`', 'o', 'orr.order_related_id = o.id')
            ->where('o.id IN (SELECT id FROM `order` WHERE unique_hash = :uniqueHash)')
            ->setParameter('uniqueHash', $orderUniqueHash, PDO::PARAM_STR);

        $stmt = $queryBuilder->execute();
        $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, $oldAttributeValue);

        return $stmt->fetchAll(PDO::FETCH_COLUMN);

monolog logi symfony

monolog:
    handlers:
        main:
            type:   stream
            path:   "%kernel.logs_dir%/%kernel.environment%.log"
            level:  critical
        console:
            type:   console
            bubble: false

enp_core:
    log_level: 200
app/xxxx/config/config_loc.yml:13
 

 


Otagowane serwisy przykład

class CustomerChecker implements ActionCheckerInterface
{
    private $checkers = [];

    public function __construct(iterable $checkers)
    {
        $this->checkers = $checkers;
    }

    public function isEligible(ActionInterface $action): bool
    {
        foreach ($this->checkers as $checker) {
            if (false === $checker->isEligible($action)) {
                return false;
            }
        }

        return true;
    }
}
    Enp\Bundle\Promotion\ActionBundle\Checker\CustomerChecker:
        autowire: true
        arguments:
            - !tagged enp_promotion.action.customer_checker

    Enp\Bundle\Promotion\ActionBundle\Checker\CustomerPermissionChecker:
        autowire: true
        tags:
            - { name: enp_promotion.action.customer_checker }

 


symfony route sposob

https://stackoverflow.com/questions/54495546/symfony-flex-overriding-twigs-routing-path-function?fbclid=IwAR225-8nqneyzkPC_k_e_lFSJn07RvClzZyLXNdOK1yyYVaYWkQy-osyq_Q


migracja array

    public function down(Schema $schema): void
    {
        $this->addSql(
            "DELETE FROM flag WHERE system_code in (:codes)",
            [
                'codes' => [
                    ENP0026OrderFlagEnum::TERG_LEASING,
                    ENP0026OrderFlagEnum::TERG_LOAN_LEASING,
                ],
            ],
            [
                'codes' => Connection::PARAM_STR_ARRAY,
            ]
        );
    }

symfony wywołanie settera na serwisie

services:
    xxxxxxxxxxx:
        calls:
            - [setItemQuantityDecorator, ['@xxxxxxx']]

stała wstrzyknieta do serwisu

    Enp\Bundle\ENP0031\AddressBundle\Validator\Constraints\ApartmentNumber\ValidatorDefault:
        class: Enp\Bundle\ENP0031\AddressBundle\Validator\Constraints\ApartmentNumber\ValidatorDefault
        arguments:
            $maxLenght: 10
        tags:
            - { name: enp_address_validator_apartment_number, service_key: !php/const:Enp\Bundle\ENP0031\AddressBundle\Validator\Constraints\ApartmentNumberValidator::DEFAULT_VALIDATOR_KEY }

twig extension optymalizacja

w naszej aktualnej wersji symfony (oraz twig) otrzymaliśmy możliwość tworzenia lazy-loaded twig extensions.
 
Ogólnie sprowadza się to do rozdzielnia extensiona na dwie klasy:
  1. FooExtension - zawierający jedynie listę dostępnych metod
  2. FooRuntime - zawierający logikę metod
Przykładowy jeden przerobiony extension znajdziecie w MR: http://gitlab.enp.me/mshp/adafir/-/merge_requests/67805

php spec test formularza

class FastOrderReturnCreatorSpec extends ObjectBehavior
{
    public function it_is_initializable(): void
    {
        $this->shouldHaveType(FastOrderReturnCreator::class);
        $this->shouldBeAnInstanceOf(OrderEditFormInterface::class);
    }

    public function let(
        FormFactoryInterface $formFactory,
        RouterInterface $router
    ): void {
        $this->beConstructedWith($formFactory, $router);
    }

    public function it_creates_form(
        FormFactoryInterface $formFactory,
        RouterInterface $router,
        OrderInterface $order,
        FormInterface $form
    ): void {
        $orderId = 1;
        $url = '/order/fast-order-return/1';

        $order->getId()->willReturn($orderId)->shouldBeCalledOnce();
        $router->generate('enp_enp0026_order_fast_return', ['orderId' => $orderId])->willReturn($url);

        $formFactory->createNamed(
            'order_return',
            FastOrderReturnType::class,
            null,
            [
                'action' => $url,
                'method' => Request::METHOD_PUT,
            ]
        )->willReturn($form);

        $this->createOrderEditForm($order)->shouldBe($form);
    }

php spec tets translatora w symfony

public function it_should_return_true(Order $order, TranslatorInterface $translator): void
    {
        $flagsToBlock = ['xxxx', 'aaaa', 'bbbb'];

        $order->hasFlagByCode('xxxx')->willReturn(false);
        $order->hasFlagByCode('aaaa')->willReturn(false);
        $order->hasFlagByCode('bbbb')->willReturn(false);

        $translator->trans(
            'enp.order.order_quick_return.order_source.error',
            [
                '%flagsToBlock%' => implode(',', $flagsToBlock),
            ],
            'EnpOrderBundle'
        )->willReturn('message');

        $this->beConstructedWith($flagsToBlock, $translator);
        $this->check($order)->shouldReturn(true);
        $this->getErrorMessage()->shouldBe('message');
    }

migracja z szukaniem tabel o podobnych nazwach

<?php

declare(strict_types=1);

namespace Application\Migrations;

use Doctrine\DBAL\Schema\Schema;
use Enp\Bundle\CoreBundle\Migration\AbstractEnpMigration;
use PDO;

final class Version20200819084526 extends AbstractEnpMigration
{
    public function up(Schema $schema): void
    {
        foreach ($this->getOrderExtensionTables() as $tableName) {
            if (empty($tableName)) {
                continue;
            }

            $this->addSql(sprintf('ALTER TABLE %s ADD payment_document_number VARCHAR(255) DEFAULT NULL', $tableName));
        }
    }

    public function down(Schema $schema): void
    {
        foreach ($this->getOrderExtensionTables() as $tableName) {
            if (empty($tableName)) {
                continue;
            }
            $this->addSql(sprintf('ALTER TABLE %s DROP payment_document_number', $tableName));
        }
    }

    private function getOrderExtensionTables(): array
    {
        $tables = $this->connection->executeQuery(
            "SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA = SCHEMA() AND TABLE_NAME LIKE '%\_order_extension';"
        )->fetchAll(PDO::FETCH_COLUMN);
        $tables[] = 'order_extension';

        return $tables;
    }
}

Przyklad migracji z last insert id

        $this->addSql('
            INSERT INTO `admin_module_action` (`security_attribute`, `name`, `descr`, `admin_module_id`, `securitySchema`, `cycle_id`)
            VALUES (\'VANSELING_ORDER\', \'Zamówienie vanseling\', \'Zamówienie vanseling\', 98, 1, NULL);
        ');
        $this->addSql('
            INSERT INTO `admin_role` (`name`, `descr`, `enabled`, `deleted_at`, `system_code`)
            VALUES (\'Operator vanseling\', \'Sprzedaż bezpośrednia od kierowcy\', 1, NULL, NULL);
            SET @adminRoleId = LAST_INSERT_ID();
        ');
        $this->addSql('
            INSERT INTO `admin_role_has_admin_module_action` (`admin_role_id`, `admin_module_action_attribute`)
            VALUES (@adminRoleId, \'VANSELING_ORDER\');
        ');
        $this->addSql('
            INSERT INTO `admin_role_has_admin_module_action` (`admin_role_id`, `admin_module_action_attribute`)
            VALUES (@adminRoleId, \'VANSELING_CHANGE_ITEM_PRICE\');
        ');

konfiguracja po zmiennych konstruktora w symfony

 Enp\Bundle\OrderBundle\Service\Calculator\OrderRealizationTimeCalculator:
        class: Enp\Bundle\OrderBundle\Service\Calculator\OrderRealizationTimeCalculator
        autowire: true
        arguments:
            $configuration: '%enp_order.configuration_of_calculating_time_of_order_realize%'

mysql group by z max wartością kolumny

  public function findLatestCreationDatesByOrderAndStatusesIds(
        OrderInterface $order,
        array $statusesIds
    ): array {
        $queryBuilder = $this->getQueryBuilder()
            ->select(
                \sprintf('IDENTITY(%s.status) as status', $this->getAlias()),
                \sprintf('max(%s.createdAt) as createdAt', $this->getAlias())
            )
            ->andWhere(\sprintf('%s.order = :order', $this->getAlias()))
            ->setParameter(
                'order',
                $order->getId(),
                PDO::PARAM_INT
            )
            ->andWhere(sprintf('%s.status IN (:statuses)', $this->getAlias()))
            ->setParameter(
                'statuses',
                $statusesIds,
                Connection::PARAM_INT_ARRAY
            );

        $queryBuilder->groupBy(sprintf('%s.status', $this->getAlias()));

        return $queryBuilder->getQuery()->getResult();
    }

sprawdzanie czy istnieje parameter przy wstrzykiwaniu

services:
    Enp\Bundle\MenuBundle\Chain\DestinationManipulatorChain\Manipulator\EsOfferListManipulator:
        class: Enp\Bundle\MenuBundle\Chain\DestinationManipulatorChain\Manipulator\EsOfferListManipulator
        arguments:
            - "@=container.hasParameter('enp_es_product_offer.enabled') ? parameter('enp_es_product_offer.enabled') : false"
        tags:
            - { name: menu_item_destination_manipulator, service_key: 'es_offer_list_destination'}

Flush persist w repozytorium

  /**
     * EM flush
     */
    public function flush()
    {
        $this->getEntityManager()->flush();
    }

    /**
     * EM persist
     * 
     * @param ClientStatData $entity
     */
    public function persist(ClientInstytutionStat $entity)
    {
        $this->getEntityManager()->persist($entity);
    }

Update BETWEEN

        return $this->createQueryBuilder('c')
            ->update()
            ->set('c.modifiedDatetime', ':modifiedDatetime')->setParameter('modifiedDatetime', $dateTimeNow)
            ->andWhere('c.requestedDatetime BETWEEN :requestedDatetimeStart AND :requestedDatetimeEnd')->setParameter('requestedDatetimeStart', $dateFrom)->setParameter('requestedDatetimeEnd', $dateTo)
            ->andWhere('( (c.modifiedDatetime NOT BETWEEN :dateStart AND :dateEnd) or c.modifiedDatetime is null )')->setParameter('dateStart', $dateFrom)->setParameter('dateEnd', $dateTo)
            ->getQuery()
            ->getSingleScalarResult();

Zapis dubagera symfony do pliku

 php bin/console debug:container > c:/as.txt

Wybrane pola mapowane na obiekt w doctrine

public function findPosts() {
        $posts = $this->getEntityManager()->createQueryBuilder('p');
        $posts
                ->select('partial p.{id, title, slug,shortcontent,publishedAt}', 't')
                ->from('App:Post', 'p')
                ->leftJoin('p.tags', 't')
                ->orderBy('p.id', 'DESC');

        return $posts;
    }

Symfony update czysty sql

 /**
     * restore suspended items
     * (with status in_progress and olther then 7 days)
     *
     * @return bool
     */
    public function restoreSuspendedItems(): bool
    {
        $maxDatetimeAdd = (new \DateTime('now - 7 days'))->format('Y-m-d H:i:s');
        try {
            $sqlQuery = 'UPDATE rb_sms_storage SET status= "' . SmsResultStatuses::WAITING . '" WHERE status = "' . SmsResultStatuses::IN_PROGRESS . '" AND datetime_add <= "' . $maxDatetimeAdd . '"';
            $connection = $this->getEntityManager()->getConnection()->prepare($sqlQuery);

            $connection->execute();
            return true;
        } catch (\Exception $ex) {
            return false;
        }
    }

Customowe pole w doctrine

stepNumber:
   columnDefinition : 'TINYINT NOT NULL'
   nullable: false

Zaokrąglanie w twigu

{{ ((single.errors/parseLogs.numberOfLogs)*100)|number_format(2,',', '') }}%

Data od do w doctrine

public function getUniqueTransactionCountByStatusInDateRange(\DateTime $dateFrom, \DateTime $dateTo, $transactionStatus) {
        $query = $this->getEntityManager()->createQueryBuilder()
                        ->from(Transaction::class, 't')
                        ->select('COUNT(DISTINCT(t.transaction_id))')
                        ->where('t.created_at >= :DateTimeBegin')->setParameter('DateTimeBegin', $dateFrom->format('Y-m-d H:i:s'))
                        ->andWhere('t.created_at <= :DateTimeEnd')->setParameter('DateTimeEnd', $dateTo->format('Y-m-d H:i:s'))
                        ->andWhere('t.status = :Status')->setParameter('Status', $transactionStatus)
        ;

        try {
            return (int) $query->getQuery()->getSingleScalarResult();
        } catch (\Doctrine\ORM\NoResultException $e) {
            return 0;
        }
    }

Form w twigu

{{ form_start(form) }}
    {{ form_errors(form.postCode) }}
    {{ form_label(form.postCode,'', { 'label_attr': {'class': 'panel-title'} }) }}
    {{ form_widget(form.postCode, {'attr':{'class':'form-control'}}) }}
{{ form_end(form) }}

Doctrine2 typy pól

const TARRAY = 'array';
const SIMPLE_ARRAY = 'simple_array';
const JSON_ARRAY = 'json_array';
const BIGINT = 'bigint';
const BOOLEAN = 'boolean';
const DATETIME = 'datetime';
const DATETIMETZ = 'datetimetz';
const DATE = 'date';
const TIME = 'time';
const DECIMAL = 'decimal';
const INTEGER = 'integer';
const OBJECT = 'object';
const SMALLINT = 'smallint';
const STRING = 'string';
const TEXT = 'text';
const BINARY = 'binary';
const BLOB = 'blob';
const FLOAT = 'float';
const GUID = 'guid';

Powrót wstecz back

return $this->redirect($request->headers->get('referer'));

Doctrine hydracja

W takim razie problemem raczej jest sposób hydrowania danych, można to rozwiązać na dwa sposoby:

1. Użyć odpowiedniej adnotacji (LAZY, EAGER lub EXTRA LAZY), więcej np. tutaj: http://docs.doctrine-project.org/projects/...sociations.html i to się sprawdzi jeśli wiemy, że np. wraz z obiektem User zawsze będziemy potrzebowali kolekcji emaili (wtedy ustawiamy na EAGER)

2. Jeśli sposób hydrowania jest zależny od kontekstu, to nie ma innego (wygodnego) wyjścia jak użyć query buildera. Jednak nie wystarczy:

  1. $qb->join('u.emails', 'e');

- trzeba jeszcze wymusić pobieranie poprzez dodanie select:

  1. $qb->select('u', 'e');


W ten sposób emaile zawsze będą w user niezależnie od tego, czy są potrzebne czy nie.

Więcej nie da się powiedzieć bo nie znam Twojego kodu, równie dobrze problemem mogą być źle zaprojektowane encje.


Dodanie klasy do labela

->add('name', TextType::class, [
    'label' => 'Nazwa grupy:',
    'required' => true,
    'attr' => ['placeholder' => 'Wpisz nazwę grupy...', 'class' => 'form-control'],
    'label_attr' => ['class' => 'panel-title']
])

wybranie pola z relacji w symfony

public function getRejectedInstitutionsIdsForClientByInstitutionsIdsAndDate(Client $client, array $institutionsIds, \DateTime $dateTime): array {
        $query = $this->createQueryBuilder('cis')
                        ->select('IDENTITY(cis.institution)')
                        ->andWhere('cis.client = :client')->setParameter('client', $client)
                        ->andWhere('cis.institution IN (:institutions)')->setParameter('institutions', $institutionsIds)
                        ->andWhere('cis.date_of_possible_next_serve >= :date_of_possible_next_serve')->setParameter('date_of_possible_next_serve', $dateTime);

        $result = $query->getQuery()->getResult();

        return array_map(function($value) {
            return $value['1'];
        }, $result);
}

Konfiguracja swiftmailera w symfony

MAILER_URL=smtp://odrserwer.home.pl:465?encryption=ssl&auth_mode=login&username=noreplay%40confronter.pl&password=xxx_your_encoder_password_xxx

Aby wysyłka emaila działała należy ustawić zaencodeowane hasło @ np w tym przypadku ma postać %40


Kierowanie forma na na konkretny adres

$formSendSms = $this->createForm(SmsType::class, [], ['action' => $this->generateUrl('user_two_step_auth_notification_option'), 'method' => 'POST'])->handleRequest($request);
$formSendEmail = $this->createForm(EmailType::class, [], ['action' => $this->generateUrl('user_two_step_auth_notification_option'), 'method' => 'POST'])->handleRequest($request);

symfony zapytanie nie puste i nie null

public function getReportsValidationCostsHavingGoogleAccount(): array {
        return $this->createQueryBuilder('c')
                        ->andWhere('c.google_account != \'\'')
                        ->getQuery()
                        ->getResult()
        ;
}

Wstrzykniecie parametru bezposrednio z parametrów

dm_report.cost_sms:
        class: DM\RaportyBundle\Service\ReportValidation\Cost\CostSmsService
        arguments: 
            - "@dm_report.report_validation.cost_repository"
            - "@dm_sms.group.repository"
            - "@dm_sms.storage.repository"
            - "@dm_report.report_validation.cost_value_repository"
            - "%logs_dir%"

symfony JSON_CONTAINS

  public function getClientDataBySerializedDataJsonKey(string $keyName, string $keyValue, int $penultimateStep) :?MultiStepFormClientData {
        $createdAtCondition = new \DateTime('now -30 days');
        
        $query = $this->createQueryBuilder('cd')
            ->where('cd.createdAt > :createdAt')
            ->andWhere('cd.stepNr = :stepNr')
            ->andWhere('cd.status = :status')    
            ->andWhere("JSON_CONTAINS(cd.serializedData, :keyName, '$.".$keyName."') = 1");

        $query->setParameter('createdAt', $createdAtCondition);
        $query->setParameter('stepNr', $penultimateStep);
        $query->setParameter('status', ClientStatuses::TYPE_COMPLETED);
        $query->setParameter('keyName', '"'.$keyValue.'"');
        $query->orderBy('cd.createdAt', 'DESC')->setMaxResults(1);
        
        return $query->getQuery()->getOneOrNullResult();
    }

//wymaga 

link