204 lines
7.9 KiB
PHP
204 lines
7.9 KiB
PHP
<?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;
|
||
}
|
||
|
||
?>
|