3

I want to be able to pass a custom object of type FormMode through a route or any other way.

My custom.routing.yml file is:

custom.page:
  path: '/custom/{model}'
  defaults:
    _controller: '\Drupal\custom\Controller\CustomController::page'
    model: ''
  requirements:
    _permission: 'administer site configuration' 

My FormModel class looks like:

class FormModel {
  public $name;
  public $area;

  function __construct($name, $area) {
    $this->name = $name;
    $this->area = $area;
  }

I create an instance of the object and use Drupal URL function like shown below:

$model = new FormModel('name', 'area');

Url::fromRoute('custom.page')->setRouteParameters(array('model' => $model));

but Drupal throws an error saying Drupal cannot convert a object to a string which I understand it cant convert object to string.

What would be the best practice to pass a object through a route or pass object created from a form into a controller? I dont want to create an entity as I would then need to update the database with the new fields.

Thanks

1 Answer 1

5

You are passing the object, but you need to pass the object ID. So you will change this:

Url::fromRoute('custom.page')->setRouteParameters(array('model' => $model));

To this:

Url::fromRoute('custom.page')->setRouteParameters(array('model' => $model->id()));

Note that your model object will need to have a public id() method that returns the ID for this to work. This will send the ID that is passed in place of {model} to the callback.

If you want the callback function (the controller) to receive a loaded object rather than just the ID, you'll need to do a few things. The first is to add options to your route:

custom.page:
  path: '/custom/{model}'
  defaults:
    _controller: '\Drupal\custom\Controller\CustomController::page'
    model: ''
  requirements:
    _permission: 'administer site configuration'
  options:
    parameters:
      model:
        type: model

Then you'll need to set up a new route in services.yml:

services:
  model:
    class: Drupal\mymodule\ParamConverter\MyModuleParamConverter
    tags:
      - { name: paramconverter }

And you'll need to create the class (Drupal\mymodule\ParamConverter\MyModuleParamConverter) that does the conversion from ID to object. This class needs to implement ParamConverterInterface:

namespace Drupal\mymodule\ParamConverter;

use Drupal\Core\ParamConverter\ParamConverterInterface;
use Symfony\Component\Routing\Route;

class MyModuleParamConverter implements ParamConverterInterface {
  public function convert($value, $definition, $name, array $defaults) {
    // Create your Model object here (not shown) then return it:
    return $model;
  }

  public function applies($definition, $name, Route $route) {
    return (!empty($definition['type']) && $definition['type'] == 'model');
  }

}

You can read more about parameter upcasting here: https://www.drupal.org/docs/8/api/routing-system/parameter-upcasting-in-routes

2
  • The problem is the object is not an entity so the data is not in the database, it is generated from form data. Is it possible? or maybe using a session variable?
    – harnamc
    Commented Jan 26, 2017 at 17:54
  • It doesn't matter how the data is generated, you still use the same method I showed above. The object is generated where I put the comment "// Create your Model object here (not shown)". I didn't show how the object is generated, it could be from the database, from files, from sessions, from external APIs, anything.
    – Jaypan
    Commented Jan 27, 2017 at 3:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.