load_textdomain(); /** Add plugin links. */ add_filter("plugin_action_links_" . plugin_basename(__FILE__), array($this, 'add_links')); /** Registers AdSimpleVote post type. */ add_action('init', array($this, 'register_adsimplevote_post_type')); /** Add REST API support to adsimplevote post type. */ add_action('init', array($this, 'adsimplevote_rest_support'), 25); /** * Since WP 4.7, filter has been removed from WP-API. I have no idea why. * Add the necessary filter to each post type. */ add_action('rest_api_init', array($this, 'rest_api_filter_add_filters')); /** Create editor button for shortcode. */ add_action('init', array($this, 'add_button')); /** Add ShorCode column to votes list. */ add_filter('manage_adsimplevote_posts_columns', array($this, 'add_head_shortcode_column'), 10); add_action('manage_adsimplevote_posts_custom_column', array($this, 'add_content_shortcode_column'), 10, 2); /** Add plugin setting page. */ add_action('admin_menu', array($this, 'add_admin_menu') ); add_action('admin_init', array($this, 'settings_init') ); /** Fire meta box setup on the post editor screen. */ add_action('load-post.php', array($this, 'meta_boxes_setup') ); add_action('load-post-new.php', array($this, 'meta_boxes_setup') ); /** Add admin css and js. */ add_action('admin_enqueue_scripts', array($this, 'admin_enqueue_scripts') ); // Add CSS /** Add plugin css and js if post has shortcode. */ add_action('the_posts', array($this, 'enqueue_styles')); /** Create [adsimplevote id="ID"] shorcode. */ add_shortcode('adsimplevote', array($this, 'adsimplevote_shortcode_func')); /** Remove unnecessary metaboxes. */ add_action('edit_form_after_title', array($this, 'remove_unnecessary_metaboxes'), 100); /** Creating adsimplevote table. */ add_action('init', array($this, 'register_adsimplevote_table'), 1); add_action('switch_blog', array($this, 'register_adsimplevote_table')); register_activation_hook(__FILE__, array($this, 'create_adsimplevote_table')); /** Add action to AJAX process vote. */ add_action('wp_ajax_process_vote', array($this, 'process_vote')); add_action('wp_ajax_nopriv_process_vote', array($this, 'process_vote')); /** Clear votes on remove vote post. */ add_action('before_delete_post', array($this, 'before_delete_vote_post')); /** Print Open Graph tags */ add_action('wp_head', array($this, 'open_graph_print')); /** Handle Open Graph canonical URL */ add_filter('get_canonical_url', array($this, 'open_graph_canonical_url'), 50, 1); } /** * Clear votes after remove vote post. * * @since 1.0.0 * @access public */ public function before_delete_vote_post($post_id){ global $wpdb; if( get_post_type($post_id) != ASV_POST_TYPE){ // Work only with adsimplevote post type return; } $res = $wpdb->delete( $wpdb->adsimplevote, array('vote_id' => $post_id) ); return $res; } /** * AJAX Add vote. * Users can vote 10 times from 1 IP in 24 hours. * * @since 1.0.0 * @access public */ public function process_vote() { $is_new_vote = boolval($_POST['new_vote']); $vote_id = intval( $_POST['vote_id'] ); $vote_val = intval( $_POST['vote_val'] ); $user_ip = sanitize_text_field(AdSimpleVoteHelper::getIP()); $guid = sanitize_text_field($_POST['guid']); $created = gmdate('Y-m-d H:i:s'); $modified = gmdate('Y-m-d H:i:s'); // TODO: Organize logic more gracefully. if ($is_new_vote) { // New Vote. // Check limits to vote from this IP if (AdSimpleVoteHelper::checkVotesLimits($vote_id, $user_ip)) { // Insert vote in table AdSimpleVoteHelper::insertVote($vote_id, $vote_val, $user_ip, $guid, $created, $modified); } else { // Exceeded the limit of votes from one IP echo json_encode(array( "status" => 0, "message" => __("Exceeded the limit of votes from one IP.", 'adsimple-vote') )); wp_die(); // Required to terminate immediately and return a proper response. } } else { // User alredy voted. // Check limits to vote from this IP if (AdSimpleVoteHelper::checkVotesLimits($vote_id, $user_ip)) { // Update previous vote AdSimpleVoteHelper::updateVote($vote_id, $vote_val, $user_ip, $guid, $modified); } else { // Exceeded the limit of votes from one IP echo json_encode(array( "status" => 0, "message" => __("Exceeded the limit of votes from one IP.", 'adsimple-vote') )); wp_die(); // Required to terminate immediately and return a proper response. } } // All OK echo json_encode(array('status' => 1, 'is_new_vote' => $is_new_vote)); wp_die(); // Required to terminate immediately and return a proper response. } /** * Creating a adsimplevote table. * id | vote_id (Post ID) | ip | value | created | modified * * @since 1.0.0 * @access public */ public function create_adsimplevote_table() { global $wpdb; global $charset_collate; require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); /** Call this manually as we may have missed the init hook. */ $this->register_adsimplevote_table(); $sql_create_table = "CREATE TABLE {$wpdb->adsimplevote} ( id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, vote_id BIGINT(20) UNSIGNED NOT NULL DEFAULT '0', value INT(3) UNSIGNED NOT NULL DEFAULT '0', ip varchar(64) CHARACTER SET utf8 NOT NULL DEFAULT '', guid varchar(64) CHARACTER SET utf8 NOT NULL DEFAULT '', created DATETIME DEFAULT NULL, modified DATETIME DEFAULT NULL, PRIMARY KEY (id) ) $charset_collate; "; dbDelta( $sql_create_table ); } /** * Store our table name in $wpdb with correct prefix. * * @since 1.0.0 * @access public */ public function register_adsimplevote_table(){ global $wpdb; $wpdb->adsimplevote = "{$wpdb->prefix}adsimplevote"; } /** * Remove all unnecessary meta boxes. * * @since 1.0.0 * @access public */ public function remove_unnecessary_metaboxes($post) { global $wp_meta_boxes; if( $post->post_type != ASV_POST_TYPE){ return; } // Only for Votes if( ! isset( $wp_meta_boxes[ASV_POST_TYPE] ) ) { return; } // Does the post have metaboxes? /** All metaboxes will be removed except this. */ $filter_metaboxes = array( 'submitdiv', 'postimagediv', 'postexcerpt', 'asv-values-meta-box', 'asv-chart-meta-box', 'asv-actions-meta-box' ); foreach( (array) $wp_meta_boxes['adsimplevote'] as $context_key => $context_item ) { foreach( $context_item as $priority_key => $priority_item ) { foreach ($priority_item as $metabox_key => $metabox_item) { if( ! in_array($metabox_key, $filter_metaboxes) ) { unset($wp_meta_boxes['adsimplevote'][$context_key][$priority_key][$metabox_key]); // Remove meta boxes. } } } } } /** * Add REST API support to adsimplevote post type. * * @since 1.0.0 * @access public */ public function adsimplevote_rest_support() { global $wp_post_types; $post_type_name = ASV_POST_TYPE; if( isset( $wp_post_types[ $post_type_name ] ) ) { $wp_post_types[$post_type_name]->show_in_rest = true; } } /** * Create editor button for shorcode. * * @since 1.0.0 * @access public */ public function add_button() { if (is_admin() && current_user_can('edit_posts') && current_user_can('edit_pages')) { add_filter('mce_external_plugins', array($this, 'add_TinyMCE_plugin') ); add_filter('mce_buttons', array($this, 'register_button') ); add_filter('mce_css', array($this, 'plugin_mce_css') ); $suffix = AdSimpleVoteHelper::getResourceSuffix(); wp_enqueue_script('asv-button-js', plugin_dir_url(__FILE__) . 'js/button' . $suffix . '.js', array('jquery'), self::VERSION, true); $adsimple_data = array( 'rest_url' => get_rest_url() ); wp_localize_script('asv-button-js', 'adsimple_data', $adsimple_data ); } } /** * Adds shortcode to the array of buttons. * * @since 1.0.0 * @access public */ public function register_button($buttons) { /** Register button with their id. */ array_push($buttons, "adsimplevote"); return $buttons; } /** * Register TinyMCE Plugin. * * @since 1.0.0 * @access public */ function add_TinyMCE_plugin($plugin_array) { $suffix = AdSimpleVoteHelper::getResourceSuffix(); $plugin_array['adsimplevote_plugin'] = plugin_dir_url(__FILE__) . 'js/adsimplevote' . $suffix . '.js'; return $plugin_array; } /** * Add stylesheet to the TinyMCE. * * @since 1.0.0 * @access public */ public function plugin_mce_css( $mce_css ) { $suffix = AdSimpleVoteHelper::getResourceSuffix(); wp_enqueue_style('adsimplevote-editor', plugin_dir_url(__FILE__) . 'css/editor' . $suffix . '.css'); return $mce_css; } /** * Core logic of [adsimplevote id="VOTE_ID"] shortcode * * @return string * @since 1.0.0 * @access public */ public function adsimplevote_shortcode_func($atts, $content = null, $tag) { global $post; $atts = shortcode_atts( array('id' => NULL), $atts); $vote = AdSimpleVoteHelper::getVote($atts['id']); if (!$vote) { return ''; } $left_value = get_post_meta($vote->ID, 'left_value', true); $right_value = get_post_meta($vote->ID, 'right_value', true); $votes_count = AdSimpleVoteHelper::countVotes($vote->ID); // Get plugin settings. $options = AdSimpleVoteHelper::getOptions(); $before_vote_msg_header = $options['before_vote_msg_header']; $before_vote_msg_description = $options['before_vote_msg_description']; $after_vote_msg_header = $options['after_vote_msg_header']; $after_vote_msg_description = $options['after_vote_msg_description']; $share_url = add_query_arg('adv', $vote->ID, get_permalink($post->ID)); ob_start(); ?>

post_title; ?>

post_excerpt)) > 0): ?>
post_excerpt; ?>
0
array($arr)); echo 'var adsimplevote_data_' . $vote_id . ' = ' . json_encode($result) . ';'; } /** * Add plugin css and js if post has shortcode * * @param array $posts * @return array * @since 1.0.0 * @access public */ public function enqueue_styles($posts) { if (empty($posts)) { return $posts; } /** False because we have to search through the posts first. */ $found = false; /** Search through each post. */ foreach ($posts as $post) { /** Check the post content for the short code. */ if (has_shortcode($post->post_content, 'adsimplevote')) { $found = true; // We have found a post with the short code. break; // Stop the search. } } // TODO: Move charts script to footer if ($found) { $this->enqueue_common(); $suffix = AdSimpleVoteHelper::getResourceSuffix(); // JS wp_enqueue_script('adsimplevote-script-js', plugin_dir_url(__FILE__) . 'js/script' . $suffix . '.js', array('adsimplevote-common-js'), '', true); // in JavaScript, object properties are accessed as ajax_object.ajax_url, ajax_object.we_value wp_localize_script('adsimplevote-script-js', 'adsimplevote_ajax', array('url' => admin_url('admin-ajax.php'))); $this->enqueue_chart(); } return $posts; } /** * Register JS & CSS for admin area. * * @since 1.0.0 * @access public */ public function admin_enqueue_scripts() { /* Add admin styles only on plugin pages */ $screen = get_current_screen(); if ($screen->post_type != ASV_POST_TYPE) { return; } add_thickbox(); $this->enqueue_common(); $suffix = AdSimpleVoteHelper::getResourceSuffix(); wp_enqueue_style('adsimplevote-admin', plugin_dir_url(__FILE__) . 'css/admin' . $suffix . '.css', array(), self::VERSION); wp_enqueue_script('adsimplevote-admin-js', plugin_dir_url(__FILE__) . 'js/admin' . $suffix . '.js', array('jquery'), self::VERSION); wp_localize_script('adsimplevote-admin-js', 'adsimplevote_dict', array( 'preview' => __('Preview', 'adsimple-vote') )); $this->enqueue_chart(); } protected function enqueue_common() { $suffix = AdSimpleVoteHelper::getResourceSuffix(); wp_enqueue_style('adsimplevote-common', plugin_dir_url(__FILE__) . 'css/common' . $suffix . '.css', array(), self::VERSION); wp_enqueue_script('adsimplevote-common-js', plugin_dir_url(__FILE__) . 'js/common' . $suffix . '.js', array('jquery'), self::VERSION); } protected function enqueue_chart() { $suffix = AdSimpleVoteHelper::getResourceSuffix(); wp_enqueue_style('adsimplevote-chartist', plugin_dir_url(__FILE__) . 'css/chartist' . $suffix . '.css'); /** Add inline CSS */ $options = AdSimpleVoteHelper::getOptions(); // Get plugin options $css = ".adsimplevote-box .asv-footer .asv-couter span {color:" . $options['key_color'] . ";}"; $css .= ".adsimplevote-chart .ct-series-a .ct-line {stroke:" . $options['key_color'] . ";}"; $css .= ".adsimplevote-chart .ct-series-a .ct-area {fill:" . $options['key_color'] . ";}"; $css .= ".adsimplevote-box .range::-webkit-slider-thumb:hover {background: " . $options['key_color'] . ";}"; $css .= ".adsimplevote-box .range:active::-webkit-slider-thumb {background: " . $options['key_color'] . ";}"; $css .= ".adsimplevote-box .range::-moz-range-thumb:hover {background: " . $options['key_color'] . ";}"; $css .= ".adsimplevote-box .range:active::-moz-range-thumb {background: " . $options['key_color'] . ";}"; wp_add_inline_style('adsimplevote-chartist', $css); // JS wp_enqueue_script('adsimplevote-chartist-js', plugin_dir_url(__FILE__) . 'js/chartist' . $suffix . '.js', array(), '', true); } /** * Add admin menu for plugin settings. * * @since 1.0.0 * @access public */ public function add_admin_menu() { add_submenu_page( 'edit.php?post_type=' . ASV_POST_TYPE, __('AdSimple-Vote — Let the users to vote with just one simple click.', 'adsimple-vote'), __('Settings', 'adsimple-vote'), 'manage_options', 'adsimplevote_settings', array($this, 'options_page') ); } /** * Generate Settings Page * * @since 1.0.0 * @access public */ public function settings_init() { register_setting('AdSimpleVoteOptionsGroup', 'adsimplevote_settings'); add_settings_section('adsimplevote_pluginPage_section', __('Plugin settings', 'adsimple-vote'), array($this, 'settings_section_callback'), 'AdSimpleVoteOptionsGroup'); /** KeyColor */ add_settings_field('key_color', __('Color', 'adsimple-vote'), array($this, 'key_color_render'), 'AdSimpleVoteOptionsGroup', 'adsimplevote_pluginPage_section'); /** Social Buttons */ add_settings_field('social_share_buttons', esc_html__('Social Share Buttons', 'adsimple-vote'), array($this, 'social_share_buttons_render'), 'AdSimpleVoteOptionsGroup', 'adsimplevote_pluginPage_section'); /** Before Vote Message */ add_settings_field('before_vote_msg', esc_html__('Before Vote Message', 'adsimple-vote'), array($this, 'before_vote_msg_render'), 'AdSimpleVoteOptionsGroup', 'adsimplevote_pluginPage_section'); /** After Vote Message */ add_settings_field('after_vote_msg', esc_html__('After Vote Message', 'adsimple-vote'), array($this, 'after_vote_msg_render'), 'AdSimpleVoteOptionsGroup', 'adsimplevote_pluginPage_section'); } /** * Render After Vote Message field. * * @since 1.0.0 * @access public */ public function after_vote_msg_render() { $options = AdSimpleVoteHelper::getOptions(); ?>



'>

true, 'labels' => array( 'name' => __('Votes', 'adsimple-vote'), 'singular_name' => __('Vote', 'adsimple-vote'), 'add_new' => __('Add New Vote', 'adsimple-vote'), 'add_new_item' => __('Add New Vote', 'adsimple-vote'), 'edit_item' => __('Edit Vote', 'adsimple-vote'), 'new_item' => __('New Vote', 'adsimple-vote'), 'view_item' => __('View Vote', 'adsimple-vote'), 'view_items' => __('View Votes', 'adsimple-vote'), 'search_items' => __('Search Votes', 'adsimple-vote'), 'not_found' => __('No votes found', 'adsimple-vote'), 'not_found_in_trash' => __('No posts found in Trash', 'adsimple-vote'), 'all_items' => __('All votes', 'adsimple-vote'), 'archives' => __('Vote Archives', 'adsimple-vote'), 'attributes' => __('Vote Attributes', 'adsimple-vote'), 'insert_into_item' => __('Insert into vote', 'adsimple-vote'), 'uploaded_to_this_item' => __('Uploaded to this vote', 'adsimple-vote'), 'featured_image' => __('Vote Image', 'adsimple-vote'), 'set_featured_image' => __('Set vote image', 'adsimple-vote'), 'remove_featured_image' => __('Remove vote image', 'adsimple-vote'), 'use_featured_image' => __('Use as vote image', 'adsimple-vote'), 'menu_name' => __('AdSimple Vote', 'adsimple-vote') ), 'menu_icon' => $this->get_svg_icon(), 'exclude_from_search' => TRUE, 'publicly_queryable' => FALSE, 'menu_position' => FALSE, 'show_in_rest' => TRUE, 'rest_base' => 'adsimplevote', 'supports' => array( 'title', 'excerpt', 'thumbnail' ) ) ); } /** * Meta box setup function. * * @since 1.0.0 * @access public */ public function meta_boxes_setup( ) { /** Add meta boxes on the 'add_meta_boxes' hook. */ add_action( 'add_meta_boxes', array($this, 'asv_add_meta_boxes') ); /** Save Left and Right values on the 'save_post' hook. */ add_action( 'save_post', array($this, 'save_vote_meta'), 1, 2 ); } /** * Create Left and Right values meta boxes to be displayed on vote editor screen. * * @since 1.0.0 * @access public */ public function asv_add_meta_boxes() { $screen = get_current_screen(); /** Left and Right values metabox */ add_meta_box( 'asv-values-meta-box', __('Values', 'adsimple-vote'), array($this, 'values_meta_box'), 'adsimplevote', 'normal', 'default' ); if ('add' != $screen->action) { add_meta_box( 'asv-chart-meta-box', __('Chart', 'adsimple-vote'), array($this, 'chart_meta_box'), 'adsimplevote', 'normal', 'default' ); } add_meta_box( 'asv-actions-meta-box', __('Actions', 'adsimple-vote'), array($this, 'actions_meta_box'), 'adsimplevote', 'side', 'default' ); } /** * Save Left and Right values. * * @since 1.0.0 * @access public */ public function save_vote_meta($post_id, $post) { /** Verify the nonce before proceeding. */ if ( ! isset($_POST['metabox_fields_nonce']) || ! wp_verify_nonce($_POST['metabox_fields_nonce'], basename(__FILE__))) { return $post_id; } /** Get the post type object. */ $post_type = get_post_type_object($post->post_type); /** Check if the current user has permission to edit the post. */ if (!current_user_can($post_type->cap->edit_post, $post_id)) { return $post_id; } /** Get Left value and sanitize it for use. */ $left_value = ( isset($_POST['left_value']) ? sanitize_text_field($_POST['left_value']) : '' ); /** Update meta value. */ $this->update_meta_val($left_value, 'left_value', $post_id); /** Get Right value and sanitize it for use. */ $right_value = ( isset($_POST['right_value']) ? sanitize_text_field($_POST['right_value']) : '' ); /** Update meta value. */ $this->update_meta_val($right_value, 'right_value', $post_id); } /** * Add, update or remove meta value. * * @since 1.0.0 * @access public */ public function update_meta_val($new_value, $meta_key, $post_id){ /** Get the meta value of the custom field key. */ $meta_value = get_post_meta($post_id, $meta_key, true); /* If a new meta value was added and there was no previous value, add it. */ if ($new_value && '' == $meta_value) { add_post_meta($post_id, $meta_key, $new_value, true); } /* If the new meta value does not match the old value, update it. */ elseif ($new_value && $new_value != $meta_value) { update_post_meta($post_id, $meta_key, $new_value); } /* If there is no new meta value but an old value exists, delete it. */ elseif ('' == $new_value && $meta_value) { delete_post_meta($post_id, $meta_key, $meta_value); } } /** * Display Left and Right values meta box. * * @since 1.0.0 * @access public * @param WP_Post $vote */ public function values_meta_box($vote) { /** Nonce field to validate form request came from current site. */ wp_nonce_field(basename(__FILE__), 'metabox_fields_nonce'); /** Get the left and right values if it's already been entered. */ $left_value = get_post_meta($vote->ID, 'left_value', true); $right_value = get_post_meta($vote->ID, 'right_value', true); ?>

adsimplevote_template(); ?> [adsimplevote id=\"{$post_ID}\"]"; } } /** * Return base64 encoded SVG icon. * * @since 1.0.0 * @access public */ public function get_svg_icon() { $svg = << CONTENT; return 'data:image/svg+xml;base64,' . base64_encode( $svg ); } /** * Loads the AdSimple-Vote translated strings. * * @since 1.0.0 * @access public */ public function load_textdomain() { load_plugin_textdomain('adsimple-vote', false, dirname(plugin_basename(__FILE__)) . '/languages'); } /** * Add "AdSimple" and "Settings" links to plugin page. * * @since 1.0.0 * @access public * * @param array $links Current links: Deactivate | Edit */ public function add_links($links) { array_unshift($links, 'Settings'); array_unshift($links, ' www.adsimple.at'); return $links; } /** * Since WP 4.7, filter has been removed from WP-API. I have no idea why. * Add the necessary filter to each post type. * * @see https://github.com/WP-API/rest-filter * @since 1.0.0 * @access public */ public function rest_api_filter_add_filters() { foreach (get_post_types(array('show_in_rest' => true), 'objects') as $post_type) { add_filter('rest_' . $post_type->name . '_query', array($this, 'rest_api_filter_add_filter_param'), 10, 2); } } /** * Add the filter parameter * * @param array $args The query arguments. * @param WP_REST_Request $request Full details about the request. * @return array $args. * * @since 1.0.0 * @access public * */ public function rest_api_filter_add_filter_param($args, $request) { // Bail out if no filter parameter is set. if (empty($request['filter']) || !is_array($request['filter'])) { return $args; } $filter = $request['filter']; if (isset($filter['posts_per_page']) && ( (int) $filter['posts_per_page'] >= 1 && (int) $filter['posts_per_page'] <= 100 )) { $args['posts_per_page'] = $filter['posts_per_page']; } global $wp; $vars = apply_filters('query_vars', $wp->public_query_vars); foreach ($vars as $var) { if (isset($filter[$var])) { $args[$var] = $filter[$var]; } } return $args; } public function open_graph_print() { $vote = AdSimpleVoteHelper::getVote(isset($_GET['adv']) ? (int)$_GET['adv'] : 0); if (!$vote) { return; } $thumbnail_url = get_the_post_thumbnail_url($vote); $title = trim($vote->post_title); $description = trim($vote->post_excerpt); ?> ID, $canonical_url); } } // End of class AdSimple-Vote. } /** Execution of the plugin. */ new AdSimpleVote();