1. Главная
  2. Форумы
  3. Техподдержка Drupal
  4. Решение проблем

Обновление модуля D7-D10

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

Аватар пользователя quattro quattro 25 октября 2025 в 16:17
<?php
if (file_exists(conf_path().'/settings-zbase.php')) require_once conf_path().'/settings-zbase.php';
else {
if(isset(
$db_url)) $zbase_url = $db_url; // drupal 6 compatibility
else if (file_exists(conf_path().'/settings.php')) {
require_once
conf_path().'/settings.php';
$zbase_url = $db_url;
}
}
?>

В представленном фрагменте кода, для Друпал 10 "conf_path()" - устарел

Как исправить подключение директорию drupal/sites/default для D10?

Комментарии

Аватар пользователя OldWarrior OldWarrior 28 октября 2025 в 12:00

quattro wrote: Как исправить подключение директорию drupal/sites/default для D10?

Что мешает самому построить путь к settings.php используя, например, константу DRUPAL_ROOT ?

Однако, в контексте Drupal 10 как-то проще обращаться к методам класса Drupal\Core\Site\Settings для получения значений settings.php. Например:

<?php
...
// Получить все настройки из settings.php
$my_settings = \Drupal\Core\Site\Settings::getAll();
...
// Получить конкретную настройку из settings.php
$setting = \Drupal\Core\Site\Settings::get('install_profile');
...
?>
Аватар пользователя quattro quattro 30 октября 2025 в 11:42

"sitePath" пока поставил, вместо "conf_path".
Ещё через сервисы подключить можно:
$site_path = \Drupal::service('site.path');
Но пока не хочется совсем переделывать модуль под D10, так как не знаю когда, Drupal и Symfony смогут сертифицировать под ФСТЭК. Причем в версии ПХП хотя бы 8.2.
Этот первый модуль, который получает доступ к базам данных сайта, и второй базе - биллинга
через файлы настроек.

Сейчас пытаюсь адаптировать другие модули, которые минимально необходимы для работы в связке с этим первым.
Задача включить интерфейс биллинга по адресу url, но чета не получается ...
Пока не понял, как через файл контроллера, подключить адрес этой страницы.
В D7 так:
файл vircadm.module

<?php require_once 'vircadm-drupal.inc';
require_once
'vircadm-drupal'.substr(Drupal::VERSION,0,2).'.inc';
require_once
'vircadm-roles.inc'; // Корень модуля
function vircadm() {
global
$user, $base_path;
if (!
$user->uid) {
$_REQUEST['destination'] = '?q=vircabo';
//drupal_goto(); //функция перенаправления drupal7,
drupal_get_destination();//функция перенаправления drupal10
return '';
}
zBaseSetConfig('vircadm');
loadConstant('LOGIN');
$drupal = (defined("VIRC_TEMPL") && VIRC_TEMPL == false); // не использовать собственный шаблон
//$drupal = true;
$content = vircadm_content();
$head = vircadm_header($drupal);
if (!
$drupal) {
include
'page-vircadm.tpl.php';
exit;
}
return
$content;
}
?>

Файл vircadm-drupal.inc


<?php
function vircadm_menu() {
$items = array();
$items['vircadm'] = array(
'title' => 'Виртуальный ИРЦ',
'page callback' => 'vircadm',
'page arguments' => null,
'access arguments' => array('access content'),
'type' => MENU_CALLBACK, //MENU_NORMAL_ITEM,
);
}
?>
Аватар пользователя kosskren kosskren 30 октября 2025 в 12:38

Начиная с друпал 8, подход к работе значительно поменялся. Для объявления URL используется yml файл. Вот тут по ссылке базовый пример, как создать url и обрабатывать его. Я специально убрал все лишнее из модуля, что бы осталась только часть про URL. Пример модуля

Аватар пользователя quattro quattro 30 октября 2025 в 15:18

Понятно что поменялось всё с 8й версии.
В инструкциях друпал написано, что можно подключить отдельный интерфейс, через объявление сервиса, или с помощью метода в файле контроллера.
Спасибо за пример ...
Набор наших модулей, реализуют учётную систему. Например для ЖКХ: https://demo.rcgkh.ru Если авторизоваться там с ролью абонент, то откроется Личный кабинет абонента., но если с любой другой ролью, то откроется как раз интерфейс биллинговой системы, в которой работают сотрудники предприятий ЖКХ.
Приведённый кусок кода выше, определят куда пробросить пользователя после авторизации, зная его роль.
Но, для всех ролей кроме Абонент ЖКХ, открывается интерфейс биллинга, у которого есть всё, и ломать его нет смысла.
В конце приведенного кода, есть подключение nclude page-vircadm.tpl.php и дальше друпал не участвует в отображении интерфейса.

<?php if (!$drupal) {
include
'page-vircadm.tpl.php';
exit;
}
return
$content; ?>

И ещё, в D10 упразднена функция drupal_goto();
замена сходу не сработала.
Сейчас попробовал заменить на Drupal::destination();
посыпались ошибки типа:

Symfony\Component\HttpKernel\Exception\ControllerDoesNotReturnResponseException: Контроллер должен вернуть объект "Symfony\Component\HttpFoundation\Response", но он вернул значение null. Вы забыли добавить инструкцию return где-нибудь в вашем контроллере? in () (строка 98 из core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php).

Аватар пользователя kosskren kosskren 30 октября 2025 в 22:34

Для замены drupal_goto() посмотрите на этот класс:
Symfony\Component\HttpFoundation\RedirectResponse;

У меня рабочего примера под рукой нет, но думаю контроллер должен возвращать что-то в этом духе:
return new RedirectResponse($url);

Для проверки роли пользователя можно использовать:
<?php $user = \Drupal::currentUser(); ?>

Так проверяем роль:
<?php $user->hasRole('admin') // true/false ?>

Аватар пользователя OldWarrior OldWarrior 31 октября 2025 в 18:21

quattro wrote: "sitePath" пока поставил, вместо "conf_path".

Это лучше всего в вашем случае. Метод DrupalKernel::$sitePath как раз идеален для этого.

quattro wrote: Ещё через сервисы подключить можно:
$site_path = \Drupal::service('site.path');

Deprecated. https://www.drupal.org/project/bs_base/issues/3346593

Аватар пользователя quattro quattro 31 октября 2025 в 18:55

OldWarrior wrote: Deprecated. https://www.drupal.org/project/bs_base/issues/3346593

Спасибо! Я сейчас тратил время, чтоб вариант через сервисы попробовать.
Я читал мануалы ориентируясь на D9+, в каком то описании было упомянуто что есть 2 варианта... Значит остался один, через метод класса. Будем теперь методы изучать, !

Аватар пользователя quattro quattro 31 октября 2025 в 22:23

OldWarrior wrote: quattro wrote: Ещё через сервисы подключить можно:
$site_path = \Drupal::service('site.path');

Deprecated. https://www.drupal.org/project/bs_base/issues/3346593

Немного не так, не через сервисы, а через "объявление" сервиса...

Аватар пользователя quattro quattro 25 ноября 2025 в 23:16

Доброго времени!
Что то, у меня не получается подключить /sites/default
Друпал пишет ошибки типа:

Warning: Undefined variable $site_path в include_once() (строка 77 из /var/www/pafes/data/www/pafes.ru/modules/custom/zbase/zbase.module)
#0 /var/www/pafes/data/www/pafes.ru/core/includes/bootstrap.inc(166): _drupal_error_handler_real()
#1 /var/www/pafes/data/www/pafes.ru/modules/custom/zbase/zbase.module(77): _drupal_error_handler()
#2 /var/www/pafes/data/www/pafes.ru/core/lib/Drupal/Core/Extension/Extension.php(153): include_once('...')
#3 /var/www/pafes/data/www/pafes.ru/core/lib/Drupal/Core/Extension/ModuleHandler.php(128): Drupal\Core\Extension\Extension->load()
#4 /var/www/pafes/data/www/pafes.ru/core/lib/Drupal/Core/Extension/ModuleHandler.php(141): Drupal\Core\Extension\ModuleHandler->load()
#5 /var/www/pafes/data/www/pafes.ru/core/lib/Drupal/Core/DrupalKernel.php(615): Drupal\Core\Extension\ModuleHandler->loadAll()
#6 /var/www/pafes/data/www/pafes.ru/core/lib/Drupal/Core/StackMiddleware/KernelPreHandle.php(46): Drupal\Core\DrupalKernel->preHandle()
#7 /var/www/pafes/data/www/pafes.ru/core/lib/Drupal/Core/StackMiddleware/ContentLength.php(28): Drupal\Core\StackMiddleware\KernelPreHandle->handle()
#8 /var/www/pafes/data/www/pafes.ru/core/modules/big_pipe/src/StackMiddleware/ContentLength.php(32): Drupal\Core\StackMiddleware\ContentLength->handle()
#9 /var/www/pafes/data/www/pafes.ru/core/modules/page_cache/src/StackMiddleware/PageCache.php(116): Drupal\big_pipe\StackMiddleware\ContentLength->handle()
#10 /var/www/pafes/data/www/pafes.ru/core/modules/page_cache/src/StackMiddleware/PageCache.php(90): Drupal\page_cache\StackMiddleware\PageCache->pass()
#11 /var/www/pafes/data/www/pafes.ru/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php(48): Drupal\page_cache\StackMiddleware\PageCache->handle()
#12 /var/www/pafes/data/www/pafes.ru/core/lib/Drupal/Core/StackMiddleware/NegotiationMiddleware.php(51): Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle()
#13 /var/www/pafes/data/www/pafes.ru/core/lib/Drupal/Core/StackMiddleware/AjaxPageState.php(36): Drupal\Core\StackMiddleware\NegotiationMiddleware->handle()
#14 /var/www/pafes/data/www/pafes.ru/core/lib/Drupal/Core/StackMiddleware/StackedHttpKernel.php(51): Drupal\Core\StackMiddleware\AjaxPageState->handle()
#15 /var/www/pafes/data/www/pafes.ru/core/lib/Drupal/Core/DrupalKernel.php(741): Drupal\Core\StackMiddleware\StackedHttpKernel->handle()
#16 /var/www/pafes/data/www/pafes.ru/index.php(19): Drupal\Core\DrupalKernel->handle()
#17 {main}

Гдето накосячил, но не могу понять, почему не видит ....
Код следующий:

<?php
if (file_exists($app_root . '/' . $site_path . '/settings-zbase.php')) require_once $app_root . '/' . $site_path .'/settings-zbase.php';
else {
if(isset(
$db_url)) $zbase_url = $db_url; // drupal 6 compatibility
else if (file_exists($app_root . '/' . $site_path . '/settings.php')) {
require_once
$app_root . '/' . $site_path . '/settings.php';
$zbase_url = $db_url;
}
}
?>

77 строка это:

<?php
else if (file_exists($app_root . '/' . $site_path . '/settings.php')) {
?>
Аватар пользователя kosskren kosskren 30 октября 2025 в 12:18

Добрый день.

Вы пишите про сертификацию ФСТЭК для Drupal и Symfony. Можете подробнее рассказать об этом если в теме? Инициализирует сертификацию сам ФСТЭК по собственному графику или допустим я создаю интернет магазин и могу им заявку отправить на сертификацию.

Аватар пользователя quattro quattro 30 октября 2025 в 14:42

День добрый!
Да, подаёте заявку, по форме центра который проводит сертификацию, платите много денег, и ждёте много времени... Пока они будут проверку делать, может что-то скажут переделать...
Но! Проблема в том, что они отстают от сертификации ПО, на актуальных версиях PHP. Не говоря про версии фреймворков...
По этом, в нашем случае необходимо поддерживать вариант работы нашего ПО, так чтоб оно могло работать и на пхп5,6
Насколько я знаю, в начале 2025 года, сертифицированный под ФСТЭК линкус поддерживал только пхп 5,6.

Аватар пользователя quattro quattro 19 декабря 2025 в 16:28

При обновлении версии php до 8.2 выскочила ошибка:
TypeError : count(): Аргумент #1 ($value) должен быть типа Countable|array, а передан null в функции loadConstant() (строка 17 файла modules/custom/vircabo/common-lib.php ).

function loadConstant($categ=false,$item=false) {
if (defined ("VIRC_SETTINGS")) return;
if (!$categ) $param = array ('categ'=>'');
else $param = array ('categ'=>''.VM.$categ);
if ($item) $param['id'] = $item;
$settArr = zQuery('_constant','select','',$param,true);
foreach($settArr as $i => $sets) {
if (!defined ($sets[0])) { define ($sets[0],$sets[1]); }
}
if ( $categ == 'LOGIN' ) {
$agent = zQuery('agent,_constant','select',DEF_AGENT,array (),true);
if (count ($agent)) {
define ("AGENT_ADDR",$agent[0][2]);
define ("AGENT_PHONE",$agent[0][3]);
}
}
if (!$item) { define ("VIRC_SETTINGS",$categ ? true : $categ); }
}

Ни как не получается исправить этот кусок кода:

if (count ($agent)) {
define ("AGENT_ADDR",$agent[0][2]);
define ("AGENT_PHONE",$agent[0][3]);
}

Есть у кого ни будь какие мысли:

Аватар пользователя Andruxa Andruxa 20 декабря 2025 в 14:45

Странный код.
if (count ($agent)) - проверяется, что $agent является непустым массивом, в старых версиях php переменная могла иметь значение NULL, и условие работало, с 8.2 типизация стала строже, и передача NULL приводит к ошибке.
Но таким способом не проверяется, что элементы массива $agent содержат в себе вложенные массивы.
Тут правильнее проверять наличие требуемых элементов массива, т.е.

if (!empty ($agent[0][2])) {
define ("AGENT_ADDR",$agent[0][2]);
}
if (!empty ($agent[0][3])) {
define ("AGENT_PHONE",$agent[0][3]);
}

И тут странность - если условие не выполняется, то константы AGENT_ADDR, AGENT_PHONE не будут объявлены. Но ведь где-то дальше в коде к ним идет обращение, если константы могут отсутствовать - это надо проверять if (defined ('AGENT_ADDR')) ...
К чему такие сложности? Не проще ли писать данные в переменные, и проверять через empty (), is_null () и т.п. ?
Ну или своим классом с методами getAgentAddr(), getAgentPhone(), если значения должны быть readonly.

Аватар пользователя quattro quattro 10 января в 19:07

Спасибо за комментарий!
Действительно, после изучения кода, где применяется этот запрос, выяснилось что он использовался в одном месте и был написан как "костыль".
То есть, задача была следующая:
Если есть AGENT_ADDR, AGENT_PHONE, то показать в отдельном блоке!
Типа по всем вопросам обращаться по такому AGENT_ADDR, звонить поAGENT_PHONE с 8 00, до 16 00.
Так как было написано для версии PHP 5,6 то работало.
Теперь нужно исправить для php 8.2.

Логотип drupal.ru

Содержимое сайта публикуется на условиях CreativeCommons Attribution-ShareAlike 3.0 или более поздней версии. Программные коды в тексте статей — на условиях GNU GPL v2 или более поздней версии.

Документация по совместной работе с репозиторием drupal.ru – https://docs.drupal.ru/code

Drupal – торговая марка Дриса Бёйтарта

12+

AltStyle によって変換されたページ (->オリジナル) /