简体   繁体   中英

Symfony advice : where to place code about an entity that needs complex database queries?

I need an advice for my Symfony 3.4 project (yes I know there is Symfony 6), I have an entity Product and I created a method that calculates the completion percentage of a Product sheet. It checks many properties of the entity and some other entities related to it (collections).

For now, I placed that method inside my Product entity and it works well. But for a specific thing, I need to do a complex query to the database and I can't use the query builder in the Entity class. So I'm wondering if I should place that code in the ProductController or maybe in the ProductRepository ?

Is it possible to use the entity object in the repository? I don't need to build queries for each check, I simply use entity getters for the most of the checks.

Then, I will show the result in several pages of my project.

My function is someting like this (simplified):

public function checkSetup()
{
    $setup = array(
        'active'    => $this->isActive(),
        'ref'       => !empty($this->ref) ? true : false,
        'tags'      => $this->tags->isEmpty() ? false : true,
    );

    // I want to add the following part :
    $qb = $em->getRepository(Product::class)->createQueryBuilder('p');
    // build complex query...
    $records = $qb->getQuery()->getResult();

    $setup['records'] = !empty($records) ? false : true;

    // Completion level
    $score = 0;
    foreach ($setup as $s) {
        if ($s) $score++;
    }

    $num = $score / count($setup) * 100;
    $setup['completion'] = round($num);

    return $setup;
}

Based on the comment of @Cerad:

Create a specific class for the checker.

<?php
// src/Checker/ProductChecker.php

namespace AppBundle\Checker;

use AppBundle\Entity\Product\Product;
use Doctrine\ORM\EntityManager;

class ProductChecker
{
    private $em;

    public function __construct(EntityManager $em)
    {
        $this->em = $em;
    }

    public function check(Product $p)
    {
        // code...

        $result = $this->em->getRepository(Product::class)->customQuery($p->getId());

        // code...
    }
}

Register ProductChecker as a service and inject EntityManager for using ProductRepository in ProductChecker .

# app/config/services.yml

app.product_checker:
   public: true
   class:      AppBundle\Checker\ProductChecker
   arguments:  ["@doctrine.orm.entity_manager"]

Write the complex query in ProductRepository.

Then, call the checker in the Controller:

$checker = $this->get("app.product_checker");
$report = $checker->check($product);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM