ORM, Symfony 4, SQL Запрос

210
12 июля 2018, 09:20

Объясните пожалуйста, как правильно сделать, мне необходимо получить результат следующего запроса:

select 
    value 
from variables 
where 
    id_language = (SELECT value FROM globalSetting WHERE code = \'lang\' limit 1)
    and code = :code  

Для взаимодействия контроллера и сущности я использую следующий mapping :

App\Entity\Variables:
  type: entity
  table: variables
  repositoryClass: App\Repository\VariablesRepository
  id:
    id:
      type: guid
  fields:
    name:
      type: string
      length: 50
      nullable: false
    code:
      type: string
      length: 100
      nullable: false
    value:
      type: string
      length: 100
      nullable: false
    id_language:
      type: integer
      length: 11
      nullable: false  

Модель:

namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
class Variables
{
    private $id;
    private $name;
    private $code;
    private $value;
    private $id_language;
    public function getId(): int
    {
        return $this->id;
    }
    public function getId_language(): int
    {
        return $this->id_language;
    }
    public function getValue(): string
    {
        return $this->value;
    }
}  

Контроллер :

namespace App\Controller\Admin;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
class AdminsController extends Controller
{
    private $entityManger;
    public function __construct()
    {
        $this->entityManger = $this->getDoctrine()->getManager();
    }
    public function entrance(Request $request)
    {
        $title = "Admin panel";
        if($request->isMethod('POST'))
        {
            $error = "";
            $login = $request->get('login');
            $password = $request->get('password');
            $user = $this->entityManger->getRepository('App:Admins')
                ->findOneBy(array('login'=>$login));
            if(is_null($user))
            {
                $result = $this->entityManger->getRepository('App:Variables')->getLanguageMessage("AuthorizationError");
                   // ->findOneBy(array('id_language' => $langId, 'code' => 'AuthorizationError'));
                print_r($result);
            }

            return $this->render('admin\login.html.twig', array('title' => $title, 'error' => $error));
        }
        else
        {
            return $this->render('admin\login.html.twig', array('title' => $title));
        }
    }
    public function logIn()
    {
        return $this->render('admin\login.html.twig');
    }
}  

И VariablesRepository:

<?php
namespace App\Repository;
use App\Entity\Product;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Symfony\Bridge\Doctrine\RegistryInterface;
/**
 * @method Product|null find($id, $lockMode = null, $lockVersion = null)
 * @method Product|null findOneBy(array $criteria, array $orderBy = null)
 * @method Product[]    findAll()
 * @method Product[]    findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
 */
class VariablesRepository extends ServiceEntityRepository
{
    public function __construct(RegistryInterface $registry)
    {
        parent::__construct($registry, Product::class);
    }
    public function getLanguageMessage($code)
    {
        $conn = $this->getEntityManager()->getConnection();
        $query =
        "
            select 
                value 
            from variables 
            where 
                id_language = (SELECT value FROM globalSetting WHERE code = \'lang\' limit 1)
                and code = :code
        ";
        $stmt = $conn->prepare($query);
        $stmt->execute(['code' => $code]);
        // returns an array of arrays (i.e. a raw data set)
        return $stmt->fetchAll();
    }
//    /**
//     * @return Product[] Returns an array of Product objects
//     */
    /*
    public function findByExampleField($value)
    {
        return $this->createQueryBuilder('p')
            ->andWhere('p.exampleField = :val')
            ->setParameter('val', $value)
            ->orderBy('p.id', 'ASC')
            ->setMaxResults(10)
            ->getQuery()
            ->getResult()
        ;
    }
    */
    /*
    public function findOneBySomeField($value): ?Product
    {
        return $this->createQueryBuilder('p')
            ->andWhere('p.exampleField = :val')
            ->setParameter('val', $value)
            ->getQuery()
            ->getOneOrNullResult()
        ;
    }
    */
}  

Я изучаю symfony, до это как правило писал на чистом php, понимаю, что фреймворк должен мне облегчить жизнь, но пока все совсем наоборот, кажется все дико запутанным. Зачем вообще существуют классы Repository? Разве они не нужны только когда mapping прописывается в аннотациях? Пожалуйста подскажите. Без фреймворка я бы давным давно сделал то что мне нужно :(.

Answer 1

Нашел ошибку, вот тут указан класс Product:

class VariablesRepository extends ServiceEntityRepository
{
    public function __construct(RegistryInterface $registry)
    {
        parent::__construct($registry, Product::class);
    }  

а надо Variables. Вопрос "Зачем Repository?" остался открытым, почему нельзя подобное написать в модели?

Answer 2

Что бросается в глаза

  1. nullable: false - это необязательно писать, так как nullable по умолчанию false.

  2. То что вы называете моделью некий объектный "образ" сущности, хранимой в БД.

  3. Очевидно, что из-за недостатка опыта, вы используете, на мой субъективный взгляд, более сложные подходы. Контроллер и репозиторий у вас это сервисы которые сами резолвят необходимые классы через DI:

Репозиторий

<?php
namespace App\Repository;
use Doctrine\ORM\EntityManagerInterface;
/**
 * Class VariablesRepository
 * @package App\Repository
 */
class VariablesRepository
{
    /**
     * @var EntityManagerInterface
     */
    private $manager;
    /**
     * VariablesRepository constructor.
     *
     * @param EntityManagerInterface $manager
     */
    public function __construct(EntityManagerInterface $manager)
    {
        $this->manager = $manager;
    }
    /**
     * @param $code
     *
     * @return array
     * @throws \Doctrine\DBAL\DBALException
     */
    public function getLanguageMessage($code)
    {
        $conn = $this->manager->getConnection();
        $query =
            "
            select 
                value 
            from variables 
            where 
                id_language = (SELECT value FROM globalSetting WHERE code = 'lang' limit 1) and code = :code
        ";
        $stmt = $conn->prepare($query);
        $stmt->execute(['code' => $code]);
        return $stmt->fetchAll();
    }
}

Контроллер:

<?php
namespace App\Controller;
use App\Repository\VariablesRepository;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Validator\Exception\ValidatorException;
/**
 * Class VariableController
 * @package App\Controller
 */
class VariableController
{
    /**
     * @var VariablesRepository
     */
    private $variableRepo;
    /**
     * VariableController constructor.
     *
     * @param VariablesRepository $variablesRepository
     */
    public function __construct(VariablesRepository $variablesRepository)
    {
        $this->variableRepo = $variablesRepository;
    }
    /**
     * @param Request $request
     *
     * @return Response
     * @throws \Doctrine\DBAL\DBALException
     */
    public function someAction(Request $request)
    {
        $code = $request->get('code');
        if (empty($code)) {
            throw new ValidatorException('code is null');
        }
        $message = $this->variableRepo->getLanguageMessage($code);
        return new Response($message);
    }
}

Надеюсь, я объяснил понятно

READ ALSO
Как сделать чтение текста на сайте

Как сделать чтение текста на сайте

Появилась необходимость сделать на сайте чтение текста, как например google переводчикЗагружается текст, а потом по нажатии на кнопку начинает...

224
Отправка сообщения whatsapp php

Отправка сообщения whatsapp php

Подскажите, пожалуйста, рабочий способ отправить сообщение в whatsapp при помощи php не могу найти

218
mongodb вывод данных по _id

mongodb вывод данных по _id

Здравствуйте, написал скрипт для вывода новостей с базы данныхПример работы:

211
Выплаты на PayPal

Выплаты на PayPal

Подскажите как реализовать проведение выплат на PayPal

171