All posts by Manish

Woocommerce Change “Read More” Button

This code is useful for removing the “Read More” button (in woocommerce) for items that are out of stock.

/*
 * replace read more buttons for out of stock items
 **/
 if (!function_exists('woocommerce_template_loop_add_to_cart'))
 {
    function woocommerce_template_loop_add_to_cart()
    {
      global $product;
      if (!$product->is_in_stock()) 
      {
         echo '<a href="'.get_permalink().'" rel="nofollow" class="outstock_button">Sold Out</a>';
      }
      else
      {
         woocommerce_get_template('loop/add-to-cart.php');
      }
   }
 }

HC-05 Bluetooth Module for Arduino

The HC-05 Bluetooth module is a Plug-n-play one. Just connect it to the board and it will start working (no need to connect and disconnect pins/ports as suggested by some).

  • The default PIN of a HC-05 Module is 1234
  • The fast blinking LED indicates that it ready to connect
  • Slow blinking LED indicates it is connected to another Bluetoooth device
  • The tiny switch is for resetting/unpairing the module.

Connect it like connecting any other bluetooth device — find it from the phone, select the name (default HC-05), select pair, type in the PIN. That’s it.

Notes:

If the bluetooth module is connected to the Arduino board through RX and TX ports then the Arduino Board cannot be programmed using the USB, it will give error.
To program the Arduino while the Bluetooth is connected —  disconnect the RX and TX of the bluetooth module, load the program/code to the Arduino, connect the RX and TX of the bluetooth module

After resetting the bluetooth module or powering it off and then on — the phone will still show that the module is paired, so need to unpair first and then pair again.

 

Cannot Delete Files / Folders In Linux

A folder/file is not getting deleted? Have changed the permission and ownership but still cannot delete?

This can be due to the immutable flag set.
(Specially In ISPConfig when a folder is created for a site or when folder is mapped to a FTP User, ISPConfig itself sets the immutable flag)

To delete a folder or file which has the immutable flag set, try the following

chattr -i filename/foldername
rm -f filename / rm -f -r foldername

A folder still is not getting deleted? Try

cd foldername
chattr -i .
chattr -i ..
cd ..
rm -f -r foldername

 

 

Prestahop Installation error 500

Problem:
Trying to install a new prestashop but getting error 500, the installation doesn’t even start

Solution:
Check file and folder permissions. Folder permission should be 755 and file should be 644.

 

Commands for changing file / folder permissions in linux through (ssh) console:

This is for changing folder permissions

find /public_html/prestashop -type d -exec chmod 755 {} \; 

This is for changing file permissions

find /public_html/prestashop -type f -exec chmod 644 {} \

Upload Files through AJAX (using Jquery and PHP)

This post demonstrates how to upload files to the server through AJAX. For the javascript  part JQuery has been used.

Besides the file upload thing there are few other useful codes here:

  • A generalised mail function. The function is capable of sending mails with attachments also.
  • Ajax call using JQuery.
  • Some server side validation codes.

Things might look a little jumbled up here, suggested to copy and paste the code to some IDE or editor first.

Form HTML
<span id="statusMessage"></span>

<form action="" method="post" name="" id="form1" enctype="multipart/form-data" onsubmit="return sendCareerData()">
    <input type="text" id="formName" name="formName" placeholder="Name" />
    <input type="text" id="formEmail" name="formEmail" placeholder="Email" />
    <input type="text" id="formPhone" name="formPhone" placeholder="Phone No." />
    <input type="file" id="formFile" name="formFile" placeholder="Upload File" />
    <input type="submit" id="button4" name="formSubmit" value="Submit" />
</form>
The Javascript part
<script type="text/javascript">
function sendCareerData()
{
    var data = new FormData(document.getElementById("form1"));
   
    // make the AJAX request
    jQuery.ajax({
        type: "POST",
        url: 'form-backend.php',
        data: data,
        mimeType:"multipart/form-data",
        contentType: false,
        cache: false,
        processData:false,
        dataType: 'json',
        success: function (data) {
            if (data.success == 0) //error on server side
            {
              /* error messages from server side validation */  
                var errors = '<ul>';
                if (data.name_msg != '')
                    errors += '<li>' + data.name_msg + '</li>';
                if (data.email_msg != '')
                    errors += '<li>' + data.email_msg + '</li>';
                if (data.phone_msg != '')
                    errors += '<li>' + data.phone_msg + '</li>';

                jQuery("#statusMessage").html(errors);
                jQuery("#statusMessage").css("display","block");
            }
            else if (data.success == 1) 
            {
                jQuery("#statusMessage").html("Thank you! We will get in touch.");
                jQuery("#statusMessage").css("display","block");
            }

        },
        error: function (error) 
        {
            jQuery("#statusMessage").html(error);
            jQuery("#statusMessage").css("display","block");
        }
    });
    
    return false;
}
</script>
The backend part using PHP
/******* form-backend.php *********/
<?php
ob_start(); //to suppress any newlines being sent before the header call

/********* a general mail sending function with or without attachment ***********/
function _mail($to, $from='', $subject = " ", $body = " ", $attachment = "" , $fileatt_type = "", $fileatt_name = "")
{
    $headers = "MIME-Version: 1.0" . "\r\n";
    if(strlen($from))
        $headers .= 'From: ' . $from . "\r\n";
    $headers .= 'Bcc: [email protected]' . "\r\n";
    
    if(strlen($attachment)) //if attachment is there
    {
        $fp = fopen($attachment, "rb");
        if(! $fp)
        {
            echo "Cannot attach file";
            return false;
        }
        $buffer = fread($fp, filesize($attachment));
        $attach_this=chunk_split(base64_encode($buffer));
        fclose($fp);
        $semi_rand = md5(time());
         $mime_boundary = "==Multipart_Boundary_x{$semi_rand}x"; 
            /*'From: ' . $from . "\r\n" .
            'Reply-To: ' . $from . "\r\n" .*/
        $headers .= 'Content-Type: multipart/mixed; ' . " boundary="PHP-mixed-{$mime_boundary}"". "\r\n" . /* THIS BOUNDARY LINE AFTER CONTENT TYPE IS IMPORTANT */
        //$headers .= 'X-Mailer: PHP/' . phpversion() ; -- causing problems        
        $msg =     "--PHP-mixed-{$mime_boundary}\r\n" .
                "Content-Type: text/html; charset="iso-8859-1"\r\n" .
                "Content-Transfer-Encoding: 7bit\r\n\r\n". $body . "\r\n";
        $msg =     "--PHP-mixed-{$mime_boundary}\r\n";
        $msg .=  "--PHP-mixed-{$mime_boundary}\r\n" .
                "Content-Type: {$fileatt_type}; " . " name="{$fileatt_name}"\r\n" .
                "Content-Disposition: attachment; " . " filename="{$fileatt_name}"\r\n" .
                "Content-Transfer-Encoding: base64\r\n\r\n" .
                $attach_this . "\r\n" . /* DON'T PUT TWO NEWLINES AFTER THE ATTACHMENT */
                "--PHP-mixed-{$mime_boundary}--\r\n"; 
        $body = $msg;
    }
    else //no attachment - send simple html mail
    {
        $headers .= "Content-type:text/html;charset=iso-8859-1" . "\r\n";
        $headers .= 'X-Mailer: PHP/' . phpversion();
    }
    $mail_sent = mail($to, $subject, $body, $headers);
    $status = $mail_sent ? "1" : "0"; //1 - no error / success . 0 - error / failed
    return $status;
}

/**** a function for validating the user inputs **********/
function validate($name,$email,$phone)
{
  $return_array = array();
  $return_array['success'] = '1';
  $return_array['name_msg'] = '';
  $return_array['email_msg'] = '';
  $return_array['phone_msg'] = '';

  if($email == '')
  {
    $return_array['success'] = '0';
    $return_array['email_msg'] = 'email is required';
  }
  else
  {
    $email_exp = '/^[A-Za-z0-9._%-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$/';
    if(!preg_match($email_exp,$email)) 
    {
      $return_array['success'] = '0';
      $return_array['email_msg'] = 'enter valid email.';  
    }
  }

  if($name == '')
  {
    $return_array['success'] = '0';
    $return_array['name_msg'] = 'Name is required';
  }
  else
  {
    $string_exp = "/^[A-Za-z .'-]+$/";
    if (!preg_match($string_exp, $name)) 
    {
      $return_array['success'] = '0';
      $return_array['name_msg'] = 'enter valid Name.';
    }
  }
  
  if($phone == '')
  {
    $return_array['success'] = '0';
    $return_array['phone_msg'] = 'Phone is required';
  }
  else
  {
     $string_exp = "/^[0-9 -]+$/";
     if (!preg_match($string_exp, $phone)) 
     {
        $return_array['success'] = '0';
        $return_array['name_msg'] = 'enter valid Phone.';
     }
  }

  return $return_array;
}

/****** assigning the values to some variables for easy handling ********/
$name = $_POST['formName'];
$email = $_POST['formEmail'];
$phone = $_POST['formPhone'];
$subject = $_POST['formSubject'];
$file = $_FILES['formFile']['tmp_name'];

$type = $_FILES['formFile']['type'];

$return_array = validate($name,$email,$phone); // validate the user input and get the result in $return_array

if($return_array['success'] == '1') //if input is okay then send the mail (with attachment)
{
  $body = "<strong>Email = </strong>".$email."<br>";
  $body .= "<strong>Name = </strong>".$name."<br>";
  $body .= "<strong>Phone = </strong>".$phone."<br>";
  
    
   if(strlen($_FILES['formFile']['tmp_name'])) //if attachment is there
   {
        _mail("[email protected]",$email,$subject,$body,$file,$type,$_FILES['formFile']['name']);
   }
   else
   {
        _mail("[email protected]",$email,$subject,$body);
   } 
  
}

ob_end_clean();//discard any output thrown above
header('Content-type: text/json');
echo json_encode($return_array);
die();
?>

 

Twitter Feeds widget

//USAGE - set the keys and token here and then just include this file into your code. Change the <li> to whatever needed. 

if(!isset($tweetAuthen) && $tweetAuthen != "awre4rwrwfe") //random string to prevent this file being run directly
{
    echo "<li>Unauthorized use of widget</li>!";
}
else
{
        //Files needed for the Twitter authentification
    //Check if TwitterOAuth doesn't already existe
    if( ! class_exists( 'TwitterOAuth' )){
    
        require_once 'twitteroauth/twitteroauth.php';
    
    }
    
    
    
   function twitter_feeds(){

    $return_value = false;
    
    $twitter_oauth_var = array('consumer_key'=>"YOUR CONSUMER KEY", 'consumer_secret'=>"YOUR CONSUMER SECRET", "token_key"=>"YOUR TOKEN KEY", 'token_secret'=>"YOUR TOKEN SECRET");
    //Check if wee use the authentification methode. We need to have all the key and secret.
    if( is_array( $twitter_oauth_var ) && count($twitter_oauth_var) == 4 ){
       
        $connection = new TwitterOAuth($twitter_oauth_var['consumer_key'], $twitter_oauth_var['consumer_secret'], $twitter_oauth_var['token_key'],$twitter_oauth_var['token_secret']);
        $last_tweet = $connection->get('https://api.twitter.com/1.1/statuses/user_timeline.json', array("count"=>"5") );  // change 5 to the number of tweets to retrieve
                
        $return_value = $last_tweet;
        
        foreach ($last_tweet as $tweet) 
        {

            $id = $tweet->id_str;

            //$options['id'] = $id;
            //$last_tweet_html = $connection->get('https://api.twitter.com/1.1/statuses/oembed.json', $options);
            
            //$tweet_id = $id;
            //$tweet_html .= $last_tweet_html->html;
            
            $temp =  $tweet->text;
            if(strlen($tweet->entities->urls[0]->url))
            {
                $temp = str_ireplace($tweet->entities->urls[0]->url,"<a href='".$tweet->entities->urls[0]->url."' target='_blank'>".$tweet->entities->urls[0]->url."</a>",$temp);
                $tweet_html .= "<li>".$temp."</li>";
            }
            else
                $tweet_html .= "<li>".$temp."</li>";
        }

    }
        return $tweet_html;
    }
    
    echo twitter_feeds();
}

Need to include twitteroauth library. Can be downloaded from here https://github.com/abraham/twitteroauth

The whole code including the twitteroauth library can be downloaded from here.

PHP include Remote File

In some case it might be needed to include or run a remote file and display the output on the current site. For this to work the below settings needs to be enabled.

    allow_url_fopen = On
    allow_url_include = On

But in case those two settings cannot be changed or even after changing it doesn’t work (which happened for me) there is another way. See the main part.

    var yname =  document.getElementById("yname").value;
    var email = document.getElementById("email").value;
    var subject = document.getElementById("subject").value;
    var mesg = document.getElementById("mesg").value;
    
    
/******************  MAIN PART *******************/
    var url = "http://www.remote-server.com/mails.php?yname=" + yname + "&email=" + email + "&subject=" + subject + "&mesg=" + mesg;
   
    mailer = document.createElement("script");
    mailer.setAttribute('type', 'text/javascript');
    mailer.setAttribute('src', url);
    mailer.setAttribute('id', 'script_id');   
    document.getElementById("mailer_holder").appendChild(mailer); 
/****************** End of MAIN PART *******************/
    
    alert("Mail Sent Successfully");
    document.getElementById("yname").value = "";
    document.getElementById("email").value = "";
    document.getElementById("subject").value = "";
    document.getElementById("mesg").value = ""; 

Prevent CRON from overlapping

To solve situations where CRON starts another copy before the current one finishes.

At the top of the CRON job use:

//check if already running
$buff = file_get_contents("cron_stat.txt");
if($buff == 1)
{
    die();
}
//set a running flag;
file_put_contents("cron_stat.txt","1");
......
......
......

When the CRON will run for the first time “cron_stat.txt” will be blank so a 1 will be written in “cron_stat.txt” indicating that the CRON is running and the script will proceed with its work.
When the CRON will start again (second time onwards) it will check “cron_stat.txt” and if it finds there is a 1 in it the script it will exit. And if it finds a 0 then it will proceed.

At the end of the file use:

file_put_contents("cron_stat.txt","0");

This will write a 0 in the “cron_stat.txt” file indicating the CRON is not running.

So in short at the start of the script set 1 in a flag indicating the CRON is running and at the end of the script set the flag to 0 indicating CRON has finished.

There are ways to implement this through Linux commands, but didn’t work for me.