Хорошо, прежде всего отказ от ответственности. Я работаю над своим первым проектом Sf2 и работаю над существующим проектом sf1, рефакторингом его в Sf2, чтобы понять, куда были перемещены все ящики.
Теперь происходит что-то странное, и я вырываю последние волосы.
--- TL;DR: резюме ---
Я визуализирую контроллер из шаблона ветки и передаю массив этому субконтроллеру. Одно из значений массива является объектом, но этот объект исчезает еще до того, как попадает в контроллер.
Я преследовал его в потоке Symfony2, насколько это возможно, и насколько я могу отследить, объект не поврежден. Затем я теряюсь, но где-то между Symfony\Component\HttpKernel\Fragment\InlineFragmentRenderer::render() и моим (суб)контроллером объект исчезает.
Это фича, баг или я просто схожу с ума?
--- Подробно ---
У меня есть шаблон ветки, который имеет дело с объектом объекта (назначенным переменной "коллекция" ветки), который содержит связанные объекты, такие как imageItem и linkedPageItem).
Мои объекты были настроены для расширения базового класса, который реализует ArrayAccess, поэтому я могу получить доступ к значениям, используя нотацию массива, независимо от того, гидратированы ли объекты или нет. (Следуя методологии варианта № 1, описанной здесь: http://docs.doctrine-project.org/en/latest/cookbook/implementing-arrayaccess-for-domain-objects.html).
В twig у меня есть такая строка, которая передает некоторые объекты субконтроллеру для рендеринга блока изображения. Субконтроллер renderImage управляет очисткой всего перед рендерингом собственного блока веток.
Вот код из основного файла ветки:
{# blockLinks.html.twig #}
...
{{- render(controller(
'MyBundle:Helper:renderImage',
{
'image': collection['imageItem'],
'options': {
'html_options': { 'class': 'foo' },
'link_options': { 'class': 'bar' },
'link_url': collection['item_link_url'],
'link_page': collection['linkedPageItem']
}
}
)) -}}
...
Однако субконтроллер renderImage никогда не получает значение $options['link_page'].
Это было странно, поэтому я углубился в детали. Я нашел файл PHP, в который twig преобразует blockLinks.html.twig, и углубился в него.
Там мы находим:
// /app/cache/dev/twig/01/30/lotsofnumbers.php
...
echo $this->env->getExtension('http_kernel')->renderFragment($this->env->getExtension('http_kernel')->controller(
"CaponicaFdsWebsiteBundle:Helper:renderImage",
array(
"image" => $this->getAttribute($_collection_, "imageItem", array(), "array"),
"options" => array(
"html_options" => array("class" => "foo"),
"link_options" => array("class" => "bar"),
"link_url" => $this->getAttribute($_collection_, "item_link_url", array(), "array"),
"link_page" => $this->getAttribute($_collection_, "linkedPageItem", array(), "array")
)
)
));
...
Хорошо, выглядит нормально.
Чтобы выяснить, что происходит, я сделал \Doctrine\Common\Util\Debug::dump($this->getAttribute($_collection_, "linkedPageItem", array(), "array"));, и он сообщает, что это действительно возвращает объект Page.
то есть он сообщает что-то вроде:
object(stdClass)[874]
public '__CLASS__' => string 'MyBundle\Entity\Page'
...
Начиная с скомпилированного php-файла twig в кеше
-> Symfony\Bridge\Twig\Extension\HttpKernelExtension::renderFragment()
-> Symfony\Component\HttpKernel\Fragment\FragmentHandler::render()
-> Symfony\Component\HttpKernel\Fragment\InlineFragmentRenderer::render()
На данный момент объект все еще не поврежден (что видно по дампу $subRequest->attributes->get('options') непосредственно перед вызовом $this->kernel->handle($subRequest, HttpKernelInterface::SUB_REQUEST, false); в строке 62 InlineFragmentRenderer)
Я не уверен, куда это пойдет дальше. Я думал, что он ушел в [\vendor\symfony\symfony\src]Symfony\Bundle\FrameworkBundle\HttpKernel, но я не могу отследить там какую-либо активность.
Однако, если я загляну в контроллер renderImage и выгружу такие параметры:
// MyBundle\Controller\HelperController.php
public function renderImageAction($image, $options = array()) {
print_r(\Doctrine\Common\Util\Debug::dump($options)); // I'm sure there's a 1337 way to use the logger/toolbar for this, I'll figure that out some other day
...
}
Я получаю это:
array (size=2)
'html_options' =>
array (size=1)
'class' => string 'foo' (length=3)
'link_options' =>
array (size=1)
'class' => string 'bar' (length=3)
Другими словами, объект 'link_page' был удален из опций - кажется, что-то голодное (и довольно страшное) скрывается в глубинах Symfony и поедает мои объекты!
Это особенность? (То, что вы не можете передать объект внутри массива в подзапрос... возможно, это злит сверхстрогих богов MVC?)
Или это ошибка? (Что-то ест то, чего не должно?)
Или я просто взял не тот конец палки?
Я надеюсь, что кто-нибудь может помочь, прежде чем я потеряю последние пряди волос...
C
{{-или{{в своем шаблоне ветки? - person cheesemacfly   schedule 10.04.2013{{-в показанной части (некоторые другие части шаблона не используют элемент управления пробелами) - person caponica   schedule 10.04.2013{{-вместо{{? Для чего там-? - person cheesemacfly   schedule 10.04.2013-удаляет предшествующие (или следующие) пробелы в сочетании с{{,}},{%или%}- person caponica   schedule 10.04.2013