2

I need help about a specific implementation in Drupal 8.

I have been trying for two days to create a view programmatically, or more precisely to create a new display of an existing view.

The objective is to create (at the same time as creating new content) a duplicate display of a view, which is almost the same than the original, with just the title and a condition in filter criteria (a node id) changed, in order that the final user never needs to add display or modify the view.

The issue that I am coming up against is that the generated view's display lost an important property, the “This block (override)” parameter is replaced by the default state “All displays (excepts overridden)” so once I have generated the second view’s display programmatically, the first view’s display has its properties (title, filter criteria) replaced inevitably by the values of the second.

So I would like to programmatically set the parameter “All displays (excepts overridden)” at “This block (override)” but I haven’t found anything of relevance in the D8 API.

Thank you in advance for any ideas or suggestions.

enter image description here

function HOOK_node_insert(Drupal\Core\Entity\EntityInterface $node) {

if ($node->type->target_id == "SPECIFIC_CONTENT_TYPE") {

    $node_title = $node->getTitle();
    $node_id = $node->id();
    $machine_title = strtolower(str_replace(" ","_",$node_title));
    $block_id = 'block_'.$machine_title;

    $view = Views::getView("api_domain");//"api_domain" is the view's machine name
    if (empty($view)) {
        return;
    }
    $display_id = 'default';
    if (!$view->access($display_id)) {
        return;
    }

    $view->newDisplay('block',$node_title, $block_id);
    $options_array = array(
        'id' => 'field_api_domain_target_id',
        'table' => 'node__field_api_domain',
        'field' => 'field_api_domain_target_id',
        'relationship' => 'none',
        'group_type' => 'group',
        'admin_label' => '',
        'operator' => '=', 'value' =>  array('value' => $node_id));

    $view->setHandler($display_id, 'filter', 'field_api_domain_target_id', $options_array);//works
    //$view->setTitle($node_title);//doesn't works
    $view->display_handler->setOption('title', $node_title);// works
    //$view->display_handler->overrideOption('title', $node_title);// works too, but the "override" problem still persists
    $view->save();
}

}

1 Answer 1

0

If you can't find a way to do this with the methods of Views API, you can try another approach by using the view entity (storage), which provides a more direct access to the display settings in an array.

Example

$view = \Drupal\views\Views::getView('myview');
$storage = $view->storage;
// add a new display
$storage->addDisplay('block', $new_title, $block_id);
// get the new display by reference
$new_display = &$storage->getDisplay($block_id);
// copy the configuration and change the filter settings
$old_display = $storage->getDisplay($old_display_id);
$new_display = array_replace_recursive($old_display, $new_display);
$new_display['display_options']['filters']['nid']['value']['value'] = 123;

$storage->save();
1
  • My problem is solved with your approach. Thank you very much ! Jan 17, 2017 at 10:41

Your Answer

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

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