Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

fix javascripts and stylesheets when using cache backend

  • Loading branch information...
commit aac1856930625d174842f4193b533e3737d143dd 1 parent 922c460
@rande rande authored
View
74 Templating/Helper/BlockHelper.php
@@ -18,6 +18,7 @@
use Sonata\BlockBundle\Model\BlockInterface;
use Sonata\BlockBundle\Block\BlockRendererInterface;
+use Sonata\BlockBundle\Util\RecursiveBlockIterator;
use Sonata\CacheBundle\Cache\CacheManagerInterface;
use Symfony\Component\Templating\Helper\Helper;
use Symfony\Component\HttpFoundation\Response;
@@ -38,6 +39,14 @@ class BlockHelper extends Helper
private $cacheHandler;
/**
+ * This property is a state variable holdings all assets used by the block for the current PHP request
+ * It is used to correctly render the javascripts and stylesheets tags on the main layout
+ *
+ * @var array
+ */
+ private $assets;
+
+ /**
* @param BlockServiceManagerInterface $blockServiceManager
* @param array $cacheBlocks
* @param BlockRendererInterface $blockRenderer
@@ -53,6 +62,11 @@ public function __construct(BlockServiceManagerInterface $blockServiceManager, a
$this->cacheManager = $cacheManager;
$this->blockContextManager = $blockContextManager;
$this->cacheHandler = $cacheHandler;
+
+ $this->assets = array(
+ 'js' => array(),
+ 'css' => array()
+ );
}
public function getName()
@@ -67,18 +81,8 @@ public function getName()
*/
public function includeJavascripts($media)
{
- $javascripts = array();
-
- foreach ($this->blockServiceManager->getLoadedServices() as $service) {
- $javascripts = array_merge($javascripts, $service->getJavascripts($media));
- }
-
- if (count($javascripts) == 0) {
- return '';
- }
-
$html = "";
- foreach ($javascripts as $javascript) {
+ foreach ($this->assets['js'] as $javascript) {
$html .= "\n" . sprintf('<script src="%s" type="text/javascript"></script>', $javascript);
}
@@ -92,19 +96,9 @@ public function includeJavascripts($media)
*/
public function includeStylesheets($media)
{
- $stylesheets = array();
-
- foreach ($this->blockServiceManager->getLoadedServices() as $service) {
- $stylesheets = array_merge($stylesheets, $service->getStylesheets($media));
- }
-
- if (count($stylesheets) == 0) {
- return '';
- }
-
$html = sprintf("<style type='text/css' media='%s'>", $media);
- foreach ($stylesheets as $stylesheet) {
+ foreach ($this->assets['css'] as $stylesheet) {
$html .= "\n" . sprintf('@import url(%s);', $stylesheet, $media);
}
@@ -114,6 +108,36 @@ public function includeStylesheets($media)
}
/**
+ * Traverse the parent block and its children to retrieve the correct list css and javascript only for main block
+ *
+ * @param BlockContextInterface $blockContext
+ */
+ protected function computeAssets(BlockContextInterface $blockContext)
+ {
+ if ($blockContext->getBlock()->hasParent()) {
+ return;
+ }
+
+ $service = $this->blockServiceManager->get($blockContext->getBlock());
+
+ $this->assets = array(
+ 'js' => array_unique(array_merge($service->getJavascripts('all'), $this->assets['js'])),
+ 'css' => array_unique(array_merge($service->getStylesheets('all'), $this->assets['css'])),
+ );
+
+ if ($blockContext->getBlock()->hasChildren()) {
+ $iterator = new \RecursiveIteratorIterator(new RecursiveBlockIterator($blockContext->getBlock()->getChildren()));
+
+ foreach ($iterator as $block) {
+ $this->assets = array(
+ 'js' => array_unique(array_merge($this->blockServiceManager->get($block)->getJavascripts('all'), $this->assets['js'])),
+ 'css' => array_unique(array_merge($this->blockServiceManager->get($block)->getStylesheets('all'), $this->assets['css'])),
+ );
+ }
+ }
+ }
+
+ /**
* @param mixed $block
* @param array $options
*
@@ -127,13 +151,17 @@ public function render($block, array $options = array())
return '';
}
+ $service = $this->blockServiceManager->get($blockContext->getBlock());
+
+ $this->computeAssets($blockContext);
+
$useCache = $blockContext->getSetting('use_cache');
$cacheKeys = $response = false;
$cacheService = $useCache ? $this->getCacheService($blockContext->getBlock()) : false;
if ($cacheService) {
$cacheKeys = array_merge(
- $this->blockServiceManager->get($blockContext->getBlock())->getCacheKeys($blockContext->getBlock()),
+ $service->getCacheKeys($blockContext->getBlock()),
$blockContext->getSetting('extra_cache_keys')
);
View
51 Tests/Util/RecursiveBlockIteratorIteratorTest.php
@@ -0,0 +1,51 @@
+<?php
+/*
+ * This file is part of the Sonata package.
+ *
+ * (c) Thomas Rabaix <thomas.rabaix@sonata-project.org>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Sonata\BlockBundle\Tests\Entity;
+
+use Sonata\BlockBundle\Util\RecursiveBlockIteratorIterator;
+
+/**
+ *
+ */
+class RecursiveBlockIteratorIteratorTest extends \PHPUnit_Framework_TestCase
+{
+ public function testInterface()
+ {
+ $block2 = $this->getMock('Sonata\BlockBundle\Model\BlockInterface');
+ $block2->expects($this->any())->method('getType')->will($this->returnValue('block2'));
+ $block2->expects($this->once())->method('hasChildren')->will($this->returnValue(false));
+
+ $block3 = $this->getMock('Sonata\BlockBundle\Model\BlockInterface');
+ $block3->expects($this->any())->method('getType')->will($this->returnValue('block3'));
+ $block3->expects($this->once())->method('hasChildren')->will($this->returnValue(false));
+
+ $block1 = $this->getMock('Sonata\BlockBundle\Model\BlockInterface');
+ $block1->expects($this->any())->method('getType')->will($this->returnValue('block1'));
+ $block1->expects($this->once())->method('hasChildren')->will($this->returnValue(true));
+ $block1->expects($this->any())->method('getChildren')->will($this->returnValue(array(
+ $block2,
+ $block3
+ )));
+
+ $block4 = $this->getMock('Sonata\BlockBundle\Model\BlockInterface');
+ $block4->expects($this->any())->method('getType')->will($this->returnValue('block4'));
+ $block4->expects($this->any())->method('hasChildren')->will($this->returnValue(false));
+
+ $i = new RecursiveBlockIteratorIterator(array($block1, $block4));
+
+ $blocks = array();
+ foreach ($i as $block) {
+ $blocks[] = $block;
+ }
+
+ $this->assertCount(4, $blocks);
+ }
+}
View
47 Util/RecursiveBlockIterator.php
@@ -0,0 +1,47 @@
+<?php
+/*
+ * This file is part of the Sonata project.
+ *
+ * (c) Thomas Rabaix <thomas.rabaix@sonata-project.org>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Sonata\BlockBundle\Util;
+
+/**
+ * RecursiveBlockIterator
+ *
+ * @author Thomas Rabaix <thomas.rabaix@sonata-project.org>
+ */
+class RecursiveBlockIterator extends \RecursiveArrayIterator implements \RecursiveIterator
+{
+ /**
+ * @param array $array
+ */
+ public function __construct($array)
+ {
+ if (is_object($array)) {
+ $array = $array->toArray();
+ }
+
+ parent::__construct($array);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getChildren()
+ {
+ return new self($this->current()->getChildren());
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function hasChildren()
+ {
+ return $this->current()->hasChildren();
+ }
+}
View
27 Util/RecursiveBlockIteratorIterator.php
@@ -0,0 +1,27 @@
+<?php
+/*
+ * This file is part of the Sonata project.
+ *
+ * (c) Thomas Rabaix <thomas.rabaix@sonata-project.org>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Sonata\BlockBundle\Util;
+
+/**
+ * RecursiveBlockIteratorIterator
+ *
+ * @author Thomas Rabaix <thomas.rabaix@sonata-project.org>
+ */
+class RecursiveBlockIteratorIterator extends \RecursiveIteratorIterator
+{
+ /**
+ * @param \Traversable $array
+ */
+ public function __construct($array)
+ {
+ parent::__construct(new RecursiveBlockIterator($array), \RecursiveIteratorIterator::SELF_FIRST);
+ }
+}
Please sign in to comment.
Something went wrong with that request. Please try again.