Первым уроком в данном разделе будет наиболее полезен новичкам и не только. Он поможет установить на ваш сайт систему комментариев на PHP + MySql, а также будет возможность оставлять комментарии от вашего аккаунта из любой социальной сети.
Полные особенности данного расширения:
Важно! Для начала вам нужно убедиться, что ваш хостинг для сайта поддерживает PHP и MYSQL.
Далее нам необходимо зарегистрироваться в Cackle (cackle.ru) — система комментирования с возможностью авторизации практически через любую социальную сеть. Не смотря на то, что код системы подключается через javascript код, приведенная далее мною модификация позволяет создать полную синхронизацию с вашим сайтом и выводить комментарии из базы данных, что делает все комментарии видимыми для поисковых систем, что в дальнейшем благополучно будет сказываться на продвижении сайта.
Перед регистрацией в Cackle нужно еще учивать, что пользования системой минимальным тарифом, который и нужен нам для полноценной работы, стоит на момент написания статьи 450 руб. Поверьте, это на самом деле копейки за такую многофункциональный движок, который позволяет комментировать с помощью любой социальной сети.
И так, мы зарегистрировались в Cackle, далее идем раздел «Виджеты» и нажимаем на вкладку «CMS Платформа». В появившемся блоке выбираем любую CMS, например WordPress, где видим следующее:
От сюда на потребуются 3 этих значения, которые мы запишем в конфигурацию нашей системы комментарирования прямо на сайте. Приведенный далее код и есть вывод наших комментариев:
<?php define('CACKLE_DB_LOCALHOST', "localhost"); // сервер базы данных define('CACKLE_DB_USER', "root"); // логин для mysql define('CACKLE_DB_PASSWORD', ""); // пароль для mysql define('CACKLE_DB_NAME', "cackle-php" ); // имя базы данных define('CACKLE_TIMER', 60); // время в секундах через которое синхронизируются комментарии define('SITE_ID', $SITE_ID); // 3 значения из настроек Cackle define('ACCOUNT_API_KEY', ""); define('SITE_API_KEY', ""); define('POST_ID', $page_id); // сюда мы записываем либо id страницы либо URL class Cackle{ function Cackle(){ if ($this->time_is_over(CACKLE_TIMER)){ $this->comment_sync(ACCOUNT_API_KEY,SITE_API_KEY); } $this->cackle_display_comments(); } function time_is_over($cron_time){ $sql="select common_value from common where `common_name` = 'last_time'"; $get_last_time = $this->db_connect($sql, "common_value"); $now=time(); $establish_time_sql="insert into `common` (`common_name`,`common_value`) values ('last_time',$now)"; $delete_time_sql="delete from `common` where `common_name` = 'last_time' and `common_value` > 0;"; if ($get_last_time==null){ $this->db_connect($establish_time_sql); return time(); } else{ if($get_last_time + $cron_time > $now){ return false; } if($get_last_time + $cron_time < $now){ $this->db_connect($delete_time_sql); $this->db_connect($establish_time_sql); return $cron_time; } } } function db_connect($sql,$field_to_return=null){ $link = mysql_connect(CACKLE_DB_LOCALHOST, CACKLE_DB_USER, CACKLE_DB_PASSWORD) or die("Could not connect "); mysql_select_db(CACKLE_DB_NAME, $link) or die(mysql_error()); mysql_query('SET NAMES 'UTF8''); $r = mysql_query($sql, $link) or die(mysql_error()); if($field_to_return!=null){ $db_resp = mysql_fetch_array($r); return $db_resp[$field_to_return]; } $x=0; if($r==1) return; // no select request $row=array(); // to be safe with empty select results while ($res=mysql_fetch_array($r)) { $row[$x]=$res; $x++; } return $row; mysql_close($link); } function comment_sync($accountApiKey,$siteApiKey,$cackle_last_comment=0){ $get_last_comment = $this->db_connect("select common_value from common where `common_name` = 'last_modified'","common_value"); if ($get_last_comment!=null){ $cackle_last_comment = $get_last_comment; } $params1 = "accountApiKey=$accountApiKey&siteApiKey=$siteApiKey&modified=$cackle_last_comment"; $host="cackle.me/api/comment/mutable_list?$params1"; function curl($url) { $ch = curl_init(); curl_setopt ($ch, CURLOPT_URL,$url); curl_setopt ($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.6) Gecko/20070725 Firefox/2.0.0.6"); curl_setopt ($ch, CURLOPT_TIMEOUT, 60); curl_setopt ($ch, CURLOPT_FOLLOWLOCATION, 1); curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1); $result = curl_exec ($ch); curl_close($ch); return $result; } $response = curl($host); $response = $this->cackle_json_decodes($response); $this->push_comments($response); } function cackle_json_decodes($response){ $response_without_jquery = str_replace('jQuery(', '', $response); $response = str_replace(');', '', $response_without_jquery); $obj = json_decode($response,true); return $obj; } function insCreate ($table,$arr){ $str=""; $key_str=""; $val_str=""; foreach($arr as $key=>$val){ $key_str .= "`" . $key . "`, "; $val_str .= "'" . mysql_escape_string($val) . "', "; } $str .= "insert into " . "`" . $table . "` " ; $sql_req=$str . "(" . $key_str . ") values (" . $val_str . "); "; $sql_req = str_replace(", )",")",$sql_req); return $sql_req; } /** * Insert each comment to database with parents */ function insert_comm($comment,$status){ /* * Here you can convert $url to your post ID */ $url = $comment['channel']; if ($comment['author']!=null){ $author_name = $comment['author']['name']; $author_email= $comment['author']['email']; $author_www = $comment['author']['www']; $author_avatar = $comment['author']['avatar']; $author_provider = $comment['author']['provider']; $author_anonym_name = null; $anonym_email = null; } else{ $author_name = null; $author_email= null; $author_www = null; $author_avatar = null; $author_provider = null; $author_anonym_name = $comment['anonym']['name']; $anonym_email = $comment['anonym']['email']; } $get_parent_local_id = null; $comment_id = $comment['id']; $comment_modified = $comment['modified']; if ($comment['parentId']) { $comment_parent_id = $comment['parentId']; $sql = "select comment_id from comment where user_agent='Cackle:$comment_parent_id';"; $get_parent_local_id = $this->db_connect($sql, "comment_id"); //get parent comment_id in local db } //You should define post_id in $commentdata according you cms engine(ex. maybe your cms have function to return post_id by page's url) $commentdata = array( 'url' => $url, 'author_name' => $author_name, 'author_email' => $author_email, 'author_www' => $author_www, 'author_avatar' => $author_avatar, 'author_provider' => $author_provider, 'anonym_name' => $author_anonym_name, 'anonym_email' => $anonym_email, 'rating' => $comment['rating'], 'created' => strftime("%Y-%m-%d %H:%M:%S", $comment['created']/1000), 'ip' => $comment['ip'], 'message' =>$comment['message'], 'status' => $status, 'user_agent' => 'Cackle:' . $comment['id'], 'parent' => $get_parent_local_id ); $this->db_connect($this->insCreate("comment",$commentdata)); $sql_last_comment_delete="delete from `common` where `common_name` = 'last_comment'"; $sql_last_comment_establish="insert into `common` set `common_name` = 'last_comment'"; $sql_last_comment="update `common` set `common_name` = 'last_comment', `common_value` = $comment_id where `common_name` = 'last_comment';"; $this->db_connect($sql_last_comment_delete); $this->db_connect($sql_last_comment_establish); $this->db_connect($sql_last_comment); $get_last_modified = $this->db_connect("select common_value from common where `common_name` = 'last_modified'","common_value"); if ($comment['modified'] > $get_last_modified) { $sql_last_modified_delete="delete from `common` where `common_name` = 'last_modified'"; $sql_last_modified_establish="insert into `common` set `common_name` = 'last_modified'"; $sql_last_modified="update `common` set `common_name` = 'last_modified', `common_value` = $comment_modified where `common_name` = 'last_modified';"; $this->db_connect($sql_last_modified_delete); $this->db_connect($sql_last_modified_establish); $this->db_connect($sql_last_modified); } } function comment_status_decoder($comment) { $status; if (strtolower($comment['status']) == "approved") { $status = 1; } elseif (strtolower($comment['status'] == "pending") || strtolower($comment['status']) == "rejected") { $status = 0; } elseif (strtolower($comment['status']) == "spam") { $status = 0; } elseif (strtolower($comment['status']) == "deleted") { $status = 0; } return $status; } function update_comment_status($comment_id, $status, $modified, $comment_content) { $sql_status="update `comment` set `status` = $status, `message` = '$comment_content' where `user_agent` = 'Cackle:$comment_id';"; $this->db_connect($sql_status); $sql_last_modified_delete="delete from `common` where `common_name` = 'last_modified'"; $sql_last_modified_establish="insert into `common` set `common_name` = 'last_modified'"; $sql_last_modified="update `common` set `common_name` = 'last_modified', `common_value` = $modified where `common_name` = 'last_modified';"; $this->db_connect($sql_last_modified_delete); $this->db_connect($sql_last_modified_establish); $this->db_connect($sql_last_modified); } function push_comments ($response){ $obj = $response['comments']; if ($obj) { foreach ($obj as $comment) { $get_last_comment = $this->db_connect("select common_value from common where `common_name` = 'last_comment'","common_value"); $get_last_modified = $this->db_connect("select common_value from common where `common_name` = 'last_modified'","common_value"); if ($comment['id'] > $get_last_comment) { $this->insert_comm($comment, $this->comment_status_decoder($comment)); } else { if (!$get_last_modified){ $get_last_modified == 0; } if ($comment['modified'] > $get_last_modified) { $this->update_comment_status($comment['id'], $this->comment_status_decoder($comment), $comment['modified'], $comment['message'] ); } } } } } function cackle_comment( $comment) { ?><li id="cackle-comment-<?php echo $comment['comment_id']; ?>"> <div id="cackle-comment-header-<?php echo $comment['comment_id']; ?>" class="cackle-comment-header"> <cite id="cackle-cite-<?php echo $comment['comment_id']; ?>"> <?php if($comment['author_name']) : ?> <a id="cackle-author-user-<?php echo $comment['comment_id']; ?>" href="<?php echo $comment['author_www']; ?>" target="_blank" rel="nofollow"><?php echo $comment['author_name']; ?></a> <?php else : ?> <span id="cackle-author-user-<?php echo $comment['comment_id']; ?>"><?php echo $comment['anonym_name']; ?></span> <?php endif; ?> </cite> </div> <div id="cackle-comment-body-<?php echo $comment['comment_id']; ?>" class="cackle-comment-body"> <div id="cackle-comment-message-<?php echo $comment['comment_id']; ?>" class="cackle-comment-message"> <?php echo $comment['message']; ?> </div> </div> </li><?php } function cackle_display_comments(){ $post_id = POST_ID; $api_id = API_ID; ?> <div id="mc-container"> <div id="mc-content"> <ul id="cackle-comments"> <?php $this->list_comments(); ?> </ul> </div> </div> <script type="text/javascript"> var mcSite = '<?php echo $api_id //from cackle's admin panel?>'; var mcChannel = '<?php echo $post_id?>'; document.getElementById('mc-container').innerHTML = ''; (function() { var mc = document.createElement('script'); mc.type = 'text/javascript'; mc.async = true; mc.src = 'http://cackle.me/mc.widget-min.js'; (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(mc); })(); </script> <?php } function get_local_comments(){ //getting all comments for special post_id from database. //$post_id = 1; //ex. $post_id = POST_ID; $api_id = API_ID; $get_all_comments = $this->db_connect("select * from `comment` where `url` = $post_id and `status` = 1;"); return $get_all_comments; } function list_comments(){ $obj = $this->get_local_comments(); foreach ($obj as $comment) { $this->cackle_comment($comment); } } } $a = new Cackle(); // выводим класс. Вставляем в нужное нам место для вывода комментариев. ?>
Также создаем в базе данных две таблицы. Первая содержит сами комментарии, вторая — время синхронизации комментариев.
CREATE TABLE `comment` ( `comment_id` BIGINT(20) NOT NULL AUTO_INCREMENT, `post_id` BIGINT(20) NULL DEFAULT NULL, `url` VARCHAR(2000) NULL DEFAULT NULL, `parent` VARCHAR(20) NULL DEFAULT NULL, `message` TEXT NULL, `media` VARCHAR(1000) NULL DEFAULT NULL, `status` VARCHAR(11) NULL DEFAULT NULL, `rating` INT(11) NULL DEFAULT NULL, `user_agent` VARCHAR(1000) NULL DEFAULT NULL, `ip` VARCHAR(39) NULL DEFAULT NULL, `author_name` VARCHAR(60) NULL DEFAULT NULL, `author_email` VARCHAR(100) NULL DEFAULT NULL, `author_www` VARCHAR(200) NULL DEFAULT NULL, `author_avatar` VARCHAR(200) NULL DEFAULT NULL, `author_provider` VARCHAR(32) NULL DEFAULT NULL, `anonym_name` VARCHAR(60) NULL DEFAULT NULL, `anonym_email` VARCHAR(100) NULL DEFAULT NULL, `created` DATETIME NULL DEFAULT NULL, PRIMARY KEY (`comment_id`) ); CREATE TABLE `common` ( `common_name` VARCHAR(50) NULL DEFAULT NULL, `common_value` VARCHAR(50) NULL DEFAULT NULL )
Настроить внешний вид формы можно в админке Cackle.
Это пока краткий экскурс по данному вопросу, жду ваши вопросы и комментарии к этой статье и думаю со временем благодаря вам я сделаю статью понятной для всех. Кстати, на моем сайте используется именно этот скрипт и система комментирования черех социальные сети Cackle, можете заодно опробывать :)
Дата публикации: 09 января, 2014Неудача — это просто возможность начать снова, но уже более мудро.
© Генри Форд
Супер-предложение!
Купить виртуальный хостинг для сайта и домен с бесплатным тестовым периодов 1 месяц!
Подпишитесь на интересные обновления моего блога, чтобы быть в тренде последних тенденций разработки и продвижения сайтов:
Спасибо огромное за исходный php код!!!!!!!!!!!!!!!! Я давно пользуюсь cackle, но всегда беспокоило то, что комментарии не индексировались, а их уже порядка 500 за год скопилось, представляю насколько сейчас посещаемость подымется
А есть бесплатная система комментариев, чтобы она индексировалась, и чтобы цитирование было, ну и социальные сети в ней работали?
бесплатных систем много, например disqus. Однако везде по умолчанию работа основывается на внедрении на страницу javascript кода, который подгружает нужные комментарии, и которые не индексируются. Если для вас 450 руб. огромная сумма, да еще и с таким функционалом - можете самостоятельно поискать. Уточняйте есть ли у выбранного сервиса API и готовые php решения для внедрения на сайт для синхронизации. Я описал свой личный опыт и свое предпочтении в выборе именно данной системы.
А есть подобное решение для Отзывов?
Для "Отзывов" системы cackle данное решение не подходит. Попробую позже описать и его.
проба
Интересный код. Как он изменится в случае установки комментариев на wordpress? Вообще-то для wordpress есть плагин, который должен все синхронизировать, но он этого не делает, а в консоли chrome во время этой операции вылазит ошибка " 500 Internal server error"...
Актуальная версия для вордпреса находится тут https://wordpress.org/plugins/cackle/ Код, описанный выше, нельзя применять в голом виде в системах управления типо джумла, вордпрес, битрикс и т.п., Он скорее подойдет для самописных систем управления сайтом.
Спасибо! Обязательно попробую внедрить Ваш скрипт на свои сайты
Эта строка: $get_all_comments = $this->db_connect("select * from `comment` where `url` = $post_id and `status` = 1;" Выдает ошибку(
В базе все значения поля post_id равны NULL - если это из-за этого..
Если у меня сайт на голом хтмле и названия страниц я задаю вида stranica.html, то как post_id сможет стать как url? Ведь: `post_id` BIGINT(20) NULL DEFAULT NULL, `url` VARCHAR(2000) NULL DEFAULT NULL,
Хорошая статья
Тест