Static call on a twig filter

2019-08-06 23:46发布

I'm trying to get a twig filter that would sort entities by score. My City class got a score attribute with getters and setters, and I created this extension :

<?php

namespace AOFVH\HomepageBundle\Twig;
use Twig_Extension, Twig_SimpleFilter, Twig_Environment;

class ScoreExtension extends \Twig_Extension
{
public function getFilters()
{
    return array(
        $filter = new Twig_SimpleFilter('score', array('AOFVH\FlyBundle\Entity\City', 'getScore'))
    );
}

public function getName()
{
    return 'score_extension';
}
}

which I call like this :

        {% for cit in cities|score %}
      <a href="{{ path('aofvh_city', {'name': cit.name}) }}">
        <div class="col-lg-4 col-md-12" style="margin-bottom:10px;">
        <img src="{{ asset('Cities/'~cit.name~'.png') }}" class="img" alt="Cinque Terre" width="300" height="300">
        <h2>{{cit.name}}</h2>
        </div>
      </a>

        {% endfor %}

But for some reason, I cannot get it rendered, instead I git this error

 ContextErrorException: Runtime Notice: call_user_func_array() expects parameter 1 to be a valid callback, non-static method AOFVH\FlyBundle\Entity\City::getScore() should not be called statically 

Did I miss something ?

2条回答
兄弟一词,经得起流年.
2楼-- · 2019-08-07 00:21

The second argument of Twig_SimpleFilter's constructor requires a callable.

If you pass it a class name and a method name, it will call that method of that class statically:

array('SomeClass', 'someMethod')

If you, instead, pass it an instance of a class and a method name, it will call that method inside the object:

array($this->someInstance, 'someMethod')

This means that you either make getScore() static or you create an instance of City and use that (maybe get it using Dependency Injection).

查看更多
一纸荒年 Trace。
3楼-- · 2019-08-07 00:39

You will have to do something like this, using the actual variable beeing filtered. Here, I guess that cities is a Collection :

class ScoreExtension extends \Twig_Extension
{

    public function getFilters()
    {
        return array(
            $filter = new Twig_SimpleFilter('score', array($this, 'getCityScore'))
        );
    }

    public function getCityScore($cities)
    {
        $scores = array();

        foreach ($cities as $city) {
            $scores[] = $city->getScore();
        }

        return $scores;
    }

    public function getName()
    {
        return 'score_extension';
    }

}
查看更多
登录 后发表回答