Files
slava.home/main_plugin/site_tree/func.site_tree.php
2025-11-07 20:53:17 +02:00

204 lines
7.9 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
* @file func.site_tree.php
* @brief Функции для работы с деревом сайта: получение, сохранение и обработка структуры, а также получение списка папок
*/
/**
* @brief Получает структуру дерева сайта из XML-файла для текущего языка
* @param array $params Не используется, но требуется для совместимости
* @return array Массив с элементами дерева сайта, включая дочерние элементы и атрибуты
* @throws Exception Если не удалось прочитать или разобрать XML-файл, или структура не сгенерирована
*/
function getSiteTree($params) {
global $path, $_SESSION;
$file = $path . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'filepath.' . $_SESSION['lng'] . '.php';
$content = file_get_contents($file);
$xml = simplexml_load_string($content);
if (!$xml) {
throw new Exception("Problem with file", -32004);
}
function generateArray($xml, $urlParts = []) {
$result = [];
$anyOpen = false;
foreach ($xml->children() as $child) {
$item = [
'name' => (string) $child->attributes()->name,
'tag' => $child->getName(),
'children' => generateArray($child, $urlParts),
'isOpen' => false,
'url' => (string) $child->attributes()->url,
'title' => (string) $child->attributes()->title,
'template' => (string) $child->attributes()->template,
'PageMenu' => (string) $child->attributes()->PageMenu,
'users' => (string) $child->attributes()->users,
'group' => (string) $child->attributes()->group,
'news' => (string) $child->attributes()->news,
'plugins' => (string) $child->attributes()->plugins,
'content' => (string)$child
];
if (!empty($urlParts) && $urlParts[0] == $item['tag']) {
array_shift($urlParts);
if (empty($urlParts)) {
if ($item['tag'] !== 'index') {
$item['isOpen'] = true;
$anyOpen = true;
}
}
}
foreach ($item['children'] as $childItem) {
if (!empty($childItem['isOpen'])) {
$item['isOpen'] = true;
$anyOpen = true;
break;
}
}
$result[] = $item;
}
if (!$anyOpen) {
foreach ($result as &$item) {
if ($item['tag'] === 'index') {
$item['isOpen'] = true;
break;
}
}
} else {
foreach ($result as &$item) {
if ($item['tag'] === 'index') {
$item['isOpen'] = false;
}
}
}
return $result;
}
$url = $_SERVER['REQUEST_URI'];
$urlParts = array_filter(explode('/', trim($url, '/')));
$urlParts = array_map(function($part) {
return pathinfo($part, PATHINFO_FILENAME);
}, $urlParts);
$result = generateArray($xml, $urlParts);
if (!is_array($result)) {
throw new Exception("Failed to generate structure", -32003);
}
return $result;
}
/**
* @brief Сохраняет структуру дерева сайта в XML-файл для текущего языка
* @param array $params Массив с ключом 'data', содержащий структуру сайта
* @return string "true" при успешном сохранении
* @throws Exception Если не удалось сохранить файл или файл пустой
*/
function saveSiteTree($params) {
global $path, $_SESSION;
$file = $path . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'filepath.' . $_SESSION['lng'] . '.php';
$treeData = isset($params['data']) ? $params['data'] : [];
$siteName = isset($treeData['sitename']) ? htmlspecialchars($treeData['sitename'], ENT_XML1 | ENT_QUOTES, 'UTF-8') : '';
$slogan = isset($treeData['slogan']) ? htmlspecialchars($treeData['slogan'], ENT_XML1 | ENT_QUOTES, 'UTF-8') : '';
$xmlContent = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n".
"<site>\n".
" <sitename>$siteName</sitename>\n".
" <slogan>$slogan</slogan>\n".
buildSiteTreeXml($treeData['children']).
"</site>\n";
$ok = file_put_contents($file, $xmlContent);
if ($ok === false || !is_file($file) || !filesize($file)) {
throw new Exception("Failed to save file", -32004);
}
return 'true';
}
/**
* @brief Рекурсивно строит XML для структуры сайта
* @param array $data Массив с элементами дерева сайта
* @param int $level Уровень вложенности для отступов
* @return string Строка XML, представляющая элементы дерева
*/
function buildSiteTreeXml($data, $level = 1) {
$xml = "";
foreach ($data as $item) {
if (!isset($item['name']) || empty($item['name'])) continue;
$tag = htmlspecialchars(trim(explode(' ', $item['name'])[0]), ENT_XML1 | ENT_QUOTES, 'UTF-8');
$nameAttr = htmlspecialchars(trim($tag), ENT_XML1 | ENT_QUOTES, 'UTF-8');
$attributes = [
'url' => isset($item['url']) ? htmlspecialchars($item['url'], ENT_XML1 | ENT_QUOTES, 'UTF-8') : '',
'title' => isset($item['title']) ? htmlspecialchars($item['title'], ENT_XML1 | ENT_QUOTES, 'UTF-8') : '',
'name' => $nameAttr,
'template' => isset($item['template']) ? htmlspecialchars($item['template'], ENT_XML1 | ENT_QUOTES, 'UTF-8') : '',
'PageMenu' => isset($item['PageMenu']) ? htmlspecialchars($item['PageMenu'], ENT_XML1 | ENT_QUOTES, 'UTF-8') : '',
'users' => isset($item['users']) ? htmlspecialchars($item['users'], ENT_XML1 | ENT_QUOTES, 'UTF-8') : '',
'group' => isset($item['group']) ? htmlspecialchars($item['group'], ENT_XML1 | ENT_QUOTES, 'UTF-8') : '',
'news' => isset($item['news']) ? htmlspecialchars($item['news'], ENT_XML1 | ENT_QUOTES, 'UTF-8') : '',
'plugins' => isset($item['plugins']) ? htmlspecialchars($item['plugins'], ENT_XML1 | ENT_QUOTES, 'UTF-8') : ''
];
$attrString = "";
foreach ($attributes as $key => $value) {
$attrString .= " $key='$value'";
}
$xml .= str_repeat(" ", $level) . "<$tag$attrString>\n";
if (!empty($item['children'])) {
$xml .= buildSiteTreeXml($item['children'], $level + 1);
}
$xml .= str_repeat(" ", $level) . "</$tag>\n";
}
return $xml;
}
/**
* @brief Получает список папок внутри указанной директории
* @param array $params Массив с ключом 'folder', указывающим путь к директории
* @return array Массив с именами папок
* @throws Exception Если директория недействительна или невозможно прочитать содержимое
*/
function getFolders($params) {
global $path;
$folder = $path . DIRECTORY_SEPARATOR . $params['folder'];
$folders = [];
$ok = true;
if (!is_dir($folder)) {
$ok = false;
} else {
$files = scandir($folder);
if ($files === false) {
$ok = false;
} else {
foreach ($files as $file) {
if ($file != '.' && $file != '..' && is_dir($folder . DIRECTORY_SEPARATOR . $file)) {
$folders[] = $file;
}
}
}
}
if (!$ok) {
throw new Exception("Failed to read folder list", -32004);
}
return $folders;
}
?>