<?php

$cms["modules"]["comments.mod.php"] = array(
    "name"        => "comments_module_name",
    "description" => "comments_module_description",
    "files"       => array(
        ".cms/mod/comments.mod.php",
        ".cms/js/comments.js",        // скрипт фронтэнда
        ".cms/js/comments_admin.js",
        ".cms/css/comments.css",      // стили фронтэнда
        ".cms/css/comments_admin.less",
        ".cms/css/comments_admin.css",
        ".cms/lang/ru_RU.UTF-8/comments.mod.php",
        ".cms/lang/en_US.UTF-8/comments.mod.php",
        ".cms/lang/uk_UA.UTF-8/comments.mod.php",
    ),
);

// Return if module disabled
if ( ! empty( $cms["config"]["comments.mod.php"]["disabled"] ) ) {
    return;
}

if ( is_admin() ) {
    
    // Количество комментариев выводимое в админке
    if ( empty( $_COOKIE["comments_pager"] ) ) {
        cms_set_sess_cookie( "comments_pager", 100 );
    }
    
    hook_add_fn( "create_tables", "cms_comments_create_tables" );
    hook_add_fn( "admin_header",  "cms_comments_admin_header" );
    hook_add_fn( "admin",         "cms_comments_admin" );
    hook_add_fn( "api",           "cms_comments_admin_api" );
}
hook_add_fn( "template", "cms_comments_on_page", 20 );

hook_add_fn( "comments", "cms_comments_on_page_api" );
$cms["urls"]["^{$cms["base_path"]}comments_api$"] = "comments";

if ( ! isset( $cms["config"]["comments.mod.php"] ) ) {
    $cms["config"]["comments.mod.php"] = array();
}
$conf = &$cms["config"]["comments.mod.php"];

// Модерация = off
if ( ! isset( $conf["moderation"] ) ) {
    $conf["moderation"] = false;
}

// 100 комментариев на странице
// Так мало чтобы если начали спамить, то не пришлось бы удалять 1000
if ( empty( $conf["comments_per_page"] ) ) {
    $conf["comments_per_page"] = 100;
}

// Email, на который отправлять уведомления о новых сообщениях
if ( ! isset( $conf["email"] ) ) {
    $conf["email"] = "";
}

// SMTP Host
if ( ! isset( $conf["smtp_host"] ) ) {
    $conf["smtp_host"] = "ssl://smtp.yandex.ru";
}

// SMTP Port
if ( ! isset( $conf["smtp_port"] ) ) {
    $conf["smtp_port"] = "465";
}

// SMTP Login
if ( ! isset( $conf["smtp_login"] ) ) {
    $conf["smtp_login"] = "";
}

// SMTP Password
if ( ! isset( $conf["smtp_password"] ) ) {
    $conf["smtp_password"] = "";
}


function cms_comments_create_tables() {
    global $cms;

    if ( empty( $cms["pdo"] ) ) {
        return;
    }

    $db_type = $cms["pdo"]->getAttribute( PDO::ATTR_DRIVER_NAME );

    if ( $db_type === "mysql" ) {
        $id_column = "id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY";
        $text_column = "text LONGTEXT NOT NULL";
    } elseif ( $db_type === "pgsql" ) {
        $id_column = "id BIGSERIAL PRIMARY KEY";
        $text_column = "text TEXT NOT NULL";
    } else {
        return; // Неизвестный тип БД
    }

    // TIMESTAMP - общий знаменатель для mysql и pgsql
    $sql_comments = "
    CREATE TABLE IF NOT EXISTS comments (
        {$id_column},
        pid INT NOT NULL,
        rid INT NOT NULL,
        created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
        name VARCHAR(32) NOT NULL DEFAULT '',
        email VARCHAR(32) NOT NULL DEFAULT '',
        uid VARCHAR(36) NOT NULL DEFAULT '',
        published TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
        {$text_column}
    );";

    $sql_banned = "
    CREATE TABLE IF NOT EXISTS comments_banned_uids (
        {$id_column},
        name VARCHAR(32) NOT NULL DEFAULT '',
        uid VARCHAR(36) NOT NULL UNIQUE,
        date TIMESTAMP NOT NULL
    );";

    try {
        $cms["pdo"]->exec( $sql_comments );
        $cms["pdo"]->exec( $sql_banned );
    } catch ( PDOException $e ) {
        error_log( $e->getMessage() );
    }
}

function cms_comments_admin_header() {
    global $cms;
    if ( is_admin_header_on( "comments.mod.php" ) ) {
        echo "        <link rel=stylesheet href='{$cms["base_path"]}css/comments_admin.css'>\n";
        echo "        <script src='{$cms["base_path"]}js/comments_admin.js'></script>\n";
    }
}

function cms_comments_admin() {
    global $cms;

    $conf = $cms["config"]["comments.mod.php"]["menu"]["comments"];
    $visible = empty( $conf["hide"] );
    $section_visible = empty( $cms["config"]["admin_sections"][ $conf["section"] ]["hide"] );
    if ( $visible && $section_visible ) {

        $conf = &$cms["config"]["comments.mod.php"];

        if ( $conf["moderation"] ) {
            $moderation = "checked";
        } else {
            $moderation = "";
        }

        $page = "
        <div class=header>
            " . widget( "search_widget.html" ) . "
            <div></div>
            <div class='button settings icon'>
                <span></span>
            </div>
            <div class='button trash icon'>
                <span></span>
            </div>
        </div>
        <div class=main>
            <div class=comments>
            </div>
        </div>
        " . widget( "footer_pager.html" ) . "

        <div class='settings panel hidden'>
            <div class=header>
                <div class=title>" . __( "comments_settings" ) . "</div>
                <div class='button close icon'>
                    <span></span>
                </div>
            </div>

            <div>" . __( "help" ) . "</div>
            <label>
                <input type=checkbox name=moderation {$moderation}> " . __( "moderation" ) . "
            </label>
            <div class=groups>
                <div class=group>
                    <div>" . __( "send_to_email" ) . "</div>
                    <input type=text name=email value='{$conf["email"]}' autocomplete=off>
                </div>
                <div class=group>
                    <div>" . __( "smtp_host" ) . "</div>
                    <input type=text name=smtp_host value='{$conf["smtp_host"]}' autocomplete=off>
                </div>
                <div class=group>
                    <div>" . __( "smtp_port" ) . "</div>
                    <input type=text name=smtp_port value='{$conf["smtp_port"]}' autocomplete=off>
                </div>
                <div class=group>
                    <div>" . __( "smtp_login" ) . "</div>
                    <input type=text name=smtp_login value='{$conf["smtp_login"]}' autocomplete=off>
                </div>
                <div class=group>
                    <div>" . __( "smtp_password" ) . "</div>
                    <div class='password widget'>
                        <input type=password name=smtp_password value='{$conf["smtp_password"]}' autocomplete=off>
                        <div class=button><span></span></div>
                    </div>
                </div>
                <div class=group>
                    <div>" . __( "comments_count" ) . "</div>
                    <input type=text name=comments_per_page value={$conf["comments_per_page"]}>
                </div>
            </div>
            <div class='save button'>
                <span>" . __( "save" ) . "</span>
            </div>
            
            <div class=title>" . __( "ban_list" ) . "</div>
            <div class=banned></div>
        </div>";

        // Create menu item if not exists
        if ( empty( $conf["menu"]["comments"] ) ) {
            $conf["menu"]["comments"] = array(
                "title"    => "comments_module_name",
                "sort"     => 20,
                "section"  => "content",
            );
            cms_save_config();
        }

        $cms["admin_pages"]["comments"] = $page;

    }
}

function cms_comments_admin_api() {
    global $cms;

    if ( empty( $cms["pdo"] ) ) {
        return;
    }

    if ( ! empty( $_POST["fn"] ) ) {
        
        switch ( $_POST["fn"] ) {
            
            case "get_comments_list":
                // Условия и значения поиска
                $search_cond   = array();
                $search_params = array();

                // Смещение
                if ( isset( $_POST["offset"] ) ) {
                    $offset = (int) $_POST["offset"];
                } else {
                    $offset = 0;
                }

                // Количество
                if ( ! empty( $_POST["count"] ) ) {
                    $limit = (int) $_POST["count"];
                } elseif ( ! empty( $_COOKIE["comments_pager"] ) ) {
                    $limit = (int) $_COOKIE["comments_pager"];
                } else {
                    $limit = 100;
                }

                if ( ! empty( $_POST["search"] ) ) {
                    $search = $_POST["search"];
                
                    // Shift разбивает искомое на символы
                    if ( $_POST["Shift"] === "true" ) {
                        $search = preg_replace( "/\s/u", "", $search );
                        $search = preg_split( '//u', $search, -1, PREG_SPLIT_NO_EMPTY );
                        $search = implode( "%", $search );
                    }

                    $search = "%" . $search . "%";

                    array_push( $search_cond, "( name LIKE ? OR text LIKE ? OR email LIKE ? )" );
                    array_push( $search_params, $search, $search, $search );
                }

                // Количество комментариев
                try {
                    $query = "SELECT COUNT(*) FROM comments";
                    if ( count( $search_cond ) > 0 ) {
                        $query .= " WHERE " . implode( " AND ", $search_cond );
                    }
                    $stmt = $cms["pdo"]->prepare( $query );
                    $stmt->execute( $search_params );
                    $count = $stmt->fetchColumn();
                } catch ( PDOException $e ) {
                    error_log( $e->getMessage() );
                    break;
                }

                $comments = array();
                $start = microtime( true );
                $overload = false;
                $notify_html = "";
                
                try {
                    $query = "SELECT * FROM comments";
                    if ( count( $search_cond ) > 0 ) {
                        $query .= " WHERE " . implode( " AND ", $search_cond );
                    }
                    $query .= " ORDER BY id DESC LIMIT ? OFFSET ?";
        
                    if ( $cms["pdo"]->getAttribute( PDO::ATTR_DRIVER_NAME ) === "mysql" ) {
                        $query = str_replace( "LIMIT ? OFFSET ?", "LIMIT {$limit} OFFSET {$offset}", $query );
                    } else {
                        array_push( $search_params, $limit, $offset );
                    }

                    $stmt = $cms["pdo"]->prepare( $query );
                    $stmt->execute( $search_params );
                    
                    $tr_lost          = __( "lost_comments" );
                    $tr_ban           = __( "ban" );
                    $tr_delete        = __( "delete" );
                    $tr_publish       = __( "publish" );
                    $tr_unpublish     = __( "unpublish" );
                    $tr_reply_deleted = __( "reply_deleted" );
                
                    while ( $comment = $stmt->fetch( PDO::FETCH_ASSOC ) ) {

                        $stmt2 = $cms["pdo"]->prepare( "SELECT title, url FROM pages WHERE id=?" );
                        $stmt2->execute( array( $comment["pid"] ) );
                        $page = $stmt2->fetch( PDO::FETCH_ASSOC );
                        if ( $page ) {
                            $link = "<a href='{$cms["base_path"]}{$page["url"]}#comment-{$comment["id"]}' target=_blank>{$page["title"]}</a>";
                        } else {
                            $link = $tr_lost;
                        }

                        $time = strtotime( $comment["created"] );
                        $created = format_date( $time );
                        if ( $comment["published"] ) {
                            $tr_publish_btn = $tr_unpublish;
                            $pub_class      = "published";
                        } else {
                            $tr_publish_btn = $tr_publish;
                            $pub_class      = "unpublished";
                        }
                        if ( empty( $comment["email"] ) ) {
                            $email = "";
                        } else {
                            $email = " <span class=email>&lt;{$comment["email"]}&gt;</span>";
                        }

                        // Извлекаем цитируемое сообщение
                        if ( $comment["rid"] ) {
                            $stmt2 = $cms["pdo"]->prepare( "SELECT * FROM comments WHERE id=?" );
                            $stmt2->execute( array( $comment["rid"] ) );
                            $reply_comment = $stmt2->fetch( PDO::FETCH_ASSOC );
                            if ( ! $reply_comment ) {
                                $cite = "
                                <div class=cite data-id=''>
                                    <div class=cite-text>{$tr_reply_deleted}</div>
                                </div>";
                            } else {
                                $max_len = 10000;
                                if ( mb_strlen( $reply_comment["text"] ) > $max_len ) {
                                    $reply_comment["text"] = mb_substr( $reply_comment["text"], 0, $max_len ) . "...";
                                }
                                $cite = "
                                <div class=cite data-id={$reply_comment["id"]}>
                                    <div class=cite-author>{$reply_comment["name"]}</div>
                                    <div class=cite-text>{$reply_comment["text"]}</div>
                                </div>";
                            }
                            $with_cite = " withcite";
                        } else {
                            $cite = "";
                            $with_cite = "";
                        }
                        
                        $html = "
                        <div class='comment {$pub_class}{$with_cite}' data-id={$comment["id"]} data-uid={$comment["uid"]}>
                            <div class=created>{$created}</div>
                            <div class='public button'>
                                <span>{$tr_publish_btn}</span>
                            </div>
                            <input type=checkbox>
                            <div class=link>
                                <span class=page>" . __( "page" ) . ":</span>
                                {$link}
                            </div>
                            <div class=user>
                                <span class=author>" . __( "author" ) . ":</span>
                                <span class=name>{$comment["name"]}</span>
                                {$email}
                                <span class='ban button'>
                                    <span>{$tr_ban}</span>
                                </span>
                            </div>
                            {$cite}
                            <div class=text>{$comment["text"]}</div>
                        </div>";

                        array_push( $comments,
                            array(
                                "id" => (int) $comment["id"],
                                "html" => $html
                            )
                        );

                        if ( microtime( true ) - $start > 1 ) {
                            $overload = true;
                            $notify_html = __( "server_overloaded_xxx" );
                            $notify_html = str_replace( "xxx", count( $comments ), $notify_html );
                            break;
                        }
                    }
                    
                    if ( isset( $_POST["search"] ) ) {
                        $search = trim( $_POST["search"] );
                    } else {
                        $search = "";
                    }
                    
                    echo( json_encode( array(
                        "result" => array(
                            "comments"    => $comments,
                            "offset"      => $offset, 
                            "count"       => $count, 
                            "overload"    => $overload,
                            "search"      => $search,
                            "notify_html" => $notify_html,
                        )
                    ) ) );
                } catch ( PDOException $e ) {
                    error_log( $e->getMessage() );
                }

            break;

            case "get_banned_list":
                // Показывать последних 100 забаненных
                $limit = 100;

                $ban_list = array();
                $q = "SELECT * FROM comments_banned_uids ORDER BY id DESC";
                try {
                    $stmt = $cms["pdo"]->query( $q );
                    while ( $limit > 0 and $banned = $stmt->fetch( PDO::FETCH_ASSOC ) ) {
                        $date = format_date( strtotime( $banned["date"] ) );

                        $html = "
                        <div data-id={$banned["id"]}>
                            <div class='delete button'>
                                <span></span>
                            </div>
                            <div class=date>{$date}</div>
                            <div class=name>{$banned["name"]}</div>
                        </div>";

                        array_push( $ban_list,
                            array(
                                "id" => (int) $banned["id"],
                                "html" => $html
                            )
                        );

                        $limit--;
                    }

                    echo( json_encode( array(
                        "result" => array(
                            "ban_list" => $ban_list,
                        )
                    ) ) );
                } catch ( PDOException $e ) {
                    error_log( $e->getMessage() );
                }

            break;

            case "comment_publish":

                $id = (int) $_POST["id"];
                try {
                    $stmt = $cms["pdo"]->prepare( "SELECT * FROM comments WHERE id=?" );
                    $stmt->execute( array( $id ) );
                    $comment = $stmt->fetch( PDO::FETCH_ASSOC );

                    if ( $comment["published"] ) {
                        $date = NULL;
                        $msg  = __( "unpublished" );
                        $button_text = __( "publish" );
                    } else {
                        $date = date( "Y-m-d H:i:sP" );
                        $msg  = __( "published" );
                        $button_text = __( "unpublish" );
                    }
                    $stmt = $cms["pdo"]->prepare( "UPDATE comments SET published=? WHERE id=?" );
                    $stmt->execute( array( $date, $id ) );

                    if ( function_exists( "cms_clear_cache" ) ) {
                        cms_clear_cache();
                    }

                    echo( json_encode( array(
                        "result" => array(
                            "notify_html" => $msg,
                            "button_text" => $button_text,
                            "date" => $date,
                        )
                    ) ) );

                } catch ( PDOException $e ) {
                    error_log( $e->getMessage() );
                }

            break;

            case "comment_ban":

                $uid  = $_POST["uid"];
                $name = $_POST["name"];
                $date = date( "Y-m-d H:i:sP" );
                
                try {
                    $stmt = $cms["pdo"]->prepare( "INSERT INTO comments_banned_uids (uid, name, date) VALUES (?, ?, ?)" );
                    $stmt->execute( array( $uid, $name, $date ) );
                    echo( json_encode( array(
                        "result" => array(
                            "notify_html" => __( "commentator_blocked" ),
                        )
                    ) ) );
                } catch ( PDOException $e ) {
                    if ( $e->getCode() == 23000 ) {
                        echo( json_encode( array(
                            "error" => array(
                                "notify_html" => __( "already_blocked" ),
                            )
                        ) ) );
                    } else {
                        error_log( $e->getMessage() );
                    }
                }
                
            break;

            case "comment_unban":

                $id = (int) $_POST["id"];
                try {
                    $stmt = $cms["pdo"]->prepare( "DELETE FROM comments_banned_uids WHERE id=?" );
                    $stmt->execute( array( $id ) );
                } catch ( PDOException $e ) {
                    error_log( $e->getMessage() );
                    break;
                }

                echo( json_encode( array(
                    "result" => array(
                        "notify_html"  => __( "commentator_unblocked" ),
                    )
                ) ) );

            break;

            case "del_comments":

                try {
                    $stmt = $cms["pdo"]->prepare( "DELETE FROM comments WHERE id=?" );
                    foreach( $_POST["ids"] as $id ) {
                        // Тут правильно что присваивание, 0 тоже нужно исключить
                        if ( $id = (int) $id ) {
                            $stmt->execute( array( $id ) );
                        }
                    }
                } catch ( PDOException $e ) {
                    error_log( $e->getMessage() );
                    break;
                }

                // Clear cache
                if ( function_exists( "cms_clear_cache" ) ) {
                    cms_clear_cache();
                }

                echo( json_encode( array(
                    "result" => array(
                        "notify_html"  => __( "comments_deleted" ),
                    )
                ) ) );

            break;

            case "comments_save_settings":

                $conf = &$cms["config"]["comments.mod.php"];

                $conf["moderation"]        = $_POST["moderation"] == "true";
                $conf["email"]             = $_POST["email"];
                $conf["smtp_host"]         = $_POST["smtp_host"];
                $conf["smtp_port"]         = $_POST["smtp_port"];
                $conf["smtp_login"]        = $_POST["smtp_login"];
                $conf["smtp_password"]     = $_POST["smtp_password"];
                $conf["comments_per_page"] = (int) $_POST["comments_per_page"];

                cms_save_config();

                if ( function_exists( "cms_clear_cache" ) ) {
                    cms_clear_cache();
                }

                echo( json_encode( array(
                    "result" => array(
                        "notify_html"  => __( "settings_saved" ),
                    )
                ) ) );

            break;

        }

    }

}

function cms_comments_on_page() {
    global $cms;

    $regular_page =
        ! empty( $cms["output"] )
        && ! is_array( $cms["output"] )
        && $cms["url"]["path"] !== $cms["config"]["admin.mod.php"]["admin_url"];

    // Comments
    if ( $regular_page && preg_match( "/(.*)(<!--\s*comments\s*-->)(.*)/us", $cms["output"], $matches ) ) {
        
        try {
            $stmt = $cms["pdo"]->prepare( "SELECT * FROM comments WHERE pid=? ORDER BY id" );
            $stmt->execute( array( $cms["page"]["id"] ) );

            $comments = [];
            $comments_count = 0;
            $max_len = 200;

            $tr_reply = __( "reply" );
            $tr_reply_deleted = __( "reply_deleted" );

            $comments_arr = array();
            while ( $comment = $stmt->fetch( PDO::FETCH_ASSOC ) ) {

                $comments_arr[ $comment["id"] ] = $comment;

                if ( mb_strlen( $comments_arr[ $comment["id"] ]["text"] ) > $max_len ) {
                    $comments_arr[ $comment["id"] ]["text"] = mb_substr( $comments_arr[ $comment["id"] ]["text"], 0, $max_len ) . "...";
                }

                if ( $comment["published"] ) {
                    // Ответ на комментарий
                    if ( $comment["rid"] ) {
                        if ( empty( $comments_arr[ $comment["rid"] ] ) ) {
                            // Комментарий, на который отвечают удален
                            $cite = "
                            <div class=cite data-id={$comment["rid"]}>
                                <div class=cite-text>{$tr_reply_deleted}</div>
                            </div>";
                        } else {
                            $cite = "
                            <div class=cite data-id={$comment["rid"]}>
                                <div class=cite-author>{$comments_arr[ $comment["rid"] ]["name"]}</div>
                                <div class=cite-text>{$comments_arr[ $comment["rid"] ]["text"]}</div>
                            </div>";
                        }
                        $with_cite = " withcite";
                    } else {
                        $cite = "";
                        $with_cite = "";
                    }

                    $time = strtotime( $comment["created"] );
                    $date = format_date( $time );
                    $comments[] = "
                        <div id=comment-{$comment["id"]} class='comment{$with_cite}' data-id={$comment["id"]}>
                            <div class=time>{$date}</div>
                            <div class=author>{$comment["name"]}</div>
                            {$cite}
                            <div class=text>{$comment["text"]}</div>
                            <div class=reply>{$tr_reply}</div>
                        </div>";
                }
                $comments_count++;
            }

            $comments = implode( $comments );

            $tr_reply = __( "leave_comment" );
            $comments .= "<div class=leave-comment-btn>{$tr_reply}</div>";

            $comments = "<div class=comments>{$comments}</div>";

            $cms["output"] = $matches[1] . $comments . $matches[3];

            // Загрузка альтернативного файла стилей из папки шаблона
            if ( file_exists( $cms["cms_dir"] . "/{$cms["template"]}/comments.css" ) ) {
                $comments_styles = file_get_contents( $cms["cms_dir"] . "/{$cms["template"]}/comments.css" );
            } else {
                $comments_styles = file_get_contents( $cms["cms_dir"] . "/css/comments.css" );
            }

            $cms["output"] = str_replace( "</head>", "<style>\n{$comments_styles}\n</style>\n</head>", $cms["output"] );
            $comments_script = file_get_contents( $cms["cms_dir"] . "/js/comments.js" );
            // При ошибке $tr === false - что ок.
            $tr = json_encode( $cms["lang"]["comments.mod.php"]["frontend"][ $cms["config"]["locale"] ] );
            $moderation = json_encode( $cms["config"]["comments.mod.php"]["moderation"] );
            $translate  = "const translate = {$tr};\n";
            $translate .= "const pid = {$cms["page"]["id"]};\n";
            $translate .= "const moderation = {$moderation};\n";
            // В скрипте используется ajax.open( "POST", base_path + "comments_api" );
            // на данный момент отдельно он не нужен, но впоследствии может пригодиться
            $translate .= "const base_path = \"{$cms["base_path"]}\";\n";
            if ( $comments_count >= $cms["config"]["comments.mod.php"]["comments_per_page"] ) {
                $translate .= "const limit_exceeded = true;\n";
            }
            $comments_script = str_replace( "/*translate*/", $translate, $comments_script );
            $cms["output"] = str_replace( "</body>", "<script>\n{$comments_script}\n</script>\n</body>", $cms["output"] );
        } catch ( PDOException $e ) {
            error_log( $e->getMessage() );
        }
    }

}

function cms_comments_on_page_api() {
    global $cms;

    if ( ! empty( $_POST["fn"] ) ) {
        
        switch ( $_POST["fn"] ) {

            case "post_comment":

                // При пустом куки имитируем отправку комментария
                if ( empty( $_COOKIE["cms_comments_uid"] ) ) {
                    echo( json_encode( array(
                        "result"   => array(
                            "collapse" => "true",
                            "answer"   => __( "comment_sended" ),
                        )
                    ) ) );
                    break;
                }

                cms_base_connect();

                $conf = &$cms["config"]["comments.mod.php"];

                try {
                    $uid = $_COOKIE["cms_comments_uid"];
                    $stmt = $cms["pdo"]->prepare( "SELECT * FROM comments_banned_uids WHERE uid=?" );
                    $stmt->execute( array( $uid ) );

                    // Если пользователь забанен, то сообщаем что комментарий отправлен
                    if ( $banned = $stmt->fetch( PDO::FETCH_ASSOC ) ) {
                        echo( json_encode( array(
                            "result"   => array(
                                "collapse" => "true",
                                "answer"   => __( "comment_sended" ),
                            )
                        ) ) );
                        break;
                    }

                    $pid   = (int) $_POST["pid"];
                    $stmt = $cms["pdo"]->prepare( "SELECT COUNT(*) FROM comments WHERE pid=? AND published" );
                    $stmt->execute( array( $pid ) );
                    $count = $stmt->fetchColumn();

                    if ( $count >= $conf["comments_per_page"] ) {
                        echo( json_encode( array(
                            "result" => array(
                                "answer" => "<span class=error>" . __( "limit_exceeded" ) . "</span>",
                            )
                        ) ) );
                        break;
                    }
                } catch ( PDOException $e ) {
                    error_log( $e->getMessage() );
                    break;
                }

                $name    = trim( strip_tags( $_POST["name"] ) );
                $email   = trim( strip_tags( $_POST["email"] ) );
                $text    = strip_tags( $_POST["text"] );
                $created = date( "Y-m-d H:i:sP" );

                if ( $conf["moderation"]  ) {
                    $published = null;
                } else {
                    $published = $created;
                }
                $rid = (int) $_POST["rid"];
                
                try {
                    $stmt = $cms["pdo"]->prepare( "
                        INSERT INTO comments 
                        (pid, rid, name, email, text, uid, created, published) 
                        VALUES (?, ?, ?, ?, ?, ?, ?, ?)
                    " );
                    $stmt->execute( array( $pid, $rid, $name, $email, $text, $uid, $created, $published ) );
                    $id = $cms["pdo"]->lastInsertId();

                    // Cite
                    if ( $rid ) {
                        $stmt = $cms["pdo"]->prepare( "SELECT * FROM comments WHERE id=?" );
                        $stmt->execute( array( $rid ) );
                        $cite = $stmt->fetch( PDO::FETCH_ASSOC );
                        $max_len = 200;
                        if ( mb_strlen( $cite["text"] ) > $max_len ) {
                            $cite_text = mb_substr( $cite["text"], 0, $max_len ) . "...";
                        } else {
                            $cite_text = $cite["text"];
                        }
                        $cite_html = "
                        <div class=cite data-id={$cite["id"]}>
                            <div class=cite-author>{$cite["name"]}</div>
                            <div class=cite-text>{$cite_text}</div>
                        </div>";
                        $with_cite = " withcite";
                    } else {
                        $cite_html = "";
                        $with_cite = "";
                    }
                } catch ( PDOException $e ) {
                    error_log( $e->getMessage() );
                }

                $time = strtotime( $created );
                $date = format_date( $time );
                $tr_reply = __( "reply" );

                $comment   = "
                <div class='comment{$with_cite}' data-id={$id}>
                    <div class=time>{$date}</div>
                    <div class=author>{$name}</div>
                    {$cite_html}
                    <div class=text>{$text}</div>
                    <div class=reply>{$tr_reply}</div>
                </div>";

                // Send email
                if ( is_email( $conf["email"] ) ) {

                    $subject = __( "subject" );
                    $body  = "
                        <style>
                        .comment {
                            display: grid;
                            grid-template-areas: 'author time'
                                'cite cite'
                                'text text';
                            grid-template-columns: 1fr auto;
                            row-gap: 0.2rem;
                            padding: 0.5rem 0.5rem;
                            position: relative;
                            background-color: white;
                            border-radius: 0.3rem;
                            border: 2px solid #ddd;
                            width: fit-content;
                            min-width: 300px;
                        }
                        .comment .time {
                            grid-area: time;
                            font-size: 0.8rem;
                            align-self: center;
                            color: #7a7a7a;
                        }
                        .comment .author {
                            grid-area: author;
                        }
                        .comment .cite {
                            grid-area: cite;
                            width: fit-content;
                            padding: 0.2rem 0.2rem 0.2rem 0.5rem;
                            background-color: #f7f7f7;
                            box-shadow: 0 2px 2px 0 #0000001f;
                            border-radius: 0.2rem;
                            border-left: 2px solid #aaa;
                        }
                        .comment .cite-text {
                            white-space: pre-wrap;
                        }
                        .comment .text {
                            grid-area: text;
                            white-space: pre-wrap;
                        }
                        .reply { display: none; }
                        </style>
                        {$comment}
                        <p></p>
                    ";
                    
                    // link to page
                    try {
                        // "Нет проверки на существование страницы и её публикации" - письмо отправляется админу, публикация не важна, существование проверяется.
                        $stmt = $cms["pdo"]->prepare( "SELECT title, url FROM pages WHERE id=?" );
                        $stmt->execute( array( $pid ) );
                        $page = $stmt->fetch( PDO::FETCH_ASSOC );
                        if ( $page ) {
                            $link    = "{$cms["url"]["scheme"]}://{$cms["url"]["host"]}{$cms["url"]["port"]}{$cms["base_path"]}{$page["url"]}#comment-{$id}";
                            $body   .= "<p>{$page["title"]} <a href='{$link}'>{$link}</a></p>";
                        }
                    } catch ( PDOException $e ) {
                        error_log( $e->getMessage() );
                    }

                    // link to admin
                    $link_admin = "{$cms["url"]["scheme"]}://{$cms["url"]["host"]}{$cms["url"]["port"]}{$cms["base_path"]}{$cms["config"]["admin.mod.php"]["admin_url"]}#comments";
                    $body   .= "<p><a href='{$link_admin}'>{$link_admin}</a></p>";

                    if ( ! empty( $email ) ) {
                        $body .= "<p>Email: <a href='mailto:{$email}'>{$email}</a></p>";
                    }

                    $data = array(
                        "type" => "text/html",
                        "from_email" => "noreply@" . $cms["url"]["host"],
                        "to_email"   => $conf["email"],
                        "subject"    => $subject,
                        "email_body" => $body,
                    );

                    if ( ! empty( $email ) ) {
                        $data["reply_to"] = $email;
                    }

                    if ( empty( $conf["smtp_host"] ) || 
                         empty( $conf["smtp_port"] ) || 
                         empty( $conf["smtp_login"] ) || 
                         empty( $conf["smtp_password"] ) )
                    {
                        $e = cms_email( $data );
                    } else {
                        $data["smtp_host"]     = $conf["smtp_host"];
                        $data["smtp_port"]     = $conf["smtp_port"];
                        $data["smtp_login"]    = $conf["smtp_login"];
                        $data["from_email"]    = $conf["smtp_login"];
                        $data["smtp_password"] = $conf["smtp_password"];
                        $e = cms_smtp_email( $data );
                    }
                }

                if ( $published === "NULL" ) {
                    echo( json_encode( array(
                        "result"   => array(
                            "collapse" => "true",
                            "answer"   => __( "sent_for_moderation" ),
                            "comment"  => "",
                            "id" => $id,
                        )
                    ) ) );
                    break;
                } else {
                    if ( function_exists( "cms_clear_cache" ) ) {
                        cms_clear_cache();
                    }
                    echo( json_encode( array(
                        "result"   => array(
                            "collapse" => "true",
                            "answer"   => __( "comment_sended" ),
                            "comment"  => $comment,
                            "id" => $id,
                        )
                    ) ) );
                    break;
                }

            break;

        }

    }
}

