Search

Romua1d.ru
Simpla

Модуль отзывов для Simpla 2.3.7

Всем снова привет! Решил написать свой пост о модуле отзывов для Simpla CMS. Сейчас продают даже бесплатные решения, обидно за наших. Хотел бы поделиться скорее не модулем, а решением для реализации отзывов для интернет-магазина для Simpla.
Вам потребуется уйма времени и ровные руки. Я честно старался подготовить и максимально доходчиво изложить.

Поехали:

  1. Для начала создадим в базе данных таблицу для отзывов. Я назвал ее s_reviews (в зависимости от префикса у Вас имя таблицы может выглядеть по другому). Выполним для этого приведенный ниже sql запрос
--
-- Структура таблицы `s_reviews`
--

CREATE TABLE IF NOT EXISTS `s_reviews` (
  `id` bigint(20) NOT NULL,
  `date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  `ip` varchar(20) NOT NULL,
  `name` varchar(255) NOT NULL,
  `message` text NOT NULL,
  `approved` int(1) NOT NULL DEFAULT '0'
) ENGINE=MyISAM AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;
--
-- Индексы таблицы `s_reviews`
--
ALTER TABLE `s_reviews`
  ADD PRIMARY KEY (`id`);

--
-- AUTO_INCREMENT для сохранённых таблиц
--

--
-- AUTO_INCREMENT для таблицы `s_reviews`
--
ALTER TABLE `s_reviews`
  MODIFY `id` bigint(20) NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=0;

Получится такая вот структура: 

  1. Создадим файл в папке api/ с названием Reviews.php, после заполним его содержимым:
<?php 

/** 
 * Simpla CMS 
 * 
 * @copyright 2011 Denis Pikusov
 * @link http://simplacms.ru 
 * @author Denis Pikusov 
 * 
 */
require_once('Simpla.php');

class Reviews extends Simpla
{
    // Возвращает комментарий по id
    public function get_review($id)
    {
        $query = $this->db->placehold("SELECT r.id, r.name, r.ip, r.type, r.text, r.date, r.approved FROM __reviews r WHERE id=? LIMIT 1",
            intval($id));
        if ($this->db->query($query)) {
            return $this->db->result();
        } else {
            return false;
        }
    }

    public function get_reviews($filter = [], $new_on_top = false)
    {
        // По умолчанию
        $limit = 0;
        $page = 1;
        $keyword_filter = '';
        $approved_filter = '';
        if (isset($filter['limit'])) {
            $limit = max(1, intval($filter['limit']));
        }
        if (isset($filter['page'])) {
            $page = max(1, intval($filter['page']));
        }
        if (isset($filter['approved'])) {
            $approved_filter = $this->db->placehold("AND (r.approved=?)", intval($filter['approved']));
        }
        $sql_limit = $this->db->placehold(' LIMIT ?, ? ', ($page - 1) * $limit, $limit);
        if (!empty($filter['keyword'])) {
            $keywords = explode(' ', $filter['keyword']);
            foreach ($keywords as $keyword) {
                $keyword_filter .= $this->db->placehold('AND r.name LIKE "%' . $this->db->escape(trim($keyword)) . '%" OR r.message LIKE "%' . $this->db->escape(trim($keyword)) . '%" ');
            }
        }
        if ($new_on_top) {
            $sort = 'DESC';
        } else {
            $sort = 'ASC';
        }
        $query = $this->db->placehold("SELECT r.id, r.name, r.ip, r.message, r.date, r.approved FROM __reviews r WHERE 1 $keyword_filter $approved_filter ORDER BY r.id $sort $sql_limit");
        $this->db->query($query);
        return $this->db->results();
    }

    public function count_reviews($filter = [])
    {
        $keyword_filter = '';
        if (!empty($filter['keyword'])) {
            $keywords = explode(' ', $filter['keyword']);
            foreach ($keywords as $keyword) {
                $keyword_filter .= $this->db->placehold('AND r.name LIKE "%' . $this->db->escape(trim($keyword)) . '%" OR r.message LIKE "%' . $this->db->escape(trim($keyword)) . '%" ');
            }
        }
        $query = $this->db->placehold("SELECT count(distinct r.id) as count FROM __reviews r WHERE 1 $keyword_filter");
        $this->db->query($query);
        return $this->db->result('count');
    }

    public function add_reviews($review)
    {
        $query = $this->db->placehold('INSERT INTO __reviews SET ?%, date = NOW()', $review);
        if (!$this->db->query($query)) {
            return false;
        }
        $id = $this->db->insert_id();
        return $id;
    }

    public function update_review($id, $review)
    {
        $date_query = '';
        if (isset($review->date)) {
            $date = $review->date;
            unset($review->date);
            $date_query = $this->db->placehold(', date=STR_TO_DATE(?, ?)', $date, $this->settings->date_format);
        }
        $query = $this->db->placehold("UPDATE __reviews SET ?% $date_query WHERE id in(?@) LIMIT 1", $review,
            (array)$id);
        $this->db->query($query);
        return $id;
    }

    public function delete_review($id)
    {
        if (!empty($id)) {
            $query = $this->db->placehold("DELETE FROM __reviews WHERE id=? LIMIT 1", intval($id));
            $this->db->query($query);
        }
    }
}
  1. В файле api/Simpla.php добавляем после
'comments' => 'Comments', 
'feedbacks' => 'Feedbacks',

Этот код

'reviews' => 'Reviews',
  1. В файле api/Managers.php после
 'blog', 'comments', 'feedbacks',

добавляем

'reviews',
  1. В папке simpla создаем файл ReviewsAdmin.php со следующим содержимым:
<?php
require_once('api/Simpla.php');

########################################
class ReviewsAdmin extends Simpla
{
    function fetch()
    {
        // Поиск
        $keyword = $this->request->get('keyword', 'string');
        if (!empty($keyword)) {
            $filter['keyword'] = $keyword;
            $this->design->assign('keyword', $keyword);
        }
        // Обработка действий
        if ($this->request->method('post')) {
            // Действия с выбранными
            $ids = $this->request->post('check');
            if (!empty($ids)) switch ($this->request->post('action')) {
                case 'approve':
                {
                    foreach ($ids as $id) {
                        $this->reviews->update_review($id, ['approved' => 1]);
                    }
                    break;
                }
                case 'delete':
                {
                    foreach ($ids as $id) {
                        $this->reviews->delete_review($id);
                    }
                    break;
                }
            }
        }
        // Отображение
        $filter = [];
        $filter['page'] = max(1, $this->request->get('page', 'integer'));
        $filter['limit'] = 40;
        // Поиск
        $keyword = $this->request->get('keyword', 'string');
        if (!empty($keyword)) {
            $filter['keyword'] = $keyword;
            $this->design->assign('keyword', $keyword);
        }
        $reviews_count = $this->reviews->count_reviews($filter);
        // Показать все страницы сразу
        if ($this->request->get('page') == 'all') {
            $filter['limit'] = $reviews_count;
        }
        $reviews = $this->reviews->get_reviews($filter, true);
        $this->design->assign('pages_count', ceil($reviews_count / $filter['limit']));
        $this->design->assign('current_page', $filter['page']);
        $this->design->assign('reviews', $reviews);
        $this->design->assign('reviews_count', $reviews_count);
        return $this->design->fetch('reviews.tpl');
    }
}

?>
  1. В файл simpla/IndexAdmin.php после
'CommentsAdmin' => 'comments', 
'FeedbacksAdmin' => 'feedbacks',

добавляем

'ReviewsAdmin' => 'reviews',
  1. В файле simpla/ajax/update_object.php после
case 'comment': 
    if($simpla->managers->access('comments')) 
        $result = $simpla->comments->update_comment($id, $values); 
    break;

добавляем

case 'review':
    if($simpla->managers->access('reviews'))
        $result = $simpla->reviews->update_review($id, $values);
    break;
  1. Теперь переходим к выводу отзывов в админке, переходим и редактируем файлы в папке simpla/design/html
  • В файл feedbacks.tpl добавляем вывод отзывов:
{* Вкладки *}
{capture name=tabs}
    {if in_array('comments', $manager->permissions)}
    <li><a href="index.php?module=CommentsAdmin">Комментарии</a></li>
    {/if}
    <li class="active">
        <a href="index.php?module=FeedbacksAdmin">Обратная связь</a>
    </li>
    {if in_array('reviews', $manager->permissions)}
    <li>
        <a href="index.php?module=ReviewsAdmin">Отзывы</a>
    </li>
    {/if} 
{/capture}
  • В файл comments.tpl добавляем также вывод отзывов:
{* Вкладки *}
{capture name=tabs}
    {if in_array('comments', $manager->permissions)}
        <li><a href="index.php?module=CommentsAdmin">Комментарии</a></li>
    {/if}
    <li class="active"><a href="index.php?module=FeedbacksAdmin">Обратная связь</a></li>
    {if in_array('reviews', $manager->permissions)}
        <li><a href="index.php?module=ReviewsAdmin">Отзывы</a></li>
    {/if}
{/capture}
  • Соответственно создаем файл вывода отзывов reviews.tpl со следующим содержимым:
{* Вкладки *}
{capture name=tabs}
{if in_array('comments', $manager->permissions)}
<li><a href="index.php?module=CommentsAdmin">Комментарии</a></li>{/if}
{if in_array('feedbacks', $manager->permissions)}
<li><a href="index.php?module=FeedbacksAdmin">Обратная связь</a></li>{/if}
<li class="active"><a href="index.php?module=ReviewsAdmin">Отзывы</a></li>
{/capture}


{* Title *}
{$meta_title='Отзывы' scope=parent}

{* Поиск *}
{if $reviews || $keyword}
<form method="get">
    <div id="search">
        <input type="hidden" name="module" value='ReviewsAdmin'>
        <input class="search" type="text" name="keyword" value="{$keyword|escape}"/>
        <input class="search_button" type="submit" value=""/>
    </div>
</form>
{/if}


{* Заголовок *}
<div id="header">
    {if $keyword && $reviews_count}
    <h1>{$reviews_count|plural:'Нашелся':'Нашлось':'Нашлись'} {$reviews_count}
        {$reviews_count|plural:'отзыв':'отзывов':'отзыва'}</h1>
    {elseif !$type}
    <h1>{$reviews_count} {$reviews_count|plural:'отзыв':'отзывов':'отзыва'}</h1>
    {/if}
</div>


{if $reviews}
<div id="main_list">

    <!-- Листалка страниц -->
    {include file='pagination.tpl'}
    <!-- Листалка страниц (The End) -->

    <form id="list_form" method="post">
        <input type="hidden" name="session_id" value="{$smarty.session.id}">

        <div id="list" class="sortable">
            {foreach $reviews as $review}
            <div class="{if !$review->approved}unapproved{/if} row">
                <div class="checkbox cell">
                    <input type="checkbox" name="check[]" value="{$review->id}"/>
                </div>
                <div class="name cell">
                    <div class="review_name">
                        {$review->name|escape}
                        <a class="approve" href="#">Одобрить</a>
                    </div>
                    <div class="review_text">
                        {$review->message|escape|nl2br}
                    </div>
                    <div class="review_info">
                        Отзыв оставлен {$review->date|date} в {$review->date|time}
                    </div>
                </div>
                <div class="icons cell">
                    <a class="delete" title="Удалить" href="#"></a>
                </div>
                <div class="clear"></div>
            </div>
            {/foreach}
        </div>

        <div id="action">
            Выбрать <label id="check_all" class="dash_link">все</label> или <label id="check_unapproved"
                                                                                   class="dash_link">ожидающие</label>

            <span id="select">
  <select name="action">
   <option value="approve">Одобрить</option>
   <option value="delete">Удалить</option>
  </select>
  </span>

            <input id="apply_action" class="button_green" type="submit" value="Применить">

        </div>
    </form>

    <!-- Листалка страниц -->
    {include file='pagination.tpl'}
    <!-- Листалка страниц (The End) -->

</div>
{else}
Нет отзывов
{/if}

<!-- Меню -->
<div id="right_menu">

</div>
<!-- Меню  (The End) -->

{literal}
<script>
 $(function () {

  // Раскраска строк
  function colorize() {
   $('#list div.row:even').addClass('even');
   $('#list div.row:odd').removeClass('even');
  }

  // Раскрасить строки сразу
  colorize();

  // Выделить все
  $('#check_all').click(function () {
   $('#list input[type="checkbox"][name*="check"]').attr('checked', $('#list input[type="checkbox"][name*="check"]:not(:checked)').length > 0);
  });

  // Выделить ожидающие
  $('#check_unapproved').click(function () {
   $('#list input[type="checkbox"][name*="check"]').attr('checked', false);
   $('#list .unapproved input[type="checkbox"][name*="check"]').attr('checked', true);
  });

  // Удалить 
  $('a.delete').click(function () {
   $('#list input[type="checkbox"][name*="check"]').attr('checked', false);
   $(this).closest('.row').find('input[type="checkbox"][name*="check"]').attr('checked', true);
   $(this).closest('form').find('select[name="action"] option[value=delete]').attr('selected', true);
   $(this).closest('form').submit();
  });

  // Одобрить
  $('a.approve').click(function () {
   var line = $(this).closest('.row');
   var id = line.find('input[type="checkbox"][name*="check"]').val();
   $.ajax({
    type: 'POST',
    url: 'ajax/update_object.php',
    data: {
     'object': 'review',
     'id': id,
     'values': {'approved': 1},
     'session_id': '{/literal}{$smarty.session.id}{literal}'
    },
    success: function (data) {
     line.removeClass('unapproved');
    },
    dataType: 'json'
   });
   return false;
  });

  $('form#list_form').submit(function () {
   if ($('#list_form select[name="action"]').val() == 'delete' && !confirm('Подтвердите удаление')) {
    return false;
   }
  });

 });

</script>
{/literal}

В результате мы сделали админ-часть этой статьи 

  1. Админская часть у нас готова. Переходим к выводу отзывов и формы. Для начала создадим страницу с адресом reviews

Потом разрешим через .htaccess подключение этой страницы. В корне сайта находим .htaccess и добавляем строку чуть ниже feedback

# feedback
RewriteRule ^contact/?$ index.php?module=FeedbackView  [L,QSA]

после добавления получится так

# feedback RewriteRule ^contact/?$ index.php?module=FeedbackView [L,QSA] # reviews RewriteRule ^reviews/?$ index.php?module=ReviewsView [L,QSA]
  1. Теперь поворотим немного в view/, создаем по адресу view/ файл ReviewsView.php со следующим содержимым
<?PHP

/**
 * Simpla CMS
 *
 * @copyright  2011 Denis Pikusov
 * @link      http://simplacms.ru
 * @author        Denis Pikusov
 *
 * Этот класс использует шаблон reviews.tpl
 *
 */
require_once('View.php');


class ReviewsView extends View
{

    function fetch()
    {
        if ($this->request->method('post') && $this->request->post('review')) {
            $review = new stdClass;
            $review->name = $this->request->post('name');
            $review->message = $this->request->post('message');
            $captcha_code = $this->request->post('captcha_code', 'string');

            // Передадим отзыв обратно в шаблон - при ошибке нужно будет заполнить форму
            $this->design->assign('name', $review->name);
            $this->design->assign('message', $review->message);

            // Проверяем капчу и заполнение формы
            if ($_SESSION['captcha_code'] != $captcha_code || empty($captcha_code)) {
                $this->design->assign('error', 'captcha');
            } elseif (empty($review->name)) {
                $this->design->assign('error', 'empty_name');
            } elseif (empty($review->message)) {
                $this->design->assign('error', 'empty_message');
            } else {
                $this->design->assign('review_sent', true);
                // Создаем отзыв
                $review->ip = $_SERVER['REMOTE_ADDR'];

                // Если были одобренные отзывы от текущего ip, одобряем сразу
                $this->db->query("SELECT 1 FROM __reviews WHERE approved=1 AND ip=? LIMIT 1", $review->ip);
                if ($this->db->num_rows() > 0) {
                    $review->approved = 1;
                }

                // Добавляем отзыв в базу
                $review_id = $this->reviews->add_reviews($review);

                // Отправляем email
                // $this->notify->email_review_admin($review_id);

                // Приберем сохраненную капчу, иначе можно отключить загрузку рисунков и постить старую
                unset($_SESSION['captcha_code']);
                //header('location: '.$_SERVER['REQUEST_URI'].'#review_'.$review_id);


            }
        }


        // Отображение
        $filter = [];
        $filter['page'] = max(1, $this->request->get('page', 'integer'));
        $filter['limit'] = 40;
        $filter['approved'] = 1;

        // Поиск
        $keyword = $this->request->get('keyword', 'string');
        if (!empty($keyword)) {
            $filter['keyword'] = $keyword;
            $this->design->assign('keyword', $keyword);
        }

        $reviews_count = $this->reviews->count_reviews($filter);
        // Показать все страницы сразу
        if ($this->request->get('page') == 'all') {
            $filter['limit'] = $reviews_count;
        }


        $reviews = $this->reviews->get_reviews($filter, true);


        $this->design->assign('pages_count', ceil($reviews_count / $filter['limit']));
        $this->design->assign('current_page', $filter['page']);

        $this->design->assign('filter', $filter);

        $this->design->assign('reviews', $reviews);
        $this->design->assign('reviews_count', $reviews_count);


        $this->design->assign('meta_title', $review->meta_title);
        $this->design->assign('meta_keywords', $review->meta_keywords);
        $this->design->assign('meta_description', $review->meta_description);

        return $this->design->fetch('reviews.tpl');
    }

}
  1. Теперь осталось вывести отзывы на странице site.ru/reviews, для этого создадим в папке design/{THEME}/html файл reviews.tpl примерно с таким содержимым
{if $review_sent}
{$name|escape}, ваш отзыв добавлен на сайт.
{else}

<h1 data-page="{$page->id}">{$page->header|escape}</h1>


{$page->body}

<form class="form review_form" method="post">
    {if $error}
    <div class="message_error">
        {if $error=='captcha'}
        Неверно введена капча
        {elseif $error=='empty_name'}
        Введите имя
        {elseif $error=='empty_text'}
        Введите сообщение
        {/if}
    </div>
    {/if}
    <label>Имя</label>
    <input data-format=".+" data-notice="Введите имя" value="{$name|escape}" name="name" maxlength="255" type="text"/>

    <label>Отзыв</label>
    <textarea data-format=".+" data-notice="Введите сообщение" value="{$message|escape}" name="message">{$message|escape}</textarea>

    <input class="button" type="submit" name="review" value="Отправить" />

    <div class="captcha"><img src="captcha/image.php?{math equation='rand(10,10000)'}"/></div>
    <input class="input_captcha" id="comment_captcha" type="text" name="captcha_code" value="" data-format="\d\d\d\d" data-notice="Введите капчу"/>
</form>
{/if}
{if $reviews}
{include file='pagination_sec.tpl'}
<ul class="comment_list">
    {foreach $reviews as $review}

    <a name="review_{$review->id}"></a>
    <li>
        <!-- Имя и дата Отзыва-->
        <div class="comment_header">
            {$review->name|escape} <i>Отзыв оставлен {$review->date|date} в {$review->date|time}</i>
        </div>
        <!-- Имя и дата Отзыва (The End)-->

        <!-- Отзыв -->
        {$review->message|escape|nl2br}
        <!-- Отзыв (The End)-->
    </li>


    {/foreach}</ul>
{include file='pagination_sec.tpl'}

{else}
Нет отзывов
{/if}

Добавляем также пагинацию, design/{THEME}/html файл pagination_sec.tpl

{if $pages_count>1}

{* Скрипт для листания через ctrl → *}
{* Ссылки на соседние страницы должны иметь id PrevLink и NextLink *}
<script type="text/javascript" src="design/js/ctrlnavigate.js"></script>

<!-- Листалка страниц -->
<div id="pagination">

    {* Количество выводимых ссылок на страницы *}
    {$visible_pages = 11}

    {* По умолчанию начинаем вывод со страницы 1 *}
    {$page_from = 1}

    {* Если выбранная пользователем страница дальше середины "окна" - начинаем вывод уже не с первой *}
    {if $current_page > floor($visible_pages/2)}
    {$page_from = max(1, $current_page-floor($visible_pages/2)-1)}
    {/if}

    {* Если выбранная пользователем страница близка к концу навигации - начинаем с "конца-окно" *}
    {if $current_page > $pages_count-ceil($visible_pages/2)}
    {$page_from = max(1, $pages_count-$visible_pages-1)}
    {/if}

    {* До какой страницы выводить - выводим всё окно, но не более ощего количества страниц *}
    {$page_to = min($page_from+$visible_pages, $pages_count-1)}

    {* Ссылка на 1 страницу отображается всегда *}
    <a class="{if $current_page==1}selected{else}droppable{/if}" href="{url page=1}">1</a>

    {* Выводим страницы нашего "окна" *}
    {section name=pages loop=$page_to start=$page_from}
    {* Номер текущей выводимой страницы *}
    {$p = $smarty.section.pages.index+1}
    {* Для крайних страниц "окна" выводим троеточие, если окно не возле границы навигации *}
    {if ($p == $page_from+1 && $p!=2) || ($p == $page_to && $p != $pages_count-1)}
    <a class="{if $p==$current_page}selected{/if}" href="{url page=$p}">...</a>
    {else}
    <a class="{if $p==$current_page}selected{else}droppable{/if}" href="{url page=$p}">{$p}</a>
    {/if}
    {/section}

    {* Ссылка на последнююю страницу отображается всегда *}
    <a class="{if $current_page==$pages_count}selected{else}droppable{/if}"  href="{url page=$pages_count}">{$pages_count}</a>

    <a href="{url page=all}">все сразу</a>
    {if $current_page>1}<a id="PrevLink" href="{url page=$current_page-1}">←назад</a>{/if}
    {if $current_page<$pages_count}<a id="NextLink" href="{url page=$current_page+1}">вперед→</a>{/if}

</div>
<!-- Листалка страниц (The End) -->
{/if}

Верстка может быть изменена.

  1. Ну и сам вывод я решил реализовать через логику, правим файл design/{THEME}/html/page.tpl , изменяем и делаем примерно таким
{* Канонический адрес страницы *}
{if $page->url == reviews }
    {$canonical="/{$page->url}" scope=parent}

    {include file='reviews.tpl'}
{else}
{$canonical="/{$page->url}" scope=parent}

<!-- Заголовок страницы -->
<h1 data-page="{$page->id}">{$page->header|escape}</h1>

<!-- Тело страницы -->
{$page->body}
{/if}

В результате получим модерируемые через админ-панель отзывы

На этом пожалуй все. Пишите вопросы. Может что дополнить надо, я как раз протестирую на одном проекте и внесу правки.

Спасибо за внимание!

Плагин рейтинга создан автором этого блога. Буду очень признателен, если вы сможете его поддержать (ссылка)

p.s. Если статья была полезной и вас переполняет чувство благодарности, можете поддержать меня долларом на патреоне

Romuald Shmidtelson

Web Developer. I have expirience in FrontEnd, Backend, Devops. PHP, Python, Javascript (Vue.js, React.js)

Смотреть комментарии

  • Страница отзывов кривовато отображается. Но главное, отзывы не сохраняются. Т.е пишешь отзыв, а его нет ни в админке и не на сайте. Где ошибся?
    https://ihsanshop.ru/reviews

  • Здравствуйте, сделал все по инструкции.
    Проверил два раза. Не отображается страница
    https://maxistock.com.ua/revews

    • Здравствуйте! Какая у вас версия?

  • Спасибо, это именно то, что нужно было. Без дискуссий как на форумах, всё чётко, всё работает.
    Хотелось бы, конечно, чтобы ещё красный бабл загорался над пунктом меню "Комментарии", но это уже мелочи.

  • Помогите, пожалуйста.

    1) Не работает кнопка "Одобрить" в админке возле отзыва (зеленая такая)
    2) Тайтл и описание действительно не выводятся. Хотя до этого было все норм

    3) есть ли возможность отвечать на отзыв?

    • 1) Возможно у Вас какая-то проблема.
      2) Этот момент не изучен.
      3) Такой возможности в данном решении нет, но реализовать при желании можно

  • Планирую поднять дев сервер с работой этого скрипта и продолжить его поддерживать

  • У меня та же проблема как и у Владимира.
    1. Не появляется информер нового отзыва в админке сайта, а сам отзыв есть.
    2. Для страницы прописаны title и description, но браузеры их не видят.
    Как исправить ? Хелп!!

    • 2. Для страницы прописаны title и description, но браузеры их не видят.
      да и сам я их не вижу тоже в коде страницы-там пусто....

      • Но страница то создана, в ней прописано?

        • страница создана и с админки прописаны тайтл и ключи.
          но при просмотре исходного кода (ctrl u) там пусто.

          PS со всеми др страницами все отлично.

  • Добрый день!
    Страница отзывов установлена и работает, однако есть две проблемы:
    1. Не появляется информер нового отзыва в админке сайта, а сам отзыв есть.
    2. Для страницы прописаны title и description в админке, но браузеры их не видят.
    Подскажите, пожалуйста, как можно найти и исправить указанные ошибки.

  • А можно как то сделать что бы файлы можно было прикреплять к отзывам?

  • Здравствуйте. Страницу установил, проверил, всё работает. Однако есть косяк: на сайте произошло искажение блоков левого меню с товаром (стали слишком высокие) и шапка немного вниз ушла. Это произошло сразу после записи нового класса reviews в api/Simpla.php.
    Что посоветуете?

    • скажу честно, что не в этом проблема

  • Все хорошо, а если есть на сайте менеджер то ему новая вкладка недоступна (

    • Здравствуйте! А в настройках посмотрите права.

      • Все разобрался, была ошибка в кавычках, ну в файл manager.tpl добавить 'reviews' =>'Отзывы',
        Все супер спасибо за Ваше внимание и открытую доработку ! С П А С И Б О !

      • а про права в файле manager тоже я не нашел не слова.... если у Вас есть время не могли бы подсказать ...

      • Добрый вечер, права дал, но отключил один из пунктов, получается правило не все имеющиеся модули, а разрешенные, а где указать что он разрешен, и я не понял в вкладки
        CommentsAdmin ведь тоже нужно выводить или нет вот в этом коде

        foreach($comments as &$comment)
        { if($comment->type == 'product' && isset($products[$comment->object_id]))
        $comment->product = $products[$comment->object_id];
        if($comment->type == 'blog' && isset($posts[$comment->object_id]))
        $comment->post = $posts[$comment->object_id];

        а его я у Вас не увидел или просто пропустил

Поделиться
Опубликовано
Romuald Shmidtelson

Недавние Посты

Как получить первый заказ на фрилансе

Получение первого заказа на фрилансе может быть вызовом, особенно для новичков, которые еще не имеют…

1 год назад

Топ 7 css фреймворков 2021 года

Разработка сайтов и веб-приложений стала в наше время неизбежной потребностью. Тем не менее, существует несколько способов…

2 года назад

Что такое семантическое ядро и как его использовать для продвижения сайта?

Компании и специалисты по маркетингу тратят много времени и денег на изучение языка поисковых систем,…

3 года назад

Что такое адаптивные изображения? Как правильно использовать srcset.

Адаптивные изображения - это набор методов, используемых для загрузки правильного изображения в зависимости от разрешения…

3 года назад

Что такое Политика конфиденциальности для сайта и для чего она нужна?

Политика конфиденциальности - это документ, в котором подробно описывается, как компания или организация обрабатывает любую…

3 года назад

Кто такой вебмастер?

В современном мире много специалистов занятых поддержанием работы сайтов, и довольно часто многих из них…

3 года назад