Тема: Голосование за комментарий

Добрый день.
Увидел в коде для реализации комментирования, что есть голосование.

  function markHelpful($comment_id, $help)
    {
        $help = ($help == 'yes') ? 1 : -1;
        
        $vote = new Orm\Vote();
        $vote['ip'] = $_SERVER['REMOTE_ADDR'];
        $vote['comment_id'] = $comment_id;
        $vote['help'] = $help;
        $vote->replace();
        
        //Пересчитываем количество положительных и отрицательных оценок у комментария
        \RS\Orm\Request::make()
            ->update($this->obj_instance)
            ->set("help_yes = (SELECT COUNT(*) FROM ".$vote->_getTable()." WHERE comment_id = id AND help=1)")
            ->set("help_no = (SELECT COUNT(*) FROM ".$vote->_getTable()." WHERE comment_id = id AND help='-1')")
            ->set("useful = (SELECT SUM(help) FROM ".$vote->_getTable()." WHERE comment_id = id)")
            ->where(array('id' => $comment_id))
            ->exec();
    }

Как обратиться к этой функции ?

Повысить оценку Понизить оценку

Re: Голосование за комментарий

У вас вверху и название класса, а чуть выше и namespace. Соответственно т.к. функция не приватная, то основы PHP нам говорят, что нужно объявить экземпляр класса и вызвать функцию.

$api = new \Нэйспейс\Имякласса();
$api->markHelpful(МоиАргументыЭтойФункции);

Re: Голосование за комментарий

Это надо контроллер дописывать или как то через шаблон использовать?
Извините, не силен, только учусь.

Повысить оценку Понизить оценку

Re: Голосование за комментарий

Задачу полностью опишите.

Re: Голосование за комментарий

Похожий вопрос (голосование за комментарий)
Как можно реализовать, чтобы при клике на ссылки

<a href=""><span>+</span>{$comment.help_yes}</a>  
<a href=""><span>-</span>{$comment.help_yes}</a>             

значение $comment.help_yes увеличивалось/уменьшалось на 1

Повысить оценку Понизить оценку

Re: Голосование за комментарий

Да, вопрос аналогичный как у Валентина. Но и с другой стороны хочется понять как обращаться к функции из шаблона.

Повысить оценку Понизить оценку

Re: Голосование за комментарий

Как реализовать эту функцию я понял.
Создал Фронт контроллер и там задействовал функцию.
Теперь не могу понять как сделать что бы при нажатии на кнопку не переходило на другую страницу
Код шаблона:

        <form action="{$router->getUrl('comments-front-del')}" method="POST" class="formStyle">
            <input type="hidden" name="id" value="{$comment.id}">
            <input type="submit" name="help" value="yes"/>
        </form>

Код фронт-контроллера

  function actionIndex()
    {
       $id = $this->url->request('id', TYPE_INTEGER);
       $help = $this->url->request('help', TYPE_INTEGER);
        if (!empty($id)) {
            $comment = new \Comments\Model\Api();
            $comment->markHelpful($id, $help);
        }
        
        if (!$this->url->request('dialogMode', TYPE_INTEGER)) {
            $this->result->setAjaxWindowRedirect($this->url->getSavedUrl($this->controller_name.'index'));
        }
        
        return $this->result->setTemplate( 'activate.tpl' );
    }

Повысить оценку Понизить оценку

8 Отредактировано Закусило Александр (30.05.2019 16:53:44)

Re: Голосование за комментарий

Валентин пишет:

Похожий вопрос (голосование за комментарий)
Как можно реализовать, чтобы при клике на ссылки

<a href=""><span>+</span>{$comment.help_yes}</a>  
<a href=""><span>-</span>{$comment.help_yes}</a>             

значение $comment.help_yes увеличивалось/уменьшалось на 1

Чем Вас не устроило готовое? )))
http://marketplace.readyscript.ru/addons/ulcomments/

Нужно делать через javascript АЯКС запросы к контроллеру. Который уже и будет увеличивать/уменьшать значение.

Re: Голосование за комментарий

Теперь не могу понять как сделать что бы при нажатии на кнопку не переходило на другую страницу

Это называется AJAX запрос.
Т.е. нужно форму обрабатывать через javascript, собирая данные. Т.к. в чистом виде у Вас будет переход как и получилось. Это можно сделать через jquery serialize и уже потом в json формате принимать ответ. Если вы к любой странице в публичной части обратитесь через AJAX, то в ответ придет json с нужными данными.

10 Отредактировано Александр (03.06.2019 16:47:15)

Re: Голосование за комментарий

Код фронт-контроллера

    function actionIndex()
    {

        if ($this->isMyPost()){
            $id = $this->url->request('id', TYPE_INTEGER);
            $help = $this->url->request('help', TYPE_STRING);
            if (!empty($id)) {
                $api = new \Comments\Model\Api();
                $api->markHelpful($id, $help);
                
            }
            if ($this->url->isAjax()) {
                $this->result->checkAjaxOutput(true); // Форсим AJAX
                $this->result->addSection('count', $this->$api->getUsefulCount());
            }
        }
        

        return $this->result;

    }

Код шаблона tpl

{addjs file="%comments%/vote.js"}
{foreach $commentlist as $comment}
<li {$comment->getDebugAttributes()}>
    <div class="info">
        <p class="starsSection"><span class="stars" title="{$comment->getRateText()}"><i class="mark{$comment.rate}"></i></span></p>
        <p class="date">{$comment.dateof|dateformat:"@date @time"}</p>
        <p class="name">{$comment.user_name}</p>
    </div>
<div class="comment">
        <i class="corner"></i>
        <p>{$comment.message|nl2br}</p>
            <div id="VoteMode">
                {if $success}
                    {$success}
                {/if}
                {if $error}
                    {$error}
                {/if}
    <form action="{$router->getUrl('comments-front-help')}" method="POST" class="formStyle">
        {$this_controller->myBlockIdInput()}
        <input type="hidden" name="id" value="{$comment.id}">
        <input type="submit" name="help" value="yes"/>    
        <input type="submit" name="help" value="no"/>            
    </form>
        <div id="useful">
        {$comment.useful}
        </div>
    </div>
</div>
</li>
{/foreach}

Код JS

$(function() {
    $("body").on('submit', '#VoteMode form', function(){
        var $_this = $("#VoteMode");
        var data   = $(this).serialize();
        $.ajax({
            type : 'POST',
            url : $(this).attr('action'),
            data : data,
            dataType : 'json',
            beforeSend: function() {
                        $('#useful').html('<i class="fa fa-spinner fa-spin fa-fw"></i>');
            },
            success : function(response){
                $('#useful').html(response);
            }
        });
        return false;
    });
});

Функция в API

    function getUsefulCount() {
        
        $comment = new \Comments\Model\Orm\Comment();
        $res = \RS\Orm\Request::make()
                        ->select('useful AS count')
                        ->from($comment)
                        ->where(array('id' => $id))
                        ->exec()->fetchRow(); 

        return $res['count'];
    }

Если без ajax при переходе на следующую страницу выводит значение useful. Но если подключаю ajax значение просто пропадает. Голову сломал не пойму что делаю не так.

Повысить оценку Понизить оценку

11 Отредактировано Закусило Александр (04.06.2019 15:23:55)

Re: Голосование за комментарий

У вас ответ от Ajax какой приходит? Он приходит в виде JSON примерно так:

{
   success: true,
   html: "Содержимое ответа"
}

В Вашем случае будет ещё секция "count"

А вы пытаетесь JSON вставить вместо HTML
Соответственно нужно смотреть, что у Вас в ответе через console.log и тогда доставать, если данные пришли. А судя из контроллера у Вас там возвращается только count секция без html.
Получается, что нужный Вам ответ лежит в response['count'] . Посмотрите что у Вас приходит в панели console и network (XHR) браузера.



И это не нужно

 $this->result->checkAjaxOutput(true); // Форсим AJAX

Система сама выдаст всё JSON формате.

Re: Голосование за комментарий

В ответ приходит

{html: null}
html: null

Повысить оценку Понизить оценку

Re: Голосование за комментарий

Ну вы HTML и не передаёте

$this->result->addSection('count', $this->$api->getUsefulCount());

Ито у Вас туда не зашло. Посмотрите почему через var_dump на разных участках. Но скорее всего isMyPost() не сработал, т.к. там проверяется id блока контента, попробуйте просто через isPost

Если нужно передавать HTML, то должна быть конструкция, иначе будет null

$this->result->setTemplate('Путь к шаблону');

Re: Голосование за комментарий

    function actionIndex()
    {
        $api = new \Comments\Model\Api();
        $comment_id = $this->url->request('id', TYPE_INTEGER);
        $help = $this->url->request('help', TYPE_STRING);
        $api->markHelpful($comment_id, $help);
        $this->result->setSuccess(true)->addSection('count', $api->getUsefulCount($comment_id));
        return $this->result;
        
    }

COUNT передать получилось. Значение useful выводится.
Теперь мучаюсь передать значение help. Форма не подхватывает value у submit'a.
Почему {$this_controller->myBlockIdInput()} выводит одинаковый block_id для каждой формы?

Повысить оценку Понизить оценку

Re: Голосование за комментарий

id вычисляется для каждого блока отдельно. Он нужен только для определения для какого блока запрос. Поэтому он и постоянный. Можете добавить в {csrf}, но тогда придется и его Вам проверять.

Лучше использовать не submit, а помешивать в data параметр или action вашего аякс запроса.