2014-03-31 41 views
1

我在我的控制器中使用了一個搜索代碼和分頁代碼,不用說它通過重複代碼是不好的編碼習慣。這就是說Symfony2中的最佳做法是爲了避免在我的所有控制器中重複使用代碼?Symfony2 - 重構代碼/方法的最佳實踐?

如何在代碼重新分解後訪問代碼?

控制器

// Search code 
    $results = null; 
    $query = $request->query->get('q'); 

    if (!empty($query)) { 
     $em = $this->getDoctrine()->getManager(); 

     $results = $em->createQueryBuilder() 
      ->from('AcmeDemoBundle:Blog', 'b') 
      ->select('b') 
      ->where('b.title LIKE :search') 
      ->setParameter(':search', "%${query}%") 
      ->getQuery() 
      ->getResult(); 
    } 


    // Pagination code 
    $page = $request->get('page'); 

    $count_per_page = 5; 
    $total_count = $this->getTotalBlogs(); 
    $total_pages = ceil($total_count/$count_per_page); 

    if (!is_numeric($page)) { 
     $page = 1; 
    } else { 
     $page = floor($page); 
    } 

    if ($total_count <= $count_per_page) { 
     $page = 1; 
    } 

    if (($page * $count_per_page) > $total_count) { 
     $page = $total_pages; 
    } 

    $offset = 0; 

    if ($page > 1) { 
     $offset = $count_per_page * ($page - 1); 
    } 

    $em = $this->getDoctrine()->getManager(); 

    $blogQuery = $em->createQueryBuilder() 
     ->select('b') 
     ->from('AcmeDemoBundle:Blog', 'b') 
     ->addOrderBy('b.created', 'DESC') 
     ->setFirstResult($offset) 
     ->setMaxResults($count_per_page); 

    $blogFinalQuery = $blogQuery->getQuery(); 

    $blogPage = $blogFinalQuery->getArrayResult(); 

    foreach ($blogPage as $blog) { 
     $blog_id = $blog['id']; 
     $commentRepository = $this->getDoctrine() 
      ->getRepository('AcmeDemoBundle:Comment'); 

     $comments[] = $commentRepository->findByBlog($blog_id); 
    } 

//退出(\原則\ COMMON \的Util \調試::轉儲($評論));

return $this->render('AcmeDemoBundlBundle:Default:index.html.twig', array(
     'blogPage'  => $blogPage, 
     'total_pages' => $total_pages, 
     'current_page' => $page, 
     'comments'  => $comments, 
     'query'  => $query, 
     'results'  => $results, 

    )); 
+0

With services;) –

+0

實體存儲庫和此包的組合:https://github.com/KnpLabs/KnpPaginatorBundle應該是一個好的開始。 –

回答

1

首先,您可以將所有自定義查詢置於custom repository classes。我懷疑這將覆蓋你在這種情況下需要的所有重用。

例如,在AcmeDemoBundle創建BlogRepository類:庫和註釋博客實體類如下定義它的倉儲類:

/** 
* @ORM\Entity(repositoryClass="Acme\DemoBundle\Repository\BlogRepository") 
*/ 

然後方法添加到庫中對於用於所需的每個自定義查詢,軸承請記住這些存儲庫方法通常被命名的方式。它看起來好像在控制器方法getTotalBlogs()也可能是在BogRepository例如一個方法:

public function findFiltered($page, $count_per_page = 5, $filterText = '') 
    { 
     $total_count = $this->findTotal(); 
     // Code to initialise page and offset here 

     $queryBuilder = $this->createQueryBuilder('blog'); 
     $queryBuilder->... 
     ... 
    } 

注意上面的方法可以使用,如果沒有$ filterText被傳遞到讓所有的博客你只想需要的東西是這樣的:

if (!empty($filterText)) 
    { 
     queryBuilder->where('b.title LIKE :search') 
        ->setParameter(':search', "%${query}%") 
    } 

然後,CommentRepository可以用一種方法來創建找到一組給定的博客(ID)■所有的評論。注意,你可以使用SQL「IN」子句,以獲得使用單個查詢的所有意見:

$commentQuery = $em->createQueryBuilder() 
         ->select('comment') 
         ->from('AcmeDemoBundle:Comment', 'comment') 
         ->where('comment.blog IN (:ids)') 
         ->setParameter('ids', $blogIds); 

除了自定義庫類我使用管理服務(如BlogManager)封裝業務流程。我的控制器主要使用管理器,而不是直接使用存儲庫,但它取決於功能。

我有點困惑,你有一個總體結果查詢,它只返回標題像搜索文本一樣的博客,而分頁查詢返回(頁面)所有博客。這可能只是一個因爲你的代碼正在進行?

+0

是的,它仍然是WIP代碼。您對整體結果查詢有什麼建議? – webdev