Replace links on post save/update in Wordpress - wordpress

I would like use short urls in wordpress post content (not the post permalink). So when I setup a new link in my post content, I would like if this url will be shortened with a service. I have an url shorten tool with yourls api, it works fine. My problem is, I unable change all long url in post to the new shortened url.
My function looks like this:
add_action( 'save_post', 'save_book_meta', 10, 3 );
function save_book_meta( $post_id, $post, $update ) {
global $wpdb;
preg_match_all('|<a.*(?=href=\"([^\"]*)\")[^>]*>([^<]*)</a>|i', $post->post_content, $match);
$new_content = $post->post_content;
foreach($match[1] as $link){
$yapikey = '********';
$api_url = 'https://yourdomain.com/yourls-api.php';
$longUrl = $link;
// Init the CURL session
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $api_url);
curl_setopt($ch, CURLOPT_HEADER, 0); // No header in the result
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // Return, do not echo result
curl_setopt($ch, CURLOPT_POST, 1); // This is a POST request
curl_setopt($ch, CURLOPT_POSTFIELDS, array( // Data to POST
'url' => $longUrl,
'format' => 'json',
'action' => 'shorturl',
'signature' => $yapikey
));
// Fetch and return content
$data = curl_exec($ch);
curl_close($ch);
// Do something with the result. Here, we echo the long URL
$data = json_decode( $data );
if($data->shorturl) {
str_replace($link, $data->shorturl, $new_content);
}
}
// unhook this function so it doesn't loop infinitely
remove_action('save_post', 'save_book_meta' );
$post_new = array(
'ID' => $post_id,
'post_content' => $new_content
);
$post_id = wp_update_post( $post_new, true );
add_action( 'save_post', 'save_book_meta' );
}
How can I replace all long url with the new shortened urls and save the updated content?

I think it would be easiest to use the filter
add_filter( 'wp_insert_post_data' , 'save_book_meta' , '99', 2 );
function save_book_meta( $data , $postarr ) {
// find your urls and do the replacements on $data['post_content'] here
return $data;
}
EDIT: It looks like another viable filter option to use is https://codex.wordpress.org/Plugin_API/Filter_Reference/content_save_pre which may work even better as there has been no sanitation performed on the content yet.

Related

Sending Order Details From WooCommerce To External System Over API

I am trying to send woocommerce order to netsuite via an external api I have written. I am nw to woocommerce and do not fully get how to add this functionality.
I have added the following code to the functions.php file in public_html/wp-content/themes/reverie-master/
add_action( 'woocommerce_payment_complete'', 'wdm_send_order_to_ext');
function wdm_send_order_to_ext( $order_id ){
// get order object and order details
$order = new WC_Order( $order_id );
$email = $order->billing_email;
$phone = $order->billing_phone;
//Create the data object
$orderData = array(
'customer_email' => $email,
'customer_phone' => $phone
);
$apiData = array(
'caller' => 'woocommerce',
'json' => $orderData,
'key' => 'MY_SECRET_KEY'
);
$jsonData =json_encode($orderData);
$url = "";
$api_mode = 'sandbox';
if($api_mode == 'sandbox'){
// sandbox URL example
$url = "https://forms.netsuite.com/app/site/hosting/scriptlet.nl?script=XXX&deploy=X&compid=XXXXXXX_SB1&h=XXXXXXXXXXXXXXXX";
}
else{
// production URL example
$url = "";
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($jsonData));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec ($ch);
curl_close ($ch);
// the handle response
if (strpos($response,'ERROR') !== false) {
print_r($response);
} else {
// success
}
}
I have tested the brunt of this code, just the parts that do not concern woocommerce in a different site and I can see the data showing up in NetSuite. However, when I go through my store and place an order, and take payment, I do not see the data come into NetSuite. Do I have this code in the right location? Is there something I am missing?
Update
I installed the plugin Code Snippets and added the code there instead. Set it to Run snippet everywhere. Still no luck.
Looks like you have a double quote on the first link
change
add_action( 'woocommerce_payment_complete'', 'wdm_send_order_to_ext');
to
add_action( 'woocommerce_payment_complete', 'wdm_send_order_to_ext');
Rather than use curl - you can always use the build in WordPress wp_remote_post() function
Also make sure you have WP_DEBUG set to true in wp-config.php while testing.

Need a custom function to be accessible throughout WordPress

I have this notification function and need to call it in different places of the code. I need to put it some where which be accessed by any files inside my child theme as well as in the plugins directory.
function send_notification($tokens, $message)
{
$url = 'https://fcm.googleapis.com/fcm/send';
$fields = array(
'registration_ids' => $tokens,
'data' => $message
);
$headers = array(
'Authorization:key = My_Token',
'Content-Type: application/json'
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
$result = curl_exec($ch);
if ($result === FALSE) {
die('Curl failed: ' . curl_error($ch));
}
curl_close($ch);
return $result;
}
First question, Where to put it, currently it is in functions.php?
Second question, how to call it in different places?
Any solution and reference would be appreciated. Thank you.
Since you've got a function with a broad scope, consider giving it a more unique name to prevent naming conflicts, such as naser_send_notitification() instead of just send_notification, or if you can - consider using a namespace or class.
Now to answer your question, functions.php is actually usually a safe bet for "broad scope" functions that need to be accessible just about anywhere. If you look at the Action Reference you'll see that after_setup_theme is fired relatively early-on, allowing your function to be accessible from that hook or later - since it will be available during this moment. However, it does come after plugins_loaded, so if you need it before then, you'll need to turn it into a plugin with a File Header or an "MU Plugin".
If you need it be accessible at effectively the earliest momement, consider putting it in a file in /wp-content/mu-plugins/ and give it a name, even something like custom-functions.php. These files are called Must-Use Plugins. Files in this directory are always loaded, and always run before anything else, so functions declared in them are accessible incredibly early. This is typically where I put code I need to make sure is theme independent, is always on and can't be deactivated.
So effectively:
1) Rename your function to something a bit more unique, like naser_send_notitification()
2) Put this code in /wp-content/mu-plugins/custom-funtions.php
3) Now you should be able to call naser_send_notification( $tokens, $message ) in any function or hook that comes after the muplugins_loaded hook (which is just about anywhere)
Here is the Solution:
every thing is commented on each line
function do_something( $a = "", $b = "" ) { // create your function
echo '<code>';
print_r( $a ); // `print_r` the array data inside the 1st argument
echo '</code>';
echo '<br />'.$b; // echo linebreak and value of 2nd argument
}
add_action( 'danish', 'do_something', 10, 2 );
// create your own action with params('action name', 'callback funtion', priority, num_of params)
then Hook everywhere you need
$a = array(
'eye patch' => 'yes',
'parrot' => true,
'wooden leg' => 1
);
$b = __( 'And Hook said: "I ate ice cream with Peter Pan."', 'textdomain' );
// Executes the action hook named 'danish'
do_action('danish', $a, $b);
that's it.
I believe wordpress shortcodes would be the best approach to handle this. Because messing with wordpress core files is not good practice and leads to several issues like code removal on upgrade etc.
There are several benefits of shortcodes and for your specific problem it would be beneficial because:
can be placed in parent/child themes functions.php
can be accessible in php code files and in dashboard editor as well
Complete Code: (just place inside functions.php)
function send_notification( $atts )
{
extract(shortcode_atts(array(
"tokens" => '',
"message" => ''
), $atts));
$url = 'https://fcm.googleapis.com/fcm/send';
$fields = array(
'registration_ids' => $tokens,
'data' => $message
);
$headers = array(
'Authorization:key = My_Token',
'Content-Type: application/json'
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
$result = curl_exec($ch);
if ($result === FALSE) {
die('Curl failed: ' . curl_error($ch));
}
curl_close($ch);
return $result;
}
add_shortcode('send-notification', 'send_notification');
Call it anywhere in theme or plugin: (like this)
wordpress editor:
[send-notification token=XXXX message="hello"]
theme/plugin files:
<?php echo do_shortcode('[send-notification token=XXXX message="hello"]'); ?>
Useful Resources:
WordPress Shortcode with Parameters
A tutorial on Wordpress Shortcodes
Creating Shortcode with different type of parameters
According to this question :
step 1: write your function into a class inside your plugin
step 2: create an object of that class into your theme
step 3: access your function by that object.
// inside your plugin
class foo {
public function send_notification() {
return "whatever you want";
}
}
// inside your themes functions.php
$foo_object = new foo();
// use the object to access your function:
$foo_object->send_notification();

Integrating SMS api with woocommerce , Not sending messages

I'm integrating SMS API with WooCommerce to send automatic order updates to customers mobiles whenever the make any purchase on site.
below is my code for the same
add_action('woocommerce_payment_complete', 'custom_process_order', 10, 1);
function custom_process_order($billing_phone)
{
$username = "my username";
$hash = "d761fbd7bd31c5eeec2a5b2556d6b9d3b1a1ae51";
//Multiple mobiles numbers separated by comma
$mobileNumber = "$billing_phone";
$senderId = "ORNGMT";
$message = urlencode("Dear Customer");
$postData = array(
'hash' => $hash,
'mobiles' => $$billing_phone,
'message' => $message,
'sender' => $senderId,
);
$url='http://api.textlocal.in/send/?';
$ch = curl_init();
curl_setopt_array($ch, array(
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $postData
//,CURLOPT_FOLLOWLOCATION => true
));
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
$output = curl_exec($ch);
if(curl_errno($ch))
{
echo 'error:' . curl_error($ch);
}
curl_close($ch);
echo $output;
}
is it correct ?
I've added this code to functions.php page
my sms gateway provider has sent me below example code to send sms with PHP
<?php
// Authorisation details.
$username = "your login id";
$hash = "your hash key";
// Configuration variables. Consult http://api.textlocal.in/docs for more info.
$test = "0";
// Data for text message. This is the text message data.
$sender = "API Test"; // This is who the message appears to be from.
$numbers = "44777000000"; // A single number or a comma-seperated list of numbers
$message = "This is a test message from the PHP API script.";
// 612 chars or less
// A single number or a comma-seperated list of numbers
$message = urlencode($message);
$data = "username=".$username."&hash=".$hash."&message=".$message."&sender=".$sender."&numbers=".$numbers."&test=".$test;
$ch = curl_init('http://api.textlocal.in/send/?');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch); // This is the result from the API
curl_close($ch);
?>
Integrating message API for each event will be difficult and you need to customize the at the code level.
You can use a popular SMSplugin for wordpress woocommerce
https://wordpress.org/plugins/woocommerce-apg-sms-notifications/
Just you need to configure this plugin from woocommerce Admin login and it will send sms notifications automatically. We are using it with Spring Edge sms gateway.. Working Good.
Tested and working
Custom api Integration with Woocommerce wordpress
Ufone pakistan sms integration with woocommerce wordpress
if you are looking for integration with ufone pakistan sms api bsms ufone pakistan service provider with woocommerce wordpress then use the following code in your functions file
sms api integration ufone bsms with wordpress woocommerce thanks to the author on this page Integrating custom SMS API with woocommerce
//add this line for calling your function on creation of order in woocommerce
add_action('woocommerce_order_status_processing', 'custom_func', 10, 3);
function custom_func ($order_id) {
$order_details = new WC_Order($order_id);
//fetch all required fields
$billing_phone = $order_details->get_billing_phone();
$billing_name = $order_details->get_billing_first_name();
$billing_last_name = $order_details->get_billing_last_name();
$total_bill = $order_details->get_total();
$textmessage = rawurlencode("Dear $billing_name, Thank you for your order. Your order #$order_id is being processed. Please wait for confirmation call Total Bill = $total_bill");
// Now put HTTP ufone BSMS API URL
$url = "https://bsms.ufone.com/bsms_v8_api/sendapi-0.3.jsp?id=msisdn&message=$textmessage&shortcode=SHORTCODE&lang=English&mobilenum=$billing_phone&password=password&messagetype=Nontransactional";
// NOW WILL CALL FUNCTION CURL
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_URL, $url);
$data = curl_exec($ch);
$err = curl_error($ch);
curl_close($ch);
return $order_id;
}
$billingphone in your function is ID. Try this below code. It works
add_action('woocommerce_payment_complete', 'custom_process_order', 10, 1);
function custom_process_order($order_id) {
//Lets get data about the order made
$order = new WC_Order( $order_id );
//Now will fetch customer/buyer id here
$customer_id = $order->user_id;
//now finally we fetch phone number
$billing_phone = get_user_meta( $customer_id, 'billing_phone', true );
// Now put your HTTP SMS API URL . I PUT WHICH WE ARE USING
$jsonurl = "http://tsms.thirdeyegoa.com/api/sendmsg.php?user=USERNAME&pass=PASSWORD&sender=MYSENDERID&phone=".$billing_phone."&priority=ndnd&stype=normal&text=MY MESSAGE TO CUSTOMER.";
// NOW WILL CALL FUNCTION CURL
$json = curl($jsonurl);
return $order_id;
}
Same you can do for Order Completed too with respective hook.
i write this piece of code and it is working.
add_action('woocommerce_order_status_completed','payment_complete');
function payment_complete($order_id)
{
$order=new Wc_order($order_id);
$order_meta = get_post_meta($order_id);
$shipping_first_name = $order_meta['_shipping_first_name'][0];
$phone=$order_meta['_billing_phone'][0];
$first_name=$order->billing_first_name;
$last_name=$order->billing_last_name;
$name=$first_name."".$last_name;
$mobile=$order->billing_mobile;
$items = $order->get_items();
foreach ( $items as $item ) {
$product_name = $item['name'];
$product_id = $item['product_id'];
$product_variation_id = $item['variation_id'];
$time=$item['timings'];
$slot=$item['time_slot'];
$qty= $item['qty'];
$date=$item['tour_date'];
}
$text="your message here";
$data="user=username&pass=password&sender=sendername&phone=".$phone."&priority=ndnd&stype=normal&text=".$text;
$ch = curl_init('http://bhashsms.com/api/sendmsg.php?');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
echo $result;
curl_close($ch);
}
I am from Textlocal. Let me help you out with the code.
Firstly the error that you are getting - 'Unexpected Token' is generally due to an invalid JSON response. If you are unaware of the source of the issue, I would suggest you to look in the Javascript console in the Dev section (triggering the error). For reference, you can check Mike's blog out here.
In the code you have shared, Textlocal API is not receiving the parameters that are mandatory for a successful POST call. You can rephrase your function like this:
add_action('woocommerce_payment_complete', 'custom_process_order', 10, 1);
function custom_process_order($order_id) {
$order = new WC_Order( $order_id );
$customer_id = $order->user_id;
$billing_phone = get_user_meta( $customer_id, 'billing_phone', true );
$data="username=USERNAME&hash=hash&sender=ORNGMT&numbers=".$billing_phone."&message=MY MESSAGE TO CUSTOMER.";
$jsonurl = curl_init('https://api.textlocal.in/send?');
$json = curl($jsonurl);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($json);
echo $result;
curl_close($json);
return $order_id;
}
If you need any further assistance, please reach out to our support team (support#textlocal.in)

How to add posts in Wordpress without admin login using xml-rpc and curl

I wants to add posts in Wordpress site using xml-rpc and curl OR any alternate method without logging in WP admin. Is this possible?
I got the answer and Following code is working for me.
function wpPostXMLRPC ($title,$body,$rpcurl,$username,$password,$category='Uncategorized',$keywords='',$encoding='UTF-8') {
$title = htmlentities($title,ENT_NOQUOTES,$encoding);
$keywords = htmlentities($keywords,ENT_NOQUOTES,$encoding);
$content = array (
'title'=>$title,
'description'=>$body,
'mt_allow_comments'=>0,
'mt_allow_pings'=>0,
'post_type'=>'post',
'mt_keywords'=>$keywords,
'categories'=>array(
$category
)
);
$params = array(
0,
$username,
$password,
$content,
true
);
$request = xmlrpc_encode_request('metaWeblog.newPost', $params);
$ch = curl_init();
curl_setopt($ch, CURLOPT_POSTFIELDS, $request);
curl_setopt($ch, CURLOPT_URL, $rpcurl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 1);
$results = curl_exec($ch);
curl_close($ch);
return $results;
}
$title = 'post-title';
$body = 'POST BODY WILL GOES HERE';
$rpcurl = 'http://example.com/xmlrpc.php';
$username = 'xxx';
$password = 'xxx';
$category = 'test';
$chk = wpPostXMLRPC($title,$body,$rpcurl,$username,$password,$category,$keywords='',$encoding='UTF-8');
if($chk) {
echo $chk;
} else {
echo 'failed';
}
There is a built-in feature in Wordpress that allow you to publish an article via e-mail. Never tested it though, but it may suit your needs.
You can configure it in your site's admin, under settings > writing (URL is like http://yourwordpresssite.com/wp-admin/options-writing.php).
However, if you need an API, you'll find useful things in Wordpress Codex pages related to XML-RPC support and wp.newPost.
For a code sample, you can have a look at this snippet, which seems a good basis to me.

Encoding issues when posting custom fields via wordpress xmlrpc api

I've a problem with wordpress xml-rpc api. My code gets some data from an xml and posts to a blog. Page title posted well, there is no problem on blog but custom fields are broken.
Code file, xml, blog settings and database tables they are all utf-8 encoded.
function wpPostXMLRPC($title,$body,$rpcurl,$username,$password,$thumbnail,$cfields,$category,$keywords='',$encoding='UTF-8') {
$title = html_entity_decode(htmlentities($title,ENT_NOQUOTES,$encoding));
$body = html_entity_decode(htmlentities($body,ENT_NOQUOTES,$encoding));
$keywords = html_entity_decode(htmlentities($keywords,ENT_NOQUOTES,$encoding));
array_walk($cfields,arr_encoding); // this function does the same thing with above
$content = array(
'title'=>$title,
'description'=>$body,
'mt_allow_comments'=>0, // 1 to allow comments
'mt_allow_pings'=>0, // 1 to allow trackbacks
'post_type'=>'post',
'mt_keywords'=>$keywords,
'categories'=>array($category),
'custom_fields' => $cfields
);
$params = array(0,$username,$password,$content,true);
$request = xmlrpc_encode_request('metaWeblog.newPost',$params);
$ch = curl_init();
curl_setopt($ch, CURLOPT_POSTFIELDS, $request);
curl_setopt($ch, CURLOPT_URL, $rpcurl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 100);
curl_setopt($ch, CURLOPT_ENCODING, "UTF-8" );
$results = curl_exec($ch);
if(curl_errno($ch))
echo '<hr>curl error:'.curl_error($ch)."<hr>";
curl_close($ch);
return $results;}
and this is arr encoding function:
function arr_encoding($cfields){
if(is_array($cfields))
array_walk($cfields, 'arr_encoding');
else if(is_string($cfields))
$cfields = html_entity_decode(htmlentities($cfields,ENT_NOQUOTES,"UTF-8"));}
Do you have any idea?
OK, here it is:
Don't use
xmlrpc_encode_request('blogger.newPost',$params);
and use:
xmlrpc_encode_request('blogger.newPost',$params,
array('encoding'=>'UTF-8','escaping'=>'markup'));

Resources