Программно создать ноду

Главные вкладки

Аватар пользователя alexboy alexboy 23 марта 2016 в 21:51

Создаю программно ноду через модуль, в котором пишу такой код:

<?php
use Drupal\node\Entity\Node;
use 
Symfony\Component\HttpFoundation\Request;
use 
Symfony\Component\HttpFoundation\Response;
use 
Symfony\Component\HttpFoundation\RequestStack;
use 
Symfony\Component\Routing\RequestContext as SymfonyRequestContext;
$node Node::create(array(
    
'type' => 'forum',
    
'title' => 'My title',
    
'langcode' => 'ru',
    
'uid' => '1',
    
'status' => 1,
    
'taxonomy_forums' => [
  [
'target_id' => '20',],
  ],   
));
$node->save();
?>

В итоге сайт падает с ошибкой:

The website encountered an unexpected error. Please try again later.
Recoverable fatal error: Argument 1 passed to Drupal\Core\Routing\RequestContext::fromRequest() must be an instance of Symfony\Component\HttpFoundation\Request, null given, called in \core\lib\Drupal\Core\Routing\RequestContext.php on line 36 and defined in Drupal\Core\Routing\RequestContext->fromRequest() (line 42 of core\lib\Drupal\Core\Routing\RequestContext.php).

Модуль отключаю и сайт работает. Проверяю - нода создана. Включаю модуль и снова та же ошибка. Т.е. ноды создаются, но сайт падает. Целый день пытаюсь устранить эту ошибку, но не выходит. Ругается на какой-то аргумент, как я понял связано с формированием ссылки. Но нода создаётся нормально. Правда не создаётся синоним patchauto, пробовал отключать шаблон patchauto для этого типа ноды, но это ситуацию не изменило. Подскажите куда копать.

Лучший ответ

Аватар пользователя g78knl6cvxf0 g78knl6cvxf0 23 мая 2016 в 0:56
1

Если код так сразу в файле и лежит, то так нельзя (точнее, наверное, можно через RouteCollection замутить свою маршрутизацию, но это ненужная сложность). Нужно положить код либо в хук, либо в метод контроллера/сервиса. Например:

YOUR_MODULE/YOUR_MODULE.routing.yml:

node_creator:
  path: 'creator/node'
  defaults:
    _controller: 'Drupal\YOUR_MODULE\Controller\CreatorNode::generator'
  requirements:
    _permission:  'access content'

YOUR_MODULE/src/Controller/CreatorNode.php:

<?php
namespace Drupal\YOUR_MODULE\Controller;

use 

Drupal\node\Entity\Node;
use 
Drupal\Core\Controller\ControllerBase;
use 
Symfony\Component\HttpFoundation\Response;
use 
Symfony\Component\HttpFoundation\RedirectResponse;

class 

CreatorNode extends ControllerBase {

  public function 

generator() {

    

// create node
    
    
$response = new Response("ok");
    
// or
    
$url = \Drupal\Core\Url::fromRoute('entity.node.canonical', ['node' => $node->id()])->toString();
    
$response =  new RedirectResponse($url);

    return 

$response;
  }
}
?>

Комментарии

Аватар пользователя alexboy alexboy 23 марта 2016 в 22:50

dgastudio wrote:


Я как раз писал модуль, опираясь на эту статью. И как результат выходит ошибка. Через kint(Node::load($nid)); сравнивал обе ноды (добавленную вручную и созданную программно): там всё идентично.

Аватар пользователя alexboy alexboy 24 марта 2016 в 15:10

dgastudio wrote:

резюме, 8ка говно, 7ка рулит


Скопировал код в функцию темы function theme_preprocess_node(&$variables) и работает как надо. Не думаю что сама восьмёрка виновата, скорее всего чего-то не хватает в моём коде. В модуле он работать не хочет...

Аватар пользователя g78knl6cvxf0 g78knl6cvxf0 23 мая 2016 в 0:56
1

Если код так сразу в файле и лежит, то так нельзя (точнее, наверное, можно через RouteCollection замутить свою маршрутизацию, но это ненужная сложность). Нужно положить код либо в хук, либо в метод контроллера/сервиса. Например:

YOUR_MODULE/YOUR_MODULE.routing.yml:

node_creator:
  path: 'creator/node'
  defaults:
    _controller: 'Drupal\YOUR_MODULE\Controller\CreatorNode::generator'
  requirements:
    _permission:  'access content'

YOUR_MODULE/src/Controller/CreatorNode.php:

<?php
namespace Drupal\YOUR_MODULE\Controller;

use 

Drupal\node\Entity\Node;
use 
Drupal\Core\Controller\ControllerBase;
use 
Symfony\Component\HttpFoundation\Response;
use 
Symfony\Component\HttpFoundation\RedirectResponse;

class 

CreatorNode extends ControllerBase {

  public function 

generator() {

    

// create node
    
    
$response = new Response("ok");
    
// or
    
$url = \Drupal\Core\Url::fromRoute('entity.node.canonical', ['node' => $node->id()])->toString();
    
$response =  new RedirectResponse($url);

    return 

$response;
  }
}
?>
Аватар пользователя alexboy alexboy 23 мая 2016 в 11:41

Всё равно не получается! То вообще ничего не создаётся, то выходит ошибка:
RuntimeException: Failed to start the session because headers have already been sent by "T:\openserver\domains\drupal8.ru\sites\drupal8.ru\modules\node_auto\node_auto.module" at line 2. in Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage->start() (line 140 of vendor\symfony\http-foundation\Session\Storage\NativeSessionStorage.php).
Модуль в итоге получился такой: node_auto

Аватар пользователя g78knl6cvxf0 g78knl6cvxf0 23 мая 2016 в 12:14
1

Попробуй зайти в файл node_auto.module и удалить там пустые строки (чтобы он в результате весил 0 байт), либо написать в самом начале <?php.
Установил твой модуль на чистый сайт - все работает как часы и под админом, и под гостем!

Аватар пользователя alexboy alexboy 24 мая 2016 в 17:23

vaplas wrote:

Попробуй зайти в файл node_auto.module и удалить там пустые строки (чтобы он в результате весил 0 байт), либо написать в самом начале <?php.


Ошибка выходить не стала, но тишина - ноды не создаются. Пробовал на чистом сайте. Версия 8.1.1. Вручную нода создаётся с параметрами прописанными в модуле, если копирую код в тему в функцию theme_preprocess_node - то тоже создаётся, а через модуль почему-то нет...

Аватар пользователя g78knl6cvxf0 g78knl6cvxf0 24 мая 2016 в 18:11
1

Я тоже на 8.1.1 проверял - все ок. Уж грешным делом подумал что OpenServer виноват - проверил на нем (скачал последнюю версию с php7, правда не на вирутальном диске запускал), все работает. Попробуй удалить модуль и поставить заново. Включи вывод всех сообщений /admin/config/development/logging, посмотри логи здесь /admin/reports/dblog и в папке с логами OpenServer/userdata/logs/. Ну и кэш почисть. Если хочешь, можешь кинуть архив с чистым сайтом и дампом базы, на котором не работает, проверю у себя.

Аватар пользователя alexboy alexboy 25 мая 2016 в 12:02

Проблема была в том, что я не понял, что для того чтобы модуль сработал нужно заходить по конкретному адресу.
В данном случае для генерации материала нужно перейти по адресу http://site.ru/creator/node
Vaplas, спасибо за помощь!

Аватар пользователя g78knl6cvxf0 g78knl6cvxf0 25 мая 2016 в 12:15

Если нужно генерировать при переходе по материалу, то можно использовать хуки в файле node_auto.module:

<?php
function node_auto_preprocess_node(&$variables) { // при переходе по материалам
function node_auto_preprocess_html(&$variables) { // при переходе по старницам вообще
  
if(условие){
    
# код
  
}  
}
?>