<?php
/**
    * @file func.editor.php
    * @brief Содержит серверные функции для плагина редактора
*/

/**
    * @brief Сохраняет содержимое центрального блока страницы
    * @param array $params Массив с данными для сохранения, включая ключ 'saveContentIdData'
    * @return string 'true' в случае успешного сохранения
    * @throws Exception В случае проблем с сохранением контента
*/
function savePageCenterBlock($params) {
    global $config, $path, $_SESSION;

    $saveContentIdXml = $path . $_SESSION['page_url'] . ".page.php";
    $saveContentIdData = $params['saveContentIdData'] ?? '';
    $file = @simplexml_load_file($saveContentIdXml);
    $node = $file->content->{$_SESSION['lng']};

    $file->content->{$_SESSION['lng']} = '';
    $node = dom_import_simplexml($node);
    $doc = $node->ownerDocument;
    $appended = $node->appendChild($doc->createCDATASection("\n" . $saveContentIdData . "\n"));
    $saved = $file->asXML($saveContentIdXml);

    if ($appended && $saved) {
        return 'true';
    }

    throw new Exception("Problem saving content", -32003);
}

/**
    * @brief Сохраняет левый и правый блоки страницы
    * @param array $params Массив с данными блоков, ключ 'floatsBlock' содержит массив левых и правых блоков
    * @return string 'true' в случае успешного сохранения
    * @throws Exception В случае проблем с сохранением блоков
*/
function savePageSideBlocks($params) {
    global $config, $path, $_SESSION;

    $saveContentIdXml = $path . $_SESSION['page_url'] . ".page.php";
    $file = @simplexml_load_file($saveContentIdXml);

    $floatsBlock = json_decode($params['floatsBlock'] ?? '[]', true);
    $left  = $floatsBlock['left']  ?? [];
    $right = $floatsBlock['right'] ?? [];

    unset($file->lblock->block, $file->rblock->block);

    foreach ($left as $d) {
        $b = $file->lblock->addChild('block');
        $b->addAttribute('url',   htmlspecialchars($d['pluginUrl'] ?? '', ENT_QUOTES, 'UTF-8'));
        $b->addAttribute('title', htmlspecialchars($d['title']     ?? '', ENT_QUOTES, 'UTF-8'));
        $b->addAttribute('tclass',htmlspecialchars($d['tclass']    ?? '', ENT_QUOTES, 'UTF-8'));
        $b->addAttribute('bclass',htmlspecialchars($d['bclass']    ?? '', ENT_QUOTES, 'UTF-8'));
    }
    foreach ($right as $d) {
        $b = $file->rblock->addChild('block');
        $b->addAttribute('url',   htmlspecialchars($d['pluginUrl'] ?? '', ENT_QUOTES, 'UTF-8'));
        $b->addAttribute('title', htmlspecialchars($d['title']     ?? '', ENT_QUOTES, 'UTF-8'));
        $b->addAttribute('tclass',htmlspecialchars($d['tclass']    ?? '', ENT_QUOTES, 'UTF-8'));
        $b->addAttribute('bclass',htmlspecialchars($d['bclass']    ?? '', ENT_QUOTES, 'UTF-8'));
    }

    $dom = new DOMDocument('1.0', 'UTF-8');
    $dom->preserveWhiteSpace = false;
    $dom->formatOutput = true;
    $dom->loadXML($file->asXML());
    $ok = $dom->save($saveContentIdXml);

    if ($ok) {
        return 'true';
    }

    throw new Exception("Problem saving floats block", -32003);
}

/**
    * @brief Сохраняет заголовок страницы
    * @param array $params Массив с данными для сохранения, ключ 'newTitle' содержит новый заголовок
    * @return string 'true' в случае успешного сохранения
    * @throws Exception В случае проблем с сохранением заголовка или если узел не найден
*/
function savePageTitle($params) {
    global $config, $path, $_SESSION;

    $newTitle = htmlspecialchars($params['newTitle'] ?? '', ENT_QUOTES, 'UTF-8');
    $filePath = $path . "data/filepath." . $_SESSION['lng'] . ".php";
    $file = @simplexml_load_file($filePath);

    $fileNode = rtrim($config['REQUEST_URI'], '.html');
    $nodes    = array_filter(explode('/', $fileNode));
    $node     = $file->index;
    $current  = 'index';

    foreach ($nodes as $n) {
        if ($n !== '' && isset($node->$n)) {
            $node = $node->$n;
            $current .= '->' . $n;
        } else {
            $error = "Node not found: $current->$n";
            break;
        }
    }

    if (isset($error)) {
        throw new Exception($error, -32602);
    }

    $node['title'] = $newTitle;
    $saved = $file->asXML($filePath);

    if ($saved) {
        return 'true';
    }

    throw new Exception("Problem saving title", -32003);
}

/**
    * @brief Сохраняет весь контент страницы, включая центральный блок, боковые блоки и атрибуты
    * @param array $params Массив с данными страницы, включая 'page_url', 'nameFile', 'saveContentIdData', 'floatsBlock', 'title', 'pluginUrl', 'tclass', 'bclass'
    * @return string 'true' в случае успешного сохранения
    * @throws Exception В случае проблем с сохранением содержимого страницы
*/
function saveHowPageContent($params) {
    global $config, $path, $_SESSION;

    $_SESSION['page_url'] = $params['page_url'] . str_replace('.page.php', '', $params['nameFile']);
    $filePath = $path . $params['page_url'] . $params['nameFile'];
    $contentData = $params['saveContentIdData'] ?? '';
    $file = simplexml_load_file($filePath);
    $langNode = $file->content->{$_SESSION['lng']};
    $file->content->{$_SESSION['lng']} = '';
    $node = dom_import_simplexml($langNode);
    $doc = $node->ownerDocument;
    $node->appendChild($doc->createCDATASection("\n" . $contentData . "\n"));

    $file->rblock = '';
    $file->lblock = '';
    $blocks   = $params['floatsBlock'] ?? [];
    $titles   = $params['title']       ?? [];
    $urls     = $params['pluginUrl']   ?? [];
    $tclasses = $params['tclass']      ?? [];
    $bclasses = $params['bclass']      ?? [];
    foreach ($blocks as $i => $blockName) {
        $newBlock = $file->$blockName->addChild('block');
        $newBlock->addAttribute('url',   htmlspecialchars($urls[$i] ?? '',   ENT_QUOTES,'UTF-8'));
        $newBlock->addAttribute('title', htmlspecialchars($titles[$i] ?? '', ENT_QUOTES,'UTF-8'));
        $newBlock->addAttribute('tclass',htmlspecialchars($tclasses[$i] ?? '',ENT_QUOTES,'UTF-8'));
        $newBlock->addAttribute('bclass',htmlspecialchars($bclasses[$i] ?? '',ENT_QUOTES,'UTF-8'));
    }

    $dom = new DOMDocument('1.0','UTF-8');
    $dom->preserveWhiteSpace = false;
    $dom->formatOutput = true;
    $dom->loadXML($file->asXML());

    $saved = $dom->save($filePath);
    if ($saved === false) {
        throw new Exception("Failed to save content", -32003);
    }
    return 'true';
}

/**
    * @brief Создаёт новую страницу на основе шаблона
    * @param array $params Массив с данными страницы, включая 'page_url', 'nameFile', 'saveContentIdData'
    * @return string 'true' в случае успешного создания страницы
    * @throws Exception В случае ошибок при создании файла или записи XML
*/
function createNewPage($params) {
    global $config, $path, $_SESSION;

    $_SESSION['page_url'] = $params['page_url'] . str_replace('.page.php', '', $params['nameFile']);
    $saveContentIdXml = $path . $params['page_url'] . $params['nameFile'];
    $templatePage = $path . "data/template.page.php";
    $saveContentIdData = $params['saveContentIdData'] ?? '';
    $templateContent = file_get_contents($templatePage);
    if ($templateContent === false || file_put_contents($saveContentIdXml, $templateContent) === false) {
        throw new Exception("Failed to create file", -32004);
    }

    $file = simplexml_load_file($saveContentIdXml);
    $node = $file->content->{$_SESSION['lng']};
    $file->content->{$_SESSION['lng']} = '';
    $node = dom_import_simplexml($node);
    $no = $node->ownerDocument;
    $node->appendChild($no->createCDATASection("\n" . $saveContentIdData . "\n"));

    $saved = $file->asXML($saveContentIdXml);
    if ($saved === false) {
        throw new Exception("Failed to write XML", -32003);
    }
    return 'true';
}

/**
    * @brief Проверяет существование файла по указанному пути
    * @param array $params Массив с данными проверки, включая 'path' и 'nameFile'
    * @return string "true" если файл существует, иначе "false"
    * @throws Exception В случае некорректного пути
*/
function checkFile($params) {
    global $path;

    $rel = trim($params['path'], "/\\");
    if ($rel !== '' && strpos($rel, '..') !== false) {
        throw new Exception("Invalid path", -32602);
    }

    $name = basename($params['nameFile']);
    $full = rtrim($path, DIRECTORY_SEPARATOR)
          . ($rel !== '' ? DIRECTORY_SEPARATOR . $rel : '')
          . DIRECTORY_SEPARATOR . $name;

    return file_exists($full) ? "true" : "false";
}

/**
    * @brief Создаёт новый плагин с базовым шаблоном
    * @param array $params Массив с данными плагина, включая 'pluginName'
    * @return string Сообщение о создании плагина или "false", если плагин уже существует
    * @throws Exception В случае отсутствия имени плагина или ошибок записи файла
*/
function createPlugin($params) {
    $pluginName = $params['pluginName'] ?? '';
    $baseDir    = __DIR__ . '/../../plugin/';

    if ($pluginName === '') {
        throw new Exception("Missing pluginName", -32602);
    }

    $dir = $baseDir . $pluginName;
    if (!is_dir($dir)) {
        umask(0);
        $stub = "<?php\n echo '<div class=\"pluginEditable\" contenteditable=\"true\"></div>'; \n?>";
        if (file_put_contents("$dir/plug.php", $stub) === false) {
            throw new Exception("Failed to write plug.php", -32004);
        }
        return "Plugin created: $pluginName";
    }

    return "false";
}

/**
    * @brief Получает содержимое плагина
    * @param array $params Массив с данными плагина, включая 'pluginName2'
    * @return string HTML-контент плагина
    * @throws Exception В случае если файл плагина не найден
*/
function getPlugin($params) {
    $pluginName = $params['pluginName2'] ?? '';
    $file       = __DIR__ . '/../../plugin/' . $pluginName . '/plug.php';
    if (!is_file($file)) {
        throw new Exception("Plugin not found", -32602);
    }
    ob_start();
    include $file;
    return ob_get_clean();
}

/**
    * @brief Загружает изображение пользователя из Base64 и сохраняет на сервер
    * @param array $params Массив с данными изображения, включая 'userImgBase64' и 'userImgName'
    * @return string Путь к сохранённому изображению
    * @throws Exception В случае ошибок при сохранении изображения
*/
function uploadImage($params) {
    global $config, $path, $_SESSION;
    $base64  = $params['userImgBase64'] ?? '';
    $filename= $params['userImgName']   ?? 'image.png';
    $uploaddir = 'img/users_img/' . ($_SESSION['username'] ?? '') . '/';
    $name      = pathinfo($filename, PATHINFO_FILENAME);
    $ext       = pathinfo($filename, PATHINFO_EXTENSION) ?: 'png';
    $target    = $uploaddir . $name . '.' . $ext;
    $i = 1;
    while (file_exists($target)) {
        $target = $uploaddir . $name . "_$i." . $ext;
        $i++;
    }
    $data = base64_decode($base64, true);
    if (file_put_contents($target, $data) === false) {
        throw new Exception("Error saving image", -32004);
    }
    return $target;
}

?>