Drupal error level

Logging severity levels as defined in RFC 3164.

Logging severity levels as defined in RFC 3164.

The WATCHDOG_* constant definitions correspond to the logging severity levels
defined in RFC 3164, section 4.1.1. PHP supplies predefined LOG_* constants
for use in the syslog() function, but their values on Windows builds do not
correspond to RFC 3164. The associated PHP bug report was closed with the
comment, «And it’s also not a bug, as Windows just have less log levels,»
and «So the behavior you’re seeing is perfectly normal.»

See also

http://www.faqs.org/rfcs/rfc3164.html

http://bugs.php.net/bug.php?id=18090

http://php.net/manual/function.syslog.php

http://php.net/manual/network.constants.php

watchdog()

watchdog_severity_levels()

File

includes/bootstrap.inc, line 55
Functions that need to be loaded on every Drupal request.

Functions

Namesort descending Location Description
DBLogTestCase::getSeverityConstant modules/dblog/dblog.test Gets the watchdog severity constant corresponding to the CSS class.
dblog_overview modules/dblog/dblog.admin.inc Page callback: Displays a listing of database log messages.
drupal_error_levels includes/errors.inc Maps PHP error constants to watchdog severity levels.
watchdog_severity_levels includes/common.inc Returns a list of severity levels, as defined in RFC 3164.

Constants

Namesort descending Location Description
WATCHDOG_ALERT includes/bootstrap.inc Log message severity — Alert: action must be taken immediately.
WATCHDOG_CRITICAL includes/bootstrap.inc Log message severity — Critical conditions.
WATCHDOG_DEBUG includes/bootstrap.inc Log message severity — Debug-level messages.
WATCHDOG_EMERGENCY includes/bootstrap.inc Log message severity — Emergency: system is unusable.
WATCHDOG_ERROR includes/bootstrap.inc Log message severity — Error conditions.
WATCHDOG_INFO includes/bootstrap.inc Log message severity — Informational messages.
WATCHDOG_NOTICE includes/bootstrap.inc Log message severity — Normal but significant conditions.
WATCHDOG_WARNING includes/bootstrap.inc Log message severity — Warning conditions.

Same name and namespace in other branches

  1. 10 core/includes/errors.inc drupal_error_levels()
  2. 8.9.x core/includes/errors.inc drupal_error_levels()
  3. 9 core/includes/errors.inc drupal_error_levels()

Maps PHP error constants to watchdog severity levels.

The error constants are documented at
http://php.net/manual/errorfunc.constants.php

Related topics

1 call to drupal_error_levels()

_drupal_error_handler_real in includes/errors.inc
Provides custom PHP error handling.

File

includes/errors.inc, line 16
Functions for error handling.

Code

function drupal_error_levels() {
  $types = array(
    E_ERROR => array(
      'Error',
      WATCHDOG_ERROR,
    ),
    E_WARNING => array(
      'Warning',
      WATCHDOG_WARNING,
    ),
    E_PARSE => array(
      'Parse error',
      WATCHDOG_ERROR,
    ),
    E_NOTICE => array(
      'Notice',
      WATCHDOG_NOTICE,
    ),
    E_CORE_ERROR => array(
      'Core error',
      WATCHDOG_ERROR,
    ),
    E_CORE_WARNING => array(
      'Core warning',
      WATCHDOG_WARNING,
    ),
    E_COMPILE_ERROR => array(
      'Compile error',
      WATCHDOG_ERROR,
    ),
    E_COMPILE_WARNING => array(
      'Compile warning',
      WATCHDOG_WARNING,
    ),
    E_USER_ERROR => array(
      'User error',
      WATCHDOG_ERROR,
    ),
    E_USER_WARNING => array(
      'User warning',
      WATCHDOG_WARNING,
    ),
    E_USER_NOTICE => array(
      'User notice',
      WATCHDOG_NOTICE,
    ),
    E_STRICT => array(
      'Strict warning',
      WATCHDOG_DEBUG,
    ),
    E_RECOVERABLE_ERROR => array(
      'Recoverable fatal error',
      WATCHDOG_ERROR,
    ),
  );

  // E_DEPRECATED and E_USER_DEPRECATED were added in PHP 5.3.0.
  if (defined('E_DEPRECATED')) {
    $types[E_DEPRECATED] = array(
      'Deprecated function',
      WATCHDOG_DEBUG,
    );
    $types[E_USER_DEPRECATED] = array(
      'User deprecated function',
      WATCHDOG_DEBUG,
    );
  }
  return $types;
}

Why The website has encountered an error. Please try again later. And not the actual error logs. Simply adding this line

$config['system.logging']['error_level'] = 'verbose';

to your sites/default/settings.php should resolve the issue.

But I will suggest these steps. Assuming I have installed my drupal in /home/drupal/

==enable twig debug and disable cache for development purpose==

cd /home/drupal/web/sites

#1 copy sites/example.settings.local.php to sites/default/settings.local.php

cp example.settings.local.php /home/drupal/web/sites/default/settings.local.php

#2 un-comment this line in the settings.local.php (#) $settings['cache']['bins']['render'] = 'cache.backend.null';

nano /home/drupal/web/sites/default/settings.local.php

#Save all by pressing:
Ctrl + X enter Y and press enter

#3 go to site/default/settings.php uncomment this lines 807 to 809

(#) if (file_exists($app_root . '/' . $site_path . '/settings.local.php')) {
(#)   include $app_root . '/' . $site_path . '/settings.local.php';
(#) }

nano /home/drupal/web/sites/default/settings.php

#Save all by pressing:
Ctrl + X enter Y and press enter

#4 edit sites/development.services.yml

nano /home/drupal/web/sites/development.services.yml

#==>> consider tabs and indentation this is a YML file, it requires indentation.

parameters:
  http.response.debug_cacheability_headers: true
  twig.config:
    debug: true
    auto-reload: true
    cache: false
services:
  cache.backend.null:
    class: DrupalCoreCacheNullBackendFactory

when all steps completed change directory to root dir and rebuild cache

cd /home/drupal/

drush cr

Refresh your site, and you should see the debug outputs, don’t forget to undo them before deploying to production.

function drupal_error_levels

drupal_error_levels()

Maps PHP error constants to watchdog severity levels.

The error constants are documented at http://php.net/manual/errorfunc.constants.php

Related topics

Logging severity levels
Logging severity levels as defined in RFC 5424.

File

core/includes/errors.inc, line 23
Functions for error handling.

Code

function drupal_error_levels() {
  $types = array(
    E_ERROR => array('Error', RfcLogLevel::ERROR),
    E_WARNING => array('Warning', RfcLogLevel::WARNING),
    E_PARSE => array('Parse error', RfcLogLevel::ERROR),
    E_NOTICE => array('Notice', RfcLogLevel::NOTICE),
    E_CORE_ERROR => array('Core error', RfcLogLevel::ERROR),
    E_CORE_WARNING => array('Core warning', RfcLogLevel::WARNING),
    E_COMPILE_ERROR => array('Compile error', RfcLogLevel::ERROR),
    E_COMPILE_WARNING => array('Compile warning', RfcLogLevel::WARNING),
    E_USER_ERROR => array('User error', RfcLogLevel::ERROR),
    E_USER_WARNING => array('User warning', RfcLogLevel::WARNING),
    E_USER_NOTICE => array('User notice', RfcLogLevel::NOTICE),
    E_STRICT => array('Strict warning', RfcLogLevel::DEBUG),
    E_RECOVERABLE_ERROR => array('Recoverable fatal error', RfcLogLevel::ERROR),
    E_DEPRECATED => array('Deprecated function', RfcLogLevel::DEBUG),
    E_USER_DEPRECATED => array('User deprecated function', RfcLogLevel::DEBUG),
  );

  return $types;
}
drupal_error_levels()

Карты PHP ошибки константы для отслеживания уровней тяжести.

Константы ошибок задокументированы на http://php.net/manual/errorfunc.constants.php.

Related topics

Уровни тяжести каротажа
Степень строгости протоколирования,как определено в RFC 5424.

File

core / includes / errors.inc , строка 23
Функции для обработки ошибок.

Code

function drupal_error_levels() {
  $types = array(
    E_ERROR => array('Error', RfcLogLevel::ERROR),
    E_WARNING => array('Warning', RfcLogLevel::WARNING),
    E_PARSE => array('Parse error', RfcLogLevel::ERROR),
    E_NOTICE => array('Notice', RfcLogLevel::NOTICE),
    E_CORE_ERROR => array('Core error', RfcLogLevel::ERROR),
    E_CORE_WARNING => array('Core warning', RfcLogLevel::WARNING),
    E_COMPILE_ERROR => array('Compile error', RfcLogLevel::ERROR),
    E_COMPILE_WARNING => array('Compile warning', RfcLogLevel::WARNING),
    E_USER_ERROR => array('User error', RfcLogLevel::ERROR),
    E_USER_WARNING => array('User warning', RfcLogLevel::WARNING),
    E_USER_NOTICE => array('User notice', RfcLogLevel::NOTICE),
    E_STRICT => array('Strict warning', RfcLogLevel::DEBUG),
    E_RECOVERABLE_ERROR => array('Recoverable fatal error', RfcLogLevel::ERROR),
    E_DEPRECATED => array('Deprecated function', RfcLogLevel::DEBUG),
    E_USER_DEPRECATED => array('User deprecated function', RfcLogLevel::DEBUG),
  );

  return $types;
}

© 2001–2016 авторы оригинала
Лицензируется по Стандартной Общественной Лицензии GNU,версия 2 и более поздняя.
Drupal является зарегистрированной торговой маркой Dries Buytaert.
https://api.drupal.org/api/drupal/core!includes!errors.inc/function/drupal_error_levels/8.1.x


Error handling можно перевести как «работа с ошибками». В этой статье я немного расскажу о том, как это устроено в Друпале, и как этот процесс можно улучшить для облегчения отладки вашего кода.

PHP по умолчанию использует вывод ошибок прямо в окно браузера (я думаю, все видели это неприглядные, но крайне полезные сообщения вверху веб-страницы типа «notice: Use of undefined constant.. «), и предоставляет возможность разработчику переопределить функцию работы с ошибками. Можно, например, сохранять информацию об ошибках PHP интерпретатора в базу данных (как сделано в Друпале), слать емейлы админу, и т.д.

Переопределяется функция вот так:

set_error_handler(‘error_handler’); // error_handler() — функция, на которую PHP перекладывает error handling

У ошибок бывают разные уровни «тяжести» — notice, warning, fatal error, parse error, user error, … В Друпаловскую функцию error_handler «долетают» только notice и warning + искусственно вызванные самим друпалом user error, по причинам сложности перехвата fatal и parse error (перехват fatal error возможен, но немного напоминает пляску с бубном, я не буду этой темы касаться сейчас, дабы не отклоняться от намеченной темы).

Вот вкратце и все. Теперь про то, как мы можем облегчить себе жизнь в Друпале.

1. Включаем вывод ошибок уровня E_NOTICE

По непонятным до сих пор мне причинам, нотисы в друпале жестко отключены. Разработчики аргументируют свое решение тем, что код ядра системы «не избавлен от нотисов». Это мы очень явно видим, когда запускаем install.php и получаем кучу ошибок, если в php.ini у нас стоит error_reporting(E_ALL);

Скрипт инсталлятора не использует error_handler Друпала (по понятным причинам, сам Друпал-то не установлен еще, а значит и фунции ядра использовать нет возможности), и поэтому приходится писать error_reporting(0); в начале install.php

После установки Друпала нотисов мы больше не увидим. Друпал берет на себя весь процесс и скрывает ошибки уровня E_NOTICE. Это значит, например, что если мы опечатаемся в написании переменной или константы, то не узнаем об этом. Лично меня такой подход совсем не устраивает — поэтому лезем в /includes/common.inc, находим функцию error_handler и строку 551

if ($errno & (E_ALL ^ E_NOTICE)) {

заменяем на

вуаля!
Друпал нас сразу радует нотисами:

notice: Undefined variable: no_module_preprocess in y:homed5wwwincludescommon.inc on line 1493.
notice: Undefined variable: no_theme_preprocess in y:homed5wwwincludescommon.inc on line 1493.

Можно конечно заняться фиксингом кода ядра, дабы избавить его от этой парочки предупреждений (благо это совсем несложно), но потом открываем другую страницу и какой-нибудь модуль типа Views радует нас еще десятком сообщений об ошибках. Становится понятно, что все не перефиксишь Smile Да и обновление модулей сразу сведет все наши старания на нет.

Что мы можем сделать? Включить нотисы только для нашего модуля.
Для этого доработаем функцию error_handler и определим дополнительную Друпаловскую переменную в settings.php:

В конец sitesdefaultsettings.php дописываем:

$conf = array();
$conf[‘debug_files’] = array(
  ‘/modules/views/views.module’,
  ‘/includes/common.inc’
);

Так я включаю вывод нотисов только для двух файлов, ‘/modules/views/views.module’ и ‘/includes/common.inc’

Теперь изменения в error_handler() (/includes/common.inc, строка 551) :
заменяем наше

на

//default error level
  $error_level = E_ALL ^ E_NOTICE;
  // fix paths if in windows
  if (strtoupper(substr(PHP_OS, 0, 3)) === ‘WIN’) {  
    $unified_filename = str_replace(DIRECTORY_SEPARATOR, ‘/’, $filename);
  } else {
    $unified_filename = $filename;
  }

 
  $debug_files = variable_get(‘debug_files’, array());

 

foreach($debug_files as $debug_file) {  
    if(strpos($unified_filename, $debug_file) !== FALSE) {          
      $error_level = E_ALL;
      break;          
    }
  }

 
  if ($errno & ($error_level)) {

Заметьте, что можно разрешить нотисы например для всей папки /modules прописав в конфиг ‘/modules/’

2. Выводим backtrace

UPD: что описано в этом разделе, можно получить установив модуль devel: http://drupal.org/project/devel
Внимание: все изменения, которые вы внесли в родной Друпаловский error_hander, во время включенного devel не будут иметь силы, контроль ошибок будет перехвачен внутренней функцией devel — backtrace_error_handler()

В процессе разработки довольно часто вылазят ошибки, которые по названию файла и номеру строки не выловишь (например: какой-то модуль делает неверный sql запрос, а друпал нам выводит ошибку:

«user warning: Unknown column ‘n.ndid’ in ‘where clause’ query: SELECT n.nid, n.vid, n.type, n.status, n.created, n.changed, n.comment, n.promote, n.sticky, r.timestamp AS revision_timestamp, r.title, r.body, r.teaser, r.log, r.format, u.uid, u.name, u.picture, u.data FROM node n INNER JOIN users u ON u.uid = n.uid INNER JOIN node_revisions r ON r.vid = n.vid WHERE n.ndid = 9 in y:homed5wwwincludesdatabase.mysql.inc on line 172.»

По этому сообщению мы лишь можем понять, что сама ошибка была в database.mysql.inc, но это и так понятно, ведь все модули общаются с базой через функции database.mysql.inc, в частности db_query(). А вот какой модуль этот самый запрос выполнял?

Чтобы узнать, какой модуль вызвал _db_query, нам надо отследить всю цепочку вызовов, предшествовавших нашей ошибке:
_db_query() // db_query вызвал _db_query, который вызвал ошибку
db_query() // а это node_load() вызвал db_query()
node_load() // а это наша функция вызвала node_load()
our_module_function() // это та самая функция с ошибкой!
// тут предыдущие вызовы

Сделать такое нам позволит PHP функция debug_backtrace(), которая возвращает стек всех вызовов в виде массива.
После модификации нашей функции error_handler() вместо вот такого малоинформативного скрина мы получаем вот такой отчет, что нам очень упростит отлов проблемы в коде. (Если вы внимательно посмотрите код ниже, то обнаружите, что я закомментировал распечатку значений аргументов функций в бектрейсе, т.к. это ломает верстку страницы — ведь друпал передает в некоторые функции html код. можно все аргументы прогонять через htmlspecialchars к примеру, и обрезать по длине, но я не стал усложнять этим свой код. Думаю, что заинтересовавшимся при желании не составит большого труда навести лоск на внешний вид сообщений.)

P.S. В Drupal 6 разработчики уже включили бектрейсинг, но почему-то сделали это достаточно замудренным и неоднозначным способом — только для функций для работы с базами данных..

Привожу полный код получившейся функции error_handler(), includes/common.inc:

function error_handler($errno, $message, $filename, $line) {
  // If the @ error suppression operator was used, error_reporting is temporarily set to 0
  if (error_reporting() == 0) {
    return;
  }

 
  //default error level
  $error_level = E_ALL ^ E_NOTICE;
  // fix paths if in windows
  if (strtoupper(substr(PHP_OS, 0, 3)) === ‘WIN’) {  
    $unified_filename = str_replace(DIRECTORY_SEPARATOR, ‘/’, $filename);
  } else {
    $unified_filename = $filename;
  }

 
  $debug_files = variable_get(‘debug_files’, array());

 

foreach($debug_files as $debug_file) {  
    if(strpos($unified_filename, $debug_file) !== FALSE) {          
      $error_level = E_ALL;
      break;          
    }
  }

 
  if ($errno & ($error_level)) {
    $types = array(1 => ‘error’, 2 => ‘warning’, 4 => ‘parse error’, 8 => ‘notice’, 16 => ‘core error’, 32 => ‘core warning’, 64 => ‘compile error’, 128 => ‘compile warning’, 256 => ‘user error’, 512 => ‘user warning’, 1024 => ‘user notice’, 2048 => ‘strict warning’);
    $entry = $types[$errno] .‘: ‘. $message .‘ in ‘. $filename .‘ on line ‘. $line .‘.’;

   
  // BACKTRACING CODE
  $backtrace = debug_backtrace();
  array_shift($backtrace); //first element is current function, ‘error_handler’

 
 
  if(count($backtrace) > 1) {
    $table_header = Array(‘File’, ‘Function’);
    $table_data = Array();
    foreach($backtrace as $file) {
      $arguments = »;    

       
      if($file[‘args’]) {  
        // if you want to see arguments passed to functions uncomment these lines (it will most likely break your page layout)      
        /*if(count($file[‘args’]) > 1) {          
          @$arguments = implode(‘ ,’, $file[‘args’]);
        } else {
          $arguments = $file[‘args’][0];
        }*/

      }    
      $file[‘file’] = isset($file[‘file’]) ? $file[‘file’] : ‘undefined’;
      $file[‘line’] = isset($file[‘line’]) ? $file[‘line’] : 0;
      $table_data[] = Array(«$file[file] (line $file[line])», «$file[function]($arguments)»);      
    }
  }

   
  $entry .= theme(‘table’, $table_header, $table_data);

    // Force display of error messages in update.php
    if (variable_get(‘error_level’, 1) == 1 || strstr($_SERVER[‘SCRIPT_NAME’], ‘update.php’)) {
      drupal_set_message($entry, ‘error’);
    }

    watchdog(‘php’, t(‘%message in %file on line %line.’, array(‘%error’ => $types[$errno], ‘%message’ => $message, ‘%file’ => $filename, ‘%line’ => $line)), WATCHDOG_ERROR);
  }
}

settings.local.php — файл с настройками локального окружения сайта. Является дополнением settings.php и использует все доступные его настройки.

Данный файл заменят, дополняет или выключает определённые настройки и поведение сайта для локальной системы. Используется при разработке проекта.

¶Создание файла

По умолчанию данный файл отсутствует. Для него поставляется стандартный пример example.settings.local.php который можно найти в директории /sites.

Для создания собственного файла достаточно скопировать example.settings.local.php в папку сайта, где уже находится основной settings.php и переименовать его в settings.local.php.

¶Подключение

Данный файл подключается из основного файлы settings.php. В конце этого файла вы можете найти следующие строки:

# if (file_exists($app_root . '/' . $site_path . '/settings.local.php')) {
#   include $app_root . '/' . $site_path . '/settings.local.php';
# }

Вам достаточно раскомментировать их и настройки из settings.local.php начнут загружаться и использоваться. Вы можете менять данное условие и поведение так как вам угодно. Данный файл должен подключаться в самом конце settings.php для того чтобы он мог изменять все основные настройки.

¶Применение

Файл settings.local.php применяется на локальных окружения в процессе разработки и заменяет некоторые настройки системы на специальные. Например, отключается кеширование, сжатие и объединение JavaScript и CSS файлов и прочие изменения необходимые для разработки, но не нужны на рабочем проекте.

Эти изменения производятся в settings.local.php для того чтобы эти настройки были явно отражены и было удобно переносить проект, делиться изменениями с командой и т.д.

¶Настройки по умолчанию

В данном разделе рассмотрены все настройки по умолчанию, который указаны в example.settings.local.php файле и подойдут для большинства проектов и задач.

¶Assertions

Drupal использует сравнения (assert), для того чтобы сообщать об ошибках использования API. Когда обнаружена проблема, запрос будет провален и выдана ошибка.

Данная настройка включает сравнения, которые по умолчанию отключены, чтобы в процессе разработки замечать ошибки на ранних стадиях.

Пример:

assert_options(ASSERT_ACTIVE, TRUE);
DrupalComponentAssertionHandle::register();

¶Сервисы для разработки

В данном файле подключается файл development.services.yml с сервисами и параметрами для разработки, которые будут загружены в контейнер.

Пример:

$settings['container_yamls'][] = DRUPAL_ROOT . '/sites/development.services.yml'

¶Подробное логирование

Для конфигурации system.logging задаётся степень детализации ошибок на подробные (verbose). Это значит, что все ошибки будут выводиться, включая стэк вызова.

$config['system.logging']['error_level'] = 'verbose';

¶Агрегация JS и CSS

В конфигурации system.performance отключается обработка JavaScript и CSS файлов. Это значит что о ни не будут объединяться, сжиматься и кешироваться. Так вы сможете видеть изменения на сайте сразу после их внесения без необходимости сброса кеша.

$config['system.performance']['css']['preprocess'] = FALSE;
$config['system.performance']['js']['preprocess'] = FALSE;

¶Кеш рендера

Кеш рендера отвечает за хранение результатов рендера рендер массивов. В процессе активной разработки он может доставлять серьезные неудобства, поэтому его рекомендуется отключать.

При помощи данной настройки вы можете отключить кеширование результатов перенаправляя весь кеш в Null хранилище, который ничего не хранит.

Пример:

$settings['cache']['bins']['render'] = 'cache.backend.null';

¶Кеш миграций

Кеш миграций хранит в себе информацию о всех объявленных миграциях. Если вы активно пишите миграции, вы можете переключить хранение миграций в память, чтобы они обнаруживались сразу как только вы их объявляете.

Пример:

$settings['cache']['bins']['discovery_migration'] = 'cache.backend.memory';

¶Кеш страниц

Кеш страниц, который предоставляется модулем Internal Page Cache, хранит в себе готовые результаты страниц. В процессе активной разработки он может доставлять серьезные неудобства, поэтому его рекомендуется отключать.

$settings['cache']['bins']['page'] = 'cache.backend.null';

¶Динамический кеш страниц

Динамический кеш страниц, который предоставляется модулем Dynamic Page Cache, хранит в себе готовые результаты страниц, в зависимости от роли пользователя и прочих контекстов.

$settings['cache']['bins']['dynamic_page_cache'] = 'cache.backend.null';

¶Включить обнаружение тестовых расширений

По умолчанию доступны только расширения (модули, темы оформления) которые не помечены как тестовые. При помощи данной настройки, вы можете включить их обнаружение и отображение в административном интерфейсе.

Пример:

$settings['extension_discovery_scan_tests'] = TRUE;

¶Доступ к ребилду

Drupal очень серьезно кеширует всю информацию что собирает. Даже с отключением различных кешей выше, он будет собираться. Например, информация о хуках, темплейтах, расширениях и т.д. кешируется даже в процессе разработки, так как оказывает серьезное влияние на производительность, а требуется нечасто.

Для того чтобы эти кеши были очищены нужно запустить ребилд системы. Для этого с Drupal поставляется файл rebuild.php, который не будет делать ничего, пока данная настройка отключена.

В процессе активной разработки вам потребуется регулярно запускать ребилд системы, поэтому данное поведение активируется. Для того чтобы запустить ребилд вам будет достаточно напрямую обратиться к файлу https://example.com/rebuild.php.

Пример:

$settings['rebuild_access'] = TRUE;

¶Отключение принудительного изменения прав на запись для директории сайта

По умолчанию Drupal регулярно проверяет важные директории и сбрасывает им права на запись. Это может вызвать неудобства в процессе разработки, поэтому данные проверки рекомендуется отключать.

$settings['skip_permissions_hardening'] = TRUE;

¶Смотрите также

  • settings.php — основные настройки окружения.

Понравилась статья? Поделить с друзьями:

Читайте также:

  • Drum ошибка на принтере что делать
  • Drum error принтер 2240 brother
  • Drs set setting failed nvapi setting not found как исправить
  • Drs save settings failed nvapi access denied как исправить
  • Drq error 0x0816

  • 0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии