Интегрируем веб-компонент wc-likes в wordpress
В этой статье мы рассмотрим вариант интеграции веб-компонента wc-likes с CMS системой wordpress на примере сайта webislife.ru
В этой статье я не буду рассматривать вариант установки, компонент настолько маленький, что его можно скопировать прост в проект ну или поддерживать последнюю актуальную версию wc-likes из npm. У нас он просто уже есть и нам нужно его интегрировать в wordpress и обойтись без новых зависимостей в фреймворках и плагинах. Конечно же вы можете скачать и просто установить плагин для wordpress, может даже я сделаю когда-нибудь его отдельно, но сегодня речь пойдет о интеграции технологии через код и поддержку самой темой webislife для wp c лайками
Добавляем лайки в wordpress
Изначально wordpress не поддерживает понятие и модель лайков, их можно добавить через post meta fields
, но мы пойдем еще более нативным путем, создаем таблицу в бд wordpress отдельно для хранения лайков, использование своей таблицы даст нам преимущества в скорости работы сайта и независимости от механик wordpress, код который создаст таблицу для лайков постов может выглядеть вот так
$table_name = $wpdb->prefix . "wp_post_likes"; $charset_collate = $wpdb->get_charset_collate(); $sql = "CREATE TABLE $table_name ( id mediumint(9) NOT NULL AUTO_INCREMENT, ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, post_id mediumint(9) NOT NULL, user_id mediumint(9) NOT NULL, PRIMARY KEY (id) ) $charset_collate;"; require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); dbDelta( $sql );
Отлично, осталось добавить еще пару php функций в наш function.php
для реализации API методов добавления и получения лайков
Получаем лайки из бд
//Получаем лайки из бд function WC_LIKES_GET_BYPOST($req) { $response_data = array( 'success' => true, 'count' => 0, 'code' => 200, ); $reqjson = json_decode($req->get_body(), true); $post_id = intval($reqjson['post_id']); //required post id if(is_int($post_id) === false) { $response_data['error'] = 'post_id:number required'; $response = new WP_REST_Response( $response_data ); $response->set_status( 200 ); return $response; } global $wpdb; $sql = $wpdb->get_row("SELECT COUNT(id) as count FROM `wp_post_likes` WHERE post_id=".$post_id); $response_data['count'] = $sql->count; $response = new WP_REST_Response( $response_data ); $response->set_status( 200 ); return $response; }
/** * Отправка лайка с сайта * API POST /wp-json/wlapi/v1/post */ function WC_LIKES_POST($request) { $response_data = array( 'success' => true, 'error' => '', 'code' => 200, ); $reqjson = json_decode($request->get_body(), true); $post_id = intval($reqjson['post_id']); $user_id = get_current_user_id($token); $response_data['post_id'] = $post_id; $headers = $request->get_headers(); //required post id if(is_int($post_id) === false) { $response_data['error'] = 'post_id:number required'; $response = new WP_REST_Response( $response_data ); $response->set_status( 200 ); return $response; } //post need exist $like_post = get_post($post_id); if(is_null($like_post)) { $response_data['error'] = "post id:".$reqjson['post_id'].' - not found'; $response = new WP_REST_Response( $response_data ); $response->set_status( 200 ); return $response; } //auth user if($user_id === 0) { $response_data['error'] = "auth require"; $response_data['code'] = 401; $response = new WP_REST_Response( $response_data ); $response->set_status( 200 ); return $response; } global $wpdb; $user_count = $wpdb->get_row("SELECT COUNT(id) as count FROM `wp_post_likes` WHERE user_id=".$user_id." AND post_id=".$post_id)->count; if($user_count > 0) { $response_data['error'] = "alreadyVoted"; $response_data['success'] = false; $response_data['code'] = 200; $response = new WP_REST_Response( $response_data ); $response->set_status( 200 ); return $response; } //insert like // $sql = $wpdb->query( "INSERT INTO `wp_post_likes` (`post_id`, `user_id`) VALUES (".$post_id.", ".$user_id.")" ); $sql = $wpdb->insert( "wp_post_likes", [ 'post_id' => $post_id, 'user_id' => $user_id ] ); $response_data['user_id'] = $user_id; // $response_data['result'] = "INSERT INTO `wp_post_likes` (`post_id`, `user_id`) VALUES (".$post_id.", ".$user_id.")"; $response_data['sql'] = $sql; $response_data['success'] = true; $response = new WP_REST_Response( $response_data ); $response->set_status( 200 ); return $response; }
Осталось добавить поддержку REST API через следующим образом
add_action( 'rest_api_init', function () { register_rest_route( 'wlapi', '/OG/', array( 'methods' => 'GET', 'callback' => 'API_OG', ) ); // API WC-likes section register_rest_route( 'wlapi', '/wc-likes/post', array( 'methods' => 'POST', 'callback' => 'WC_LIKES_POST', ) ); register_rest_route( 'wlapi', '/wc-likes/get-by-post', array( 'methods' => 'POST', 'callback' => 'WC_LIKES_GET_BYPOST', ) ); } );
С бекенд частью закончили, просто не так ли? Этим и подкупает разработка на wordpress)
Переиспользуем веб-компонент wc-likes
Основная реализация и стили лайков уже заложены в компоненте wc-likes
, осталось лишь добавить поддержку наших созданных апишек на фронте, давайте расширим wc-likes
import WCLikes from './web/wc-like.js'; import WPA from './../app.js'; class WCLikesPost extends WCLikes { initialState:WPA["State"] constructor() { super(); } connectedCallback(): void { this.fetchAsyncLikes(); const initialState:WPA["State"] = window.__WPA.State; if(initialState.userLogged === false) { this.classList.add('-auth'); this.setAttribute('data-hint', 'Для лайков необходимо авторизоваться'); this.LikesIcon.onpointerup = null; } } /** * Submit post like */ async fetchSubmitLikes():Promise { const post_id = +this.getAttribute('data-post-id'); const likesCountResponseJson = await window._WPA.API('/wp-json/wlapi/wc-likes/post', { method: 'POST', body: JSON.stringify({post_id}) }, true, true); if(likesCountResponseJson.error === 'alreadyVoted' && likesCountResponseJson.success == false) { this.Liked = true; this.setAttribute('data-hint', 'Вы уже лайкали этот пост'); } return likesCountResponseJson.success === true ? 200 : likesCountResponseJson.code; } /** * Fetch likes count */ async fetchAsyncLikes(params?:any):Promise { this.setAttribute('fetch', '1'); const post_id = +this.getAttribute('data-post-id') const likesCountResponseJson = await window._WPA.API('/wp-json/wlapi/wc-likes/get-by-post', { method: 'POST', body: JSON.stringify({post_id}) }, true); this.removeAttribute('fetch'); this.setAttribute('value', likesCountResponseJson.count); return likesCountResponseJson.count; } } window.customElements.define('wc-likes-post', WCLikesPost); export default WCLikesPost;
Все очень просто, мы расширили класс компонента wc-likes
и реализовали в нем 2 метода отправки и получения лайков
fetchSubmitLikes
и fetchAsyncLikes
в итоге нам не пришолсь писать ни капли boilerplate кода. Осталось вывести в шаблоне сайта наши лайки например в single-post.php
шаблоне
<wc-likes-post class="-fetch" data-post-id="<?=$post_id;?>" data-logged="<?=$isLoggedIn;?>"></wc-likes-post>
Зарегистрируйтесь, чтобы проверить работу лайка прямо под этим постом)
Последняя редакция 8 февраля, 2023 в 12:02