2

ページに3つ表示する必要がある友達のリストがあります。各友達にはカテゴリがあり、選択したカテゴリの友達のみを表示するように選択するドロップダウン メニューもあります。また、1 ページに 3 つ表示する必要があります。フィルタリングされた友人とフィルタリングされていない友人の表示方法は同じなので、コントローラーに2つのほぼアクションと2つの同一のテンプレートを入れたくなかったので、1つのコントローラーのアクションとテンプレートでこれを作成しようとしましたが、問題。フィルタリングされた友達の 2 ページ目以降のページネーションができません。助けてください!:(問題は、フォームを使用していて、2番目のページをクリックすると、フォームに入力されバインドされた変数が未定義になることです。コードは次のとおりです。

  1. コントローラーのアクション

    public function displayAction($page, Request $request)
    {
        $em = $this->getDoctrine()->getEntityManager();
        $user = $this->get('security.context')->getToken()->getUser();
    
        $cat = new Category();
    
        $dd_form = $this->createForm(new ChooseCatType($user->getId()), $cat);
    
        if($request->get('_route')=='filter')
        {
            if($request->getMethod() == 'POST')
            {
    
                $dd_form->bindRequest($request);
    
                if($cat->getName() == null)
                {      
                    return $this->redirect($this->generateUrl('home_display'));
                }
    
                $filter = $cat->getName()->getId();
                if ($dd_form->isValid())
                {   
                    $all_friends = $em->getRepository('EMMyFriendsBundle:Friend')
                                      ->filterFriends($filter);
                    $result = count($all_friends);
                    $FR_PER_PAGE = 3;
                    $pages = $result/$FR_PER_PAGE;
                    $friends = $em->getRepository('EMMyFriendsBundle:Friend')
                                  ->getFilteredFriendsFromTo($filter, $FR_PER_PAGE, ($page-1)*$FR_PER_PAGE); 
    
                    $link = 'filter';
                }
            }
        }
    
        else
        {
            $all_friends = $user->getFriends();
    
            $result = count($all_friends);
            $FR_PER_PAGE = 3;
            $pages = $result/$FR_PER_PAGE;
    
            $friends = $em->getRepository('EMMyFriendsBundle:Friend')
                          ->getFriendsFromTo($user->getId(), $FR_PER_PAGE, ($page-1)*$FR_PER_PAGE); 
    
            $link = 'home_display';
        }
    
        // Birthdays
        $birthdays = null;
        $now = new \DateTime();
        $now_day = $now->format('d');
        $now_month = $now->format('m');
    
        foreach ($all_friends as $fr)
        {
            if($fr->getBirthday() != null)
            {    
                if($fr->getBirthday()->format('d') == $now_day && $fr->getBirthday()->format('m') == $now_month)
                {
                    $birthdays[]=$fr;
                    $fr->setYears();
                }
            }
        }
    
        // Search
        $search = new Search();
        $s_form = $this->createFormBuilder($search)
            ->add('words', 'text', array(
            'label' => 'Search: ',
            'error_bubbling' => true))
            ->getForm();
    
    
        // Renders the template
        return $this->render('EMMyFriendsBundle:Home:home.html.twig', array(
            'name' => $name, 'friends' => $friends, 'user' => $user, 'birthdays' => $birthdays, 'pages' => $pages, 'page' => $page, 'link' => $link,
            'dd_form' => $dd_form->createView(), 's_form' => $s_form->createView()));
    }
    
  2. テンプレート

    {% if birthdays != null %}
            <div>
    
                <img class="birthday" src="http://www.clker.com/cliparts/1/d/a/6/11970917161615154558carlitos_Balloons.svg.med.png">
    
                <div class="try"> 
                    This friends have birthday today: 
                    {% for bd in birthdays %}
    
                        <p>
                            <a href="{{ path('friend_id', {'id': bd.id}) }}">{{ bd.name }}</a>
                            <span class="years">
                                ({{ bd.years }} years)
                            </span>
                        </p>
    
                    {% endfor %}
                </div>
    
            </div>
        {% endif %}
    
        {% for fr in friends %}
    
            {# TODO: Fix where are shown #}
    
            {% if fr.getWebPath()!=null %}
                <a href="{{ path('friend_id', {'id': fr.id}) }}">
                    <img class="avatar" src="{{ fr.getWebPath }}">
                </a>
            {% endif %}
    
            {% if loop.index is odd %}
                    <p class="list1">
                {% else %}
                    <p class="list2">
            {% endif %}
                        <a class="friends" href="{{ path('friend_id', {'id': fr.id}) }}">{{ fr.name }}</a>
                    </p>
    
        {% endfor %}
    
        {# TODO: Pagination #}
        {% if pages>1 %}
        <p>
        {% for i in 0..pages %}
    
                {% if page == loop.index %}
                <span class="pagination">{{ loop.index }}</span>
    
                {% else %}
                <span class="pagination"><a  href="{{ path(link, {'page': loop.index}) }}">{{ loop.index }}</a></span>
                {% endif %}
    
        {% endfor %}
        </P>
        {% endif %}
    
        <p>Choose category:</p>   
        <form class="search" action="{{ path('filter') }}" method="post" {{ form_enctype(s_form) }}> 
            {{ form_widget(dd_form.name) }}
            {{ form_rest(dd_form) }}
            <input type="submit" value="Show friends" />
        </form>
    
  3. リポジトリ

    クラス FriendRepository は EntityRepository を拡張します
    {
        パブリック関数 getFriendsFromTo ($user、$limit、$offset)
        {
             $this->getEntityManager() を返す
                ->createQuery('SELECT f FROM EMMyFriendsBundle:Friend f WHERE f.user='.$user.'ORDER BY f.name ASC')
                ->setMaxResults($limit)
                ->setFirstResult($offset)
                ->getResult();
        }
    パブリック関数 filterFriends ($filter)
        {
            $q = $this->createQueryBuilder('f');

        $q->select('f')
          ->where('f.category = :filter')            
          ->setParameter('filter', $filter);
    
        return $q->getQuery()->getResult();
    }
    
    public function getFilteredFriendsFromTo ($filter, $limit, $offset)
    {
        $q = $this->createQueryBuilder('f');
    
        $q->select('f')
          ->where('f.category = :filter')
                ->setMaxResults($limit)
            ->setFirstResult($offset)
          ->setParameter('filter', $filter);
    
        return $q->getQuery()->getResult();
    }
    }
    

いろいろ試しましたが、いつも問題があります。このコードでは$all_friends、誕生日の for ループ内の変数が定義されていないことが示されています - はい、定義されていません。たぶん、セッションに保存する必要があり、これを試しました:

    $session = $this->getRequest()->getSession();

    $session->set('all_friends');

次にforループに渡し$friends=$session->get('all_friends');ますが、機能せず、変数$all_friendsが大きすぎて保存できませんか?

どんなアイデアも高く評価されます!お時間とご尽力いただきありがとうございます。


編集

セッションで道を使うと

    $session = $this->getRequest()->getSession();

    $session->set('all_friends');

    $fri=$session->get('all_friends');

    foreach ($fri as $fr)
    { .... }

私が得るエラーは

Warning: Invalid argument supplied for foreach() in C:\xampp\htdocs\MyFriends\src\EM\MyFriendsBundle\Controller\HomeController.php line 100

そしてまた

Warning: Missing argument 2 for Symfony\Component\HttpFoundation\Session::set(), called in C:\xampp\htdocs\MyFriends\src\EM\MyFriendsBundle\Controller\HomeController.php on line 71 and defined in C:\xampp\htdocs\MyFriends\app\cache\dev\classes.php line 148

セッションを使用しないと、

Notice: Undefined variable: all_friends in C:\xampp\htdocs\MyFriends\src\EM\MyFriendsBundle\Controller\HomeController.php line 100

友達を表示するカテゴリを選択し、その 2 番目のページをクリックしたとき。

PSエラーの行は、貼り付けたコードの行に対応していません。アクション、リポジトリ、およびテンプレートの一部をスキップしたためです。これらはこの問題には関係なく、正しく機能するためです。誰かが望むなら、私は彼に送るか、ここですべてのコードを更新できます。

4

1 に答える 1

1

あなたはセッションに何も設定していません:

$session->set('all_friends');

代わりにこれを行う必要があります:

$session->set('all_friends', $data);

Symfony2 のコーディング標準も尊重し始める必要があります。

あなたのコードを読もうとすると、目が溶けてしまいます。これを読んで、コントローラーでフォームを作成する代わりにフォームクラスを作成することを忘れないでください。

編集: $data が Doctrine2 クエリの結果である場合は、後で必要なときに取得できるように、entity idとのみを保存することをお勧めします。entity class

EDIT2:セッションフィルターデータの保存に役立つコードを次に示します。PS、不足しているものを追加することを忘れないでくださいuse ....

/**
 * Set filters
 *
 * @param array  $filters Filters
 * @param string $type    Type
 */
public function setFilters($name, array $filters = array())
{
    foreach ($filters as $key => $value) {
        // Transform entities objects into a pair of class/id
        if (is_object($value)) {
            if ($value instanceof ArrayCollection) {
                if (count($value)) {
                    $filters[$key] = array(
                        'class' => get_class($value->first()),
                        'ids' => array()
                    );
                    foreach ($value as $v) {
                        $identifier = $this->getDoctrine()->getManager()->getUnitOfWork()->getEntityIdentifier($v);
                        $filters[$key]['ids'][] = $identifier['id'];
                    }
                } else {
                    unset($filters[$key]);
                }
            } elseif (!$value instanceof \DateTime) {
                $filters[$key] = array(
                    'class' => get_class($value),
                    'id'    => $this->getDoctrine()->getManager()->getUnitOfWork()->getEntityIdentifier($value)
                );
            }
        }
    }

    $this->getRequest()->getSession()->set(
        $name,
        $filters
    );
}

/**
 * Get Filters
 *
 * @param array $filters Filters
 * @param type  $type    Type
 *
 * @return array
 */
public function getFilters($name, array $filters = array())
{
    $filters = array_merge(
        $this->getRequest()->getSession()->get(
            $name,
            array()
        ),
        $filters
    );

    foreach ($filters as $key => $value) {
        // Get entities from pair of class/id
        if (is_array($value) && isset($value['class'])) {
            if (isset($value['id'])) {
                $filters[$key] = $this->getDoctrine()->getManager()->find($value['class'], $value['id']);
            } elseif (isset($value['ids'])) {
                $data = $this->getDoctrine()->getManager()->getRepository($value['class'])->findBy(array('id' => $value['ids']));
                $filters[$key] = new ArrayCollection($data);
            }
        }
    }

    return $filters;
}

EDIT3:ページネーションにKnpPaginatorBundleを使用していないのはなぜですか?

于 2013-05-03T14:09:55.833 に答える