4

I am trying to get to grips with Drupal 8s layout and and architecture.

Having worked with Drupal 6 for the last 2 years I have become used to its procedural style, so I am finding the OOP approach takes a little getting used to.

This is what Im trying to achieve.

My Module has a block which displays content The content of that block is refreshed every 5 seconds This is done with an Ajax call to the server which overwrites the content of the block with the freshly acquired Ajax HTML

So I have gotten the block to display my content on the page easily enough. My problem is now how do I get to the content to refresh. The logic for building the content is contained in functions in my Block class.

I have tried to set up a route in my .yml file to call these functions again to refresh my content via ajax, but I get fatal errors, and also it does not feel like the right approach to access my block class. I feel I should be routing to the controller.

but then, how do I get at the functions that I have written to build the content for the block in the first place?

Should I have written all my logic in my Controller? and if so, how do I access it from my block?

UPDATE

Attempting the solution suggested by Daniel Wehner below I receive the following error:

    Call to undefined method Drupal\livequotes\Controller\LivequotesController::getEntityManager() 
in <b>C:\Work\excel-8\modules\livequotes\lib\Drupal\livequotes\Controller\LivequotesController.php

I guess this is because I need to extend my controller or to implement the class that defines getEntityManager()

any ideas on how to do this?

UPDATE 2

Following on the suggestion in comments from Daniel Wehners answer I have attempted to use dependency injection to give access to EntityManager from my controller.

This is the code for my controller:

    namespace Drupal\livequotes\Controller;

    class LivequotesController{

    protected $entity;

    public function __construct(EntityManager $em) {
        $this->entity = $em;
    }
    /**
     * Re-render a specific block (yeah if we do something it should be generic).
     */
    public function livequotesShowBlock() 
    {
        $block = $this->entity->getStorage('block')->load($block_id);
        return $this->entity->getViewBuilder('block')->view($block);
    }
}

The following error is received when I try and access function livequotesShowBlock() from my ajax call:

Recoverable fatal error: Argument 1 passed to Drupal\livequotes\Controller\LivequotesController::__construct() must be an instance of Drupal\livequotes\Controller\EntityManager, none given

UPDATE 3

Following the link to an example of Dependency injection into a Controller class, drupal.org/node/2168121 provided by Daniel Wehners comment in his answer my Controller now looks like this:

namespace Drupal\livequotes\Controller;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Controller\ControllerBase;

/**
 * Controller routines for livequotes routes.
 */

class LivequotesController extends ControllerBase{

    protected $entity;

    public function create(Container $container) 
    {
        return new static($container->get('entity'));
    }

    public function __construct(EntityInterface $em) {
        $this->entity = $em;
    }

    public function livequotesShowBlock() 
    {
        $block_id = "livequotes_content";
        $block = $this->entity->getStorage('block')->load($block_id);
        return $this->entity->getViewBuilder('block')->view($block);
    }
}

Unfortunately though, I am now getting the following error:

Fatal error: Cannot make static method Drupal\Core\Controller\ControllerBase::create() non static in class Drupal\livequotes\Controller\LivequotesController in C:\Work\excel-8\modules\livequotes\lib\Drupal\livequotes\Controller\LivequotesController.php on line 16

UPDATE 4

Changing the signature to static

    namespace Drupal\livequotes\Controller;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Controller\ControllerBase;

/**
 * Controller routines for livequotes routes.
 */

class LivequotesController extends ControllerBase{

    protected $entity;

    public static function create(Container $container) {
        return new static($container->get('entity'));
    }

    public function __construct(EntityInterface $em) {
        $this->entity = $em;
    }
    /**
     * Re-render a specific block (yeah if we do something it should be generic).
     */
    public function livequotesShowBlock() 
    {
        $block_id = "livequotes_content";
        $block = $this->entity->getStorage('block')->load($block_id);
        return $this->entity->getViewBuilder('block')->view($block);
    }
}

results in the following error:

Declaration of Drupal\livequotes\Controller\LivequotesController::create() must be compatible with Drupal\Core\DependencyInjection\ContainerInjectionInterface::create(Symfony\Component\DependencyInjection\ContainerInterface $container)

1

The proper way is probably to re-render the block in your controller:

<?php
class ExampleController extends ControllerBase {

  /**
   * Re-render a specific block (yeah if we do something it should be generic).
   */
  public function renderBlock($block_id) {
     $block = $this->getEntityManager()->getStorage('block')->load($block_id);
     return $this->getEntityManager()->getViewBuilder('block')->view($block);
  }

}
  • This looks very promising. Seems like what I need to do to access block via my controller. Please see the update in my question that shows the results of attempting your approach – Kevin Bradshaw Apr 18 '14 at 18:16
  • In this case you don't extend the COntrollerBase class ... in that case you can also inject the entity manager directly – Daniel Wehner Apr 18 '14 at 21:26
  • Ive tried to use DI for my EntityManager, but with little success. Update 2 above shows the error I received. – Kevin Bradshaw Apr 19 '14 at 10:28
  • drupal.org/node/2168121 shows an example – Daniel Wehner Apr 20 '14 at 12:11
  • 1
    Still not getting it I'm afraid. I've updated my answer to show where I'm at but I can't seem to get any further. – Kevin Bradshaw Apr 21 '14 at 19:19

This site is temporarily in read only mode and not accepting new answers.

Not the answer you're looking for? Browse other questions tagged .