Reputation: 11
I'm new to PHP programing and Symfony. English isn't my native language so sorry if it sounds strange how I write...
I have two entities: Article and Category, where each Article has a Category. And I need to show how many articles I have for a given category:
Category ------------------ N°
Vehicles -------------------- 4
Electronics ---------------- 20
Food ----------------------- 15
Furniture ------------------ 8
With Doctrine I've made the CRUD files for both entities.
php app/console doctrine:generate:crud
Like I said, the problem is that I want to show a table with properties of a Category (name, description, etc) and how many articles of it are in the inventory.
The SQL query is very simple:
SELECT count(*) FROM Articles a WHERE a.id_category = $id_category
Where to put that?! I'm very confused and don't want to brake best practice rules. Doctrine generated lots of files: ArticleController.php, ArticleType.php (Form), and all the .twig for the views. Same for Category.
Upvotes: 0
Views: 1710
Reputation: 1575
In the spirit of giving a direct answer to your question: what you need is a custom Doctrine Repository, in this case an ArticleRepository
.
e.g. ArticleRepository.php
namespace ACME\DemoBundle\Article;
use Doctrine\ORM\EntityRepository;
class ArticleRepository extends EntityRepository
{
public function countForCategory($id)
{
$result= $this->createQueryBuilder('a')
->join('a.category', 'c')
->where('c.category_id = :id')
->setParameter('id', $id)
->select('count(a')
->getQuery()
->getSingleScalarResult();
return $result;
}
}
And then you set your Article entity to use that ArticleRepository
Article.php
/**
* @ORM\Entity
* @ORM\Table(name="article")
* @ORM\Entity(repositoryClass="ACME\DemoBundle\Entity\ArticleRepository")
*/
class Article
{
/// etc...
You can then get the Repository for the Entity in e.g. your Controller (although as suggested elsewhere you can hide this away in some kind of service to avoid filling your Controller with business logic; it just needs to be reachable somehow from inside your Controller), and run the query:
ArticleController
class ArticleController extends Controller
{
public function countAction($id)
{
$articleRepo = $this->getDoctrine()->getRepository('DemoBundle:Article');
$count = $articleRepo->countForCategory();
//etc...
NB If you really want exactly the output in your example, it may be more efficient to do one query for the whole table, probably in a CategoryRepository, performing a count and grouping by Category. The query would return an array containing Category name and count.
Upvotes: 2
Reputation: 13107
When using Symfony2 + Doctrine2,
don't think (so much) about the database. Think of persistent data objects, so called entities, and let Doctrine handle them. Spend some time on cleanly defining the relations between those objects, though.
forget about the term “MVC”. MVC is a rather abstract concept, things are more complex in reality. Fabian (lead dev of SF) has a nice write-up about this topic: http://fabien.potencier.org/article/49/what-is-symfony2
If you wonder where to put what in your Symfony bundles, read this Cookbook article: http://symfony.com/doc/current/cookbook/bundles/best_practices.html
Upvotes: 1
Reputation: 12063
Create a CategoryManager class in your service layer, and handle any business logic there. You can pass the router to it through dependency injection.
For your example, CategoryManager would have a getUrl(Article $article) method which would use the router instance (that you either injected through __construct or a separate setter method) to generate the Url based on properties of $article, and return it.
This method will ensure that your business logic doesn't pollute the view or controller layers.
Check this link Services Symfony
Upvotes: 0