public function match(nc_routing_request $request, nc_routing_result $result) { $infoblock_id = $result->get_infoblock_id(); if ($infoblock_id && preg_match('/^(\\d+)/', $result->get_remainder(), $matches)) { $object_id = $matches[0]; $infoblock_settings = nc_core::get_object()->sub_class->get_by_id($infoblock_id); list($object_id, $real_object_keyword) = (array) ObjectExistsByID($infoblock_settings['Class_ID'], $infoblock_settings['sysTbl'], $object_id, $result->get_resource_parameter('date'), true); if ($object_id) { $result->set_resource_parameter('object_id', $object_id); $result->set_resource_parameter('object_keyword', $real_object_keyword); $result->truncate_remainder(strlen($object_id)); return true; } } return false; }
/** * @param nc_url|string $url Объект nc_url или строка * @param string $method GET|POST * @param int|null $site_id Если null — текущий сайт * @return array|false Массив с информацией об объекте, на который ссылается путь, * или FALSE. * array( * resource_type => folder|infoblock|object|script * site_id => идентификатор сайта * folder_id => идентификатор раздела * infoblock_id => [идентификатор инфоблока] * object_id => идентификатор объекта в инфоблоке * action => действие над инфоблоком или объектом * format => html|rss|xml * variables => массив с дополнительными переменными (только для модуля маршрутизации) * date => дата в пути * script_path => путь к скрипту от папки DOCUMENT_ROOT/SUB_FOLDER (только для модуля маршрутизации для resource_type=script) * redirect_to_url => при запросе всегда будет выполняться переадресация * ) */ function nc_resolve_url($url, $method = null, $site_id = null) { $nc_core = nc_core::get_object(); $routing_module_enabled = nc_module_check_by_keyword('routing'); // --- Приведение параметра $url к nc_url --- if (!$url instanceof nc_url) { $url = new nc_url($url); } else { if (!$routing_module_enabled) { // Создадим клон $url, так как в процессе работы будут изменяться свойства этого объекта $url = clone $url; } } // --- Определение сайта --- if (!$site_id) { $site_settings = $nc_core->catalogue->get_by_host_name($url->get_parsed_url('host')); if (isset($site_settings['Catalogue_ID'])) { $site_id = $site_settings['Catalogue_ID']; } else { $site_id = $nc_core->catalogue->id(); } } if (!$site_id) { return false; } // --- Использование модуля маршрутизации --- if ($routing_module_enabled) { $result = nc_routing::resolve(new nc_routing_request($site_id, $method, $url->get_parsed_url())); if ($result) { $result = $result->to_array(); $result['site_id'] = $site_id; return $result; } else { return false; } } // --- «Классическая» маршрутизация --- $result = array('resource_type' => 'folder', 'site_id' => $site_id, 'folder_id' => null, 'infoblock_id' => null, 'object_id' => null, 'action' => null, 'format' => 'html', 'variables' => array(), 'date' => null, 'redirect_to_url' => null); // Инициализация переменных $component_id = 0; $default_action = null; $page_not_found = false; // Имя «файла» $req_file = strrchr($url->get_parsed_url('path'), '/'); // Определяем раздел по пути $result['folder_id'] = $nc_core->subdivision->get_by_uri($url->get_parsed_url('path'), $site_id, 'Subdivision_ID', true, true); // Если раздел не найден, дальнейшая обработка адреса не имеет смысла, // так как мы в любом случае должны вернуть FALSE if (!$result['folder_id']) { return false; } $file_name = ''; $file_extension = ''; $uri_date = $url->get_uri_date(); if ($req_file != '/') { $req_file = substr($req_file, 1); if (strpos($req_file, '.')) { $req_file_parts = explode(".", $req_file); $file_name = $req_file_parts[0]; $file_extension = strtolower($req_file_parts[count($req_file_parts) - 1]); } if (in_array($file_extension, array('html', 'rss', 'xml'))) { // name without extension $url->set_parsed_url_item('path', substr($url->get_parsed_url('path'), 0, strlen($url->get_parsed_url('path')) - strlen($req_file))); } else { // append trailing slash $url->set_parsed_url_item('path', rtrim($url->get_parsed_url('path'), "/") . "/"); } // Адрес имеет расширение (.html, .rss, .xml) — это адрес объекта или инфоблока if (in_array($file_extension, array('html', 'rss', 'xml'))) { $result['format'] = $file_extension; $infoblocks_in_folder = $nc_core->sub_class->get_by_subdivision_id($result['folder_id']); // keyword.html — совпадение по ключевому слову объекта if (nc_preg_match("/^([_a-zа-я0-9-]+)\$/i", $file_name, $regs)) { if (!empty($infoblocks_in_folder)) { foreach ($infoblocks_in_folder as $infoblock_settings) { if ($file_extension == 'rss' && !$infoblock_settings['AllowRSS']) { continue; } if ($file_extension == 'xml' && !$infoblock_settings['AllowXML']) { continue; } // Находим объект, подходящий под имеющиеся параметры if ($object_id = ObjectExists($infoblock_settings['Class_ID'], $infoblock_settings['sysTbl'], $infoblock_settings['Sub_Class_ID'], $file_name, $uri_date)) { $component_id = $infoblock_settings['Class_ID']; $result['resource_type'] = 'object'; $result['infoblock_id'] = $_db_cc = $infoblock_settings['Sub_Class_ID']; $result['object_id'] = $object_id; $result['action'] = 'full'; break; } } } } // news.html — ключевое слово компонента, при условии, что нет такого объекта if (!$result['object_id'] && nc_preg_match("/^([a-zа-я0-9-]+)\$/i", $file_name, $regs)) { if (!empty($infoblocks_in_folder)) { foreach ($infoblocks_in_folder as $infoblock_settings) { if ($infoblock_settings['EnglishName'] == $regs[1]) { if ($file_extension == 'rss' && !$infoblock_settings['AllowRSS']) { continue; } if ($file_extension == 'xml' && !$infoblock_settings['AllowXML']) { continue; } $result['resource_type'] = 'infoblock'; $result['infoblock_id'] = $_db_cc = $infoblock_settings['Sub_Class_ID']; // action может быть задан в get'e или post'e if (!$result['action']) { $result['action'] = $infoblock_settings['DefaultAction']; } break; } } } } // add_news.html, search_news.html, subscribe_news.html — добавление, поиск, подписка в компоненте if (nc_preg_match("/^(add|search|subscribe)_((?i:[a-zа-я0-9-]+))\$/", $file_name, $regs)) { if (!empty($infoblocks_in_folder)) { foreach ($infoblocks_in_folder as $infoblock_settings) { if ($infoblock_settings['EnglishName'] != $regs[2]) { continue; } $result['resource_type'] = 'infoblock'; $result['infoblock_id'] = $_db_cc = $infoblock_settings['Sub_Class_ID']; $result['action'] = $regs[1]; break; } } } // news_5.html — отображение объекта по компоненту и идентификатору if (nc_preg_match("/^([a-zа-я0-9-]+)_([0-9]+)\$/i", $file_name, $regs) && $file_name == $regs[1] . "_" . $regs[2]) { if (!empty($infoblocks_in_folder)) { foreach ($infoblocks_in_folder as $infoblock_settings) { // check component in sub keyword if ($infoblock_settings['EnglishName'] != $regs[1]) { continue; } if ($file_extension == 'rss' && !$infoblock_settings['AllowRSS']) { continue; } if ($file_extension == 'xml' && !$infoblock_settings['AllowXML']) { continue; } // find message with requested params if ($object_id = ObjectExistsByID($infoblock_settings['Class_ID'], $infoblock_settings['sysTbl'], $regs[2], $uri_date)) { $component_id = $infoblock_settings['Class_ID']; $result['resource_type'] = 'object'; $result['infoblock_id'] = $_db_cc = $infoblock_settings['Sub_Class_ID']; $result['object_id'] = $object_id; $result['action'] = 'full'; break; } } } } // edit_object.html — изменение объекта по ДЕЙСТВИЮ и КЛЮЧЕВОМУ СЛОВУ, при условии, что нет объекта по компоненту и идентификатору if (!$result['object_id'] && nc_preg_match("/^(edit|delete|drop|checked|subscribe)_((?i:[_a-zа-я0-9-]+))\$/", $file_name, $regs)) { if (!empty($infoblocks_in_folder)) { foreach ($infoblocks_in_folder as $infoblock_settings) { // find message with need params if ($object_id = ObjectExists($infoblock_settings['Class_ID'], $infoblock_settings['sysTbl'], $infoblock_settings['Sub_Class_ID'], $regs[2])) { $component_id = $infoblock_settings['Class_ID']; $result['resource_type'] = 'object'; $result['infoblock_id'] = $_db_cc = $infoblock_settings['Sub_Class_ID']; $result['object_id'] = $object_id; $result['action'] = $regs[1]; break; } } } } // edit_news_5.html — изменение объекта по действию, компоненту и идентификатору объекта if (nc_preg_match("/^(edit|delete|drop|checked|subscribe)_((?i:[_a-zа-я0-9-]+))_([0-9]+)\$/", $file_name, $regs)) { if (!empty($infoblocks_in_folder)) { foreach ($infoblocks_in_folder as $infoblock_settings) { // check component in sub keyword if ($infoblock_settings['EnglishName'] != $regs[2]) { continue; } // find message with need params if ($object_id = ObjectExistsByID($infoblock_settings['Class_ID'], $infoblock_settings['sysTbl'], $regs[3])) { $component_id = $infoblock_settings['Class_ID']; $result['resource_type'] = 'object'; $result['infoblock_id'] = $_db_cc = $infoblock_settings['Sub_Class_ID']; $result['object_id'] = $object_id; $result['action'] = $regs[1]; break; } } } } } else { // У «файла» нет расширения, либо нестандартное расширение // Добавить "/" и сделать переадресацию $result['redirect_to_url'] = $url->source_url() . ($url->get_parsed_url('query') ? "?" . $url->get_parsed_url('query') : "") . ($url->get_parsed_url('fragment') ? "#" . $url->get_parsed_url('fragment') : ""); } } // Для разделов установить ID первого инфоблока if ($result['resource_type'] == 'folder' && !$file_name && $result['folder_id']) { if (empty($infoblocks_in_folder)) { $infoblocks_in_folder = $nc_core->sub_class->get_by_subdivision_id($result['folder_id']); } foreach ((array) $infoblocks_in_folder as $infoblock_settings) { if ($infoblock_settings['Checked'] || $infoblock_settings['sysTbl'] == 3) { $component_id = $infoblock_settings['Class_ID']; if ($uri_date && !$nc_core->get_component($component_id)->get_date_field()) { continue; } $result['infoblock_id'] = $infoblock_settings['Sub_Class_ID']; if (!$result['action']) { $result['action'] = $infoblock_settings['DefaultAction']; } break; } } } // Если есть «имя файла», но не определён по крайней мере ID инфоблока, то это неправильный путь if ($file_name && !$result['infoblock_id']) { $page_not_found = true; } // Дата в пути if (!$page_not_found && $uri_date) { if (!$result['infoblock_id'] || $result['infoblock_id'] && !$nc_core->get_component($component_id)->get_date_field()) { // if there is a date in URI segments and no "event" field in the corresponding component, it is an incorrect path $page_not_found = true; } else { $result['date'] = $uri_date; } } return $page_not_found ? false : $result; }