AJAX Click Counter Wordpress - wordpress

I need a simple click counter for links in my wordpress posts. I used google a lot but couldnt find a working one. I want to count clicks from a specific class and store it in post_meta or as a custom field to display the count later.
here is some code i found but i cant get it to work..nothting happens when i click the link.
js
jQuery(document).ready(function($) {
$("a[link-out]").click(function() {
var linkout = $(this).attr("link-out");
var data = {
action: 'my_action',
postid: linkout
};
$.post(MyAjax.ajaxurl, data);
});
});
php
wp_enqueue_script( 'my-ajax-request', plugin_dir_url( __FILE__ ) . 'js/countclicks.js', array( 'jquery' ) );
// declare the URL to the file that handles the AJAX request (wp-admin/admin-ajax.php)
wp_localize_script( 'my-ajax-request', 'MyAjax', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) );
add_action('wp_ajax_my_action', 'my_action_callback');
add_action('wp_ajax_nopriv_my_action', 'my_action_callback');
function my_action_callback() {
global $wpdb;
$post_id = $_POST['postid'];
$post_id = mysql_real_escape_string($post_id);
$wpdb->query("UPDATE wp_postmeta SET meta_value = meta_value+1 WHERE post_id = '$post_id' AND meta_key = 'clicks_out'");
}
here is another one i found here on stackoverflow, but also doenst work
coding ajax click counter on wordpress

Related

Woocommerce ajax call on single product page

I get all my products from an API and those who are variations to each other all share a custom meta key called "api_product_family". The products with the same api_product_family are variants to each other, so on the single page I have a hook where I display the other variants with image and anchor to it's variants.
My code:
function mv_variations() {
global $post;
global $wpdb;
$product_id = $post->ID;
$product_family = get_post_meta( $post->ID, 'api_product_family', true );
if(!empty($product_family)) {
$query = "
SELECT post_id
FROM " . $wpdb->prefix . "postmeta
WHERE meta_value = '" . $product_family . "'
";
$products = $wpdb->get_col($query);
if(count($products) > 0) {
for($i=0; $i<count($products); $i++) {
if($products[$i] == $product_id) {
unset($products[$i]);
}
}
if(count($products) > 0) {
print '<h3>Choose other variants: </h3>';
foreach($products as $product) {
$image = wp_get_attachment_image_src(get_post_thumbnail_id($product));
print '<img src="' . $image[0] . '" alt="img"/> ';
}
}
}
}
}
add_action( 'woocommerce_single_product_summary', 'mv_variations' );
The problem:
I have a LOT of posts, and a lot of post_meta's, so it's taking an eternity to load so I was thinking to move this whole function inside and AJAX call so it's doesn't slow down the initial load. The problem is that I have no idea how to do that with wordpress
Are you simply looking to run a WP function via AJAX?
1) Add ajax actions
This needs to run inside the main plugin file. If you run this only on the public code, it will not work. WP is a little weird and all ajax uses admin-ajax.php
if ( wp_doing_ajax() ){
add_action( 'wp_ajax_yourcustomfunction', array($this, 'yourcustomfunction') );
add_action( 'wp_ajax_nopriv_yourcustomfunction', array($this, 'yourcustomfunction') );
}
function yourcustomfunction(){
echo 'success';
exit();
}
2) In JavaScript
in the backend, you have the global: ajaxurl for the ajax url
BUT in the front end you need to pass this as a variable via wp_localize_script
$datatoBePassed = array(
'ajaxurl' => admin_url( 'admin-ajax.php' ),
);
wp_localize_script( 'your_javascript_script', 'plugin_display_settings', $datatoBePassed );
In JS:
var datavar = {
action: 'yourcustomfunction',
};
$.post(plugin_display_settings.ajaxurl, datavar, function(response){
//response received here. It will be 'success' which is echoed in PHP
});
3)
If you also want to run a security nonce check (to check the request truly originates from the WP website, prevents some attacks), it gets a little more complicated:
$datatoBePassed should also include 'security' => wp_create_nonce( 'yourplugin_security_nonce' ),
datavar in JS includes security: plugin_display_settings.security,
Finally, your PHP custom function begins with:
// Check security nonce.
if ( ! check_ajax_referer( 'yourplugin_security_nonce', 'security' ) ) {
wp_send_json_error( 'Invalid security token sent.' );
wp_die();
}
// If security check passed, run further
So I think you might get better performance using WP_Query. Below I converted what you have into a custom WP_Query. May need some slight adjustment but should be the right direction.
function mv_variations() {
global $post_id;
// get current post "product family"
$product_family = get_post_meta( $post_id, 'api_product_family', true );
// build related "product family" products query
$products_query_args = array(
'post_type' => 'product', // may need to update this for your case
'posts_per_page' => -1, // return all found
'post__not_in' => array($post_id), // exclude current post
'post_status' => 'publish',
// use a meta query to pull only posts with same "product family" as current post
'meta_query' => array(
array(
'key' => 'api_product_family',
'value' => $product_family,
'compare' => '='
)
)
);
$products_query = new WP_Query($products_query);
// use "the loop" to display your products
if ( $products_query->have_posts() ) :
print '<h3>Choose other variants: </h3>';
while ( $products_query->have_posts() ) : $products_query->the_post();
print ''. wp_get_attachment_image() .'';
endwhile;
// restore global post
wp_reset_postdata();
endif;
}
add_action( 'woocommerce_single_product_summary', 'mv_variations' );

How can I register a short code using form inputs from users?

I am trying to build a plugin where I need to take inputs from users from a form and create a shortcode with some of the user inputs. I have created a separate page for the adding form. there I am trying to process the input data and save on a custom table in WordPress DB. The problem I am facing is that, After saving the data in my custom table, I want to create a shortcode with some of the inputs but the add_shortcode method with its callback function is not working. I am new to Wordpress so I am not sure where I am going wrong.
I have tried a lot of ways but at the end was left with scratching my head. I have tried first saving everything. Then on the plugin main file. Tried to retrieve data from DB and create shortcode there. But no result
if (isset($_POST['sc_add_submit'])) {
$name = sanitize_text_field($_POST['sc_name']);
$shortcode = sanitize_text_field($_POST['shortcode']);
$content = sanitize_text_field($_POST['content']);
$short_desc = sanitize_text_field($_POST['short_desc']);
$errors = [];
$msgs = [];
global $wpdb;
$wpdb->insert('wp_sc_content', array(
'sc_name' => $name,
'shortcode' => 'sc_'.$shortcode,
'content' => $content,
'short_desc' => $short_desc,
));
$sc_lastInsert_id = $wpdb->insert_id;
if (!empty($sc_lastInsert_id)) {
$msgs[] = "Shortcode inserted succesfully";
function sc_register_shortcode()
{
return $content;
}
add_shortcode($shortcode, 'sc_register_shortcode');
} else {
$errors[] = "DB insert failed";
}
}
I just need to register the shortcode each time the form is submitted. So that the user paste the shortcode and it returns the content wherever he wants.
So, your shortcodes are "added" as soon as the form is submitted. When you navigate to other pages or reload the screen, the add_shortcode() is not triggering anymore!
What you need to do is to query your shortcodes from the database and hook it to something like init, so it's always loaded.
Let me write the code for you-
<?php
add_action( 'init', 'wpse_54302608_add_shortocodes' );
function wpse_54302608_add_shortocodes() {
global $wpdb;
$table = 'wp_sc_content'; // hopefully $wpdb->prefix . 'sc_content';
$query = "SELECT * FROM {$table}";
$results = $wpdb->get_results( $query );
foreach ( $results as $row ) {
$fn = function() use ( $row ) {
return $row->content;
};
add_shortcode( $row->shortcode, $fn );
}
}
Not tested. But should work.

Inserting checkbox values into WordPress database

I am trying to insert the values of all ticked checkboxes in a wordpress database, into a table which i created myself. Here's my jQuery code:
$(document).ready(function(){
$('#submit').click(function(){
var insert = [];
$('.get_value').each(function(){
if($(this).is(":checked") ){
insert.push($(this).val() );
}
});
insert = insert.toString();
$.ajax({
url:"insert.php",
method:"POST",
data:{insert:insert},
success:function(data){
$('.result').html(data);
}
});
});
});
and my insert code, (its in insert.php):
if ( isset($_POST["insert"]) ){
global $wpdb;
$table_name = $wpdb->prefix . "status";
$wpdb->insert($table_name, array(
'status' => 'approved'
);
}
its not showing any errors, but its not inserting either.I dont know if this information is useful, but the checkboxes are at the admin backend as part of a custom post type.
This isn't going to work, because you are calling insert.php in your ajax call. The url should point to ajaxurl that is localized with the script where your ajax is.
So if your script is located in file called custom.js and you have it enqueued it like:
wp_enqueue_script( 'my_custom_script', get_template_directory_uri() . '/js/custom.js', array( 'jquery' ),'', true );
Then you'll localize your ajax url like
wp_localize_script( 'my_custom_script', 'ajax_call', array(
'ajaxurl' => admin_url( 'admin-ajax.php' ),
) );
And use it in your script like
$(document).ready(function(){
$('#submit').click(function(){
var insert = [];
$('.get_value').each(function(){
if($(this).is(":checked") ){
insert.push($(this).val() );
}
});
insert = insert.toString();
$.ajax({
url: ajax_call.ajaxurl,
method:"POST",
data:{
'action': 'my_action_callback',
'insert': insert,
},
success:function(data){
$('.result').html(data);
}
});
});
});
Also your insert.php code should be inside a function hooked on wp_ajax hooks
add_action( 'wp_ajax_my_action_callback', 'my_action_callback' );
add_action( 'wp_ajax_nopriv_my_action_callback', 'my_action_callback' );
function my_action_callback(){
if ( isset($_POST["insert"]) ){
global $wpdb;
$table_name = $wpdb->prefix . "status";
$wpdb->insert($table_name, array(
'status' => 'approved'
);
}
}
https://codex.wordpress.org/AJAX_in_Plugins

How to populate wp-admin/post.php file during edit?

In post.php page of wp-admin I like to populate a post meta while the page is loading. For that I tried the following
add_action('load-post.php', 'show_buy_ticket_date');
function show_buy_ticket_date() {
$screen = get_current_screen();
if ($screen->post_type === 'ai1ec_event') {
$post_id = filter_input(INPUT_GET, 'post');
$buy_ticket_date_unix_timestamp = get_post_meta($post_id,
'buy_ticket_date', TRUE);
}
}
Here I fetched the post's meta value. But How can I populate it in one of the field in the form once edit page is loaded / before loading.
For e.g. the field looks like this
<input class="ai1ec-date-input ai1ec-form-control datepicker hasDatepicker" name="ai1ec_admin_buy_ticket-date-input" id="ai1ec_admin_buy_ticket-date-input" type="date">
You need to convert the timestamp to a date value suitable for input taking into account that, provided that the timestamp is in UTC time, you probably want to align it with your current timezone.
Finally, you pass the date value to input with the value attribute:
date_default_timezone_set( 'Europe/Helsinki' );
$buy_ticket_date = date( 'Y-n-j', intval( $buy_ticket_date_unix_timestamp ));
<input
class="ai1ec-date-input ai1ec-form-control datepicker hasDatepicker"
name="ai1ec_admin_buy_ticket-date-input"
id="ai1ec_admin_buy_ticket-date-input"
type="date" ,
value="<?php echo $buy_ticket_date; ?>
>
UPDATE:
Given the limitation that input is in some third-party code, I would update the field via JavaScript:
Pass $buy_ticket_date with localized JavaScript, PHP:
add_action( 'wp_enqueue_scripts', 'my_scripts' ) );
function my_scripts() {
// ... get $buy_ticket_date_unix_timestamp based on post ID
date_default_timezone_set( 'Europe/Helsinki' );
$buy_ticket_date = date( 'Y-n-j', intval( $buy_ticket_date_unix_timestamp ));
wp_register_script( 'my_script', MY_PLUGIN_URL . 'js/script.js', array( 'jquery' ) );
wp_localize_script( 'my_script', 'buy_ticket_date', $buy_ticket_date );
wp_enqueue_script( 'my_script' );
}
and JavaScript (script.js):
/*global document, jQuery */
(function ($) {
'use strict';
$(document).ready(function () {
$('#ai1ec_admin_buy_ticket-date-input').val(buy_ticket_date);
});
}(jQuery));

Removing Content with wp_delete_post in a Plugin with Custom Post Type

I set up a plugin that adds a custom post type and then brings in a bunch of dummy content with wp_insert_post on activation like so:
register_activation_hook( __FILE__, array( $this, 'activate' ) );
public function activate( $network_wide ) {
include 'dummycontent.php';
foreach ($add_posts_array as $post){
wp_insert_post( $post );
};
} // end activate
I would like to remove this content when the plugin is deactivated so I set up this function:
register_deactivation_hook( __FILE__, array( $this, 'deactivate' ) );
public function deactivate( $network_wide ) {
include 'dummycontent.php';
foreach($remove_posts_array as $array){
$page_name = $array["post_title"];
global $wpdb;
$page_name_id = $wpdb->get_results("SELECT ID FROM " . $wpdb->base_prefix . "posts WHERE post_title = '". $page_name ."'");
foreach($page_name_id as $page_name_id){
$page_name_id = $page_name_id->ID;
wp_delete_post( $page_name_id, true );
};
};
} // end deactivate
It works just fine. Except because the custom post type is created with the same plugin that these two functions are run through, the post type is removed before the posts themselves can be through wp_delete_post. When I test these functions out without the custom post type posts are added upon activation and removed upon deactivation. So I know the problem is with the post type. Does anyone know how to work around this?
Try something like this (YOUTPOSTTYPE is the name of your post type):
function deactivate () {
$args = array (
'post_type' => 'YOURPOSTTYPE',
'nopaging' => true
);
$query = new WP_Query ($args);
while ($query->have_posts ()) {
$query->the_post ();
$id = get_the_ID ();
wp_delete_post ($id, true);
}
wp_reset_postdata ();
}
It works in my plugin, it should works in your's. (This has been tested with WordPress 3.5.1).
wp_delete_post($ID, false) sends it to Trash. Only when you remove from Trash is a post really deleted. That's why it works with $force = true.
So it works as expected. First posts go to Trash, then they get actually deleted. Like Recycle Bin. Trace the post_status change to see when it hits the Trash if you want to do anything then. Otherwise wait for the delete.
Also delete content on uninstall and not on deactivate. Consider deactivating a plugin as pausing it and uninstalling it when you really want it gone.
Try this Function
function deactivate () {
$args = array(
'post_type' => 'POST_TYPE',
'posts_per_page' => - 1
);
if ( $posts = get_posts( $args ) ) {
foreach ( $posts as $post ) {
wp_delete_post( $post->ID, true );
}
}
}

Resources